aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2019-08-19 20:49:42 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-08-19 20:49:42 +0000
commitb74c00bd10bc789bc2fc4d56b02e25bb431611f2 (patch)
tree1945ba0d73dd9ecc9361beaaa2fa056653e3bce8
parent7731e84e7ec203bea2bf07a273354b78ff853ba0 (diff)
parent4f6bdb08bab64b973e465fb45deb751561e3b969 (diff)
downloadgcc-b74c00bd10bc789bc2fc4d56b02e25bb431611f2.zip
gcc-b74c00bd10bc789bc2fc4d56b02e25bb431611f2.tar.gz
gcc-b74c00bd10bc789bc2fc4d56b02e25bb431611f2.tar.bz2
Merge from trunk revision 274678.
From-SVN: r274681
-rw-r--r--ChangeLog13
-rw-r--r--MAINTAINERS9
-rwxr-xr-xconfigure24
-rw-r--r--configure.ac16
-rw-r--r--contrib/ChangeLog4
-rwxr-xr-xcontrib/test_summary2
-rw-r--r--fixincludes/ChangeLog9
-rw-r--r--fixincludes/fixincl.x66
-rw-r--r--fixincludes/inclhack.def27
-rw-r--r--fixincludes/tests/base/os/availability.h18
-rw-r--r--gcc/ChangeLog3107
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog1030
-rw-r--r--gcc/ada/Makefile.rtl13
-rw-r--r--gcc/ada/ali.adb3
-rw-r--r--gcc/ada/ali.ads14
-rw-r--r--gcc/ada/aspects.adb2
-rw-r--r--gcc/ada/aspects.ads11
-rw-r--r--gcc/ada/checks.adb68
-rw-r--r--gcc/ada/contracts.adb11
-rw-r--r--gcc/ada/contracts.ads1
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_advice.rst28
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_aspects.rst6
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst15
-rw-r--r--gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst42
-rw-r--r--gcc/ada/doc/gnat_ugn/building_executable_programs_with_gnat.rst36
-rw-r--r--gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst269
-rw-r--r--gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst152
-rw-r--r--gcc/ada/einfo.adb7
-rw-r--r--gcc/ada/einfo.ads18
-rw-r--r--gcc/ada/errout.adb2
-rw-r--r--gcc/ada/errout.ads6
-rw-r--r--gcc/ada/exp_aggr.adb68
-rw-r--r--gcc/ada/exp_atag.adb11
-rw-r--r--gcc/ada/exp_atag.ads7
-rw-r--r--gcc/ada/exp_attr.adb317
-rw-r--r--gcc/ada/exp_attr.ads5
-rw-r--r--gcc/ada/exp_ch3.adb18
-rw-r--r--gcc/ada/exp_ch4.adb145
-rw-r--r--gcc/ada/exp_ch6.adb198
-rw-r--r--gcc/ada/exp_dbug.adb1
-rw-r--r--gcc/ada/exp_disp.adb308
-rw-r--r--gcc/ada/exp_dist.adb52
-rw-r--r--gcc/ada/exp_spark.adb37
-rw-r--r--gcc/ada/exp_util.adb42
-rw-r--r--gcc/ada/exp_util.ads54
-rw-r--r--gcc/ada/freeze.adb14
-rw-r--r--gcc/ada/gcc-interface/Make-lang.in3
-rw-r--r--gcc/ada/gcc-interface/Makefile.in27
-rw-r--r--gcc/ada/gcc-interface/lang.opt4
-rw-r--r--gcc/ada/gcc-interface/misc.c1
-rw-r--r--gcc/ada/gcc-interface/trans.c176
-rw-r--r--gcc/ada/gnat1drv.adb6
-rw-r--r--gcc/ada/gnat_rm.texi1479
-rw-r--r--gcc/ada/gnat_ugn.texi77
-rw-r--r--gcc/ada/gnatcmd.adb36
-rw-r--r--gcc/ada/impunit.adb1
-rw-r--r--gcc/ada/inline.adb463
-rw-r--r--gcc/ada/inline.ads27
-rw-r--r--gcc/ada/libgnarl/s-taprop__vxworks.adb7
-rw-r--r--gcc/ada/libgnat/a-cbmutr.adb4
-rw-r--r--gcc/ada/libgnat/a-cfdlli.ads1
-rw-r--r--gcc/ada/libgnat/a-cfhama.ads1
-rw-r--r--gcc/ada/libgnat/a-cfinve.adb4
-rw-r--r--gcc/ada/libgnat/a-cfinve.ads1
-rw-r--r--gcc/ada/libgnat/a-cforma.ads1
-rw-r--r--gcc/ada/libgnat/a-cgaaso.ads13
-rw-r--r--gcc/ada/libgnat/a-cgarso.ads16
-rw-r--r--gcc/ada/libgnat/a-cofove.adb4
-rw-r--r--gcc/ada/libgnat/a-cofove.ads2
-rw-r--r--gcc/ada/libgnat/a-cofuba.adb179
-rw-r--r--gcc/ada/libgnat/a-cofuba.ads17
-rw-r--r--gcc/ada/libgnat/a-cofuma.ads1
-rw-r--r--gcc/ada/libgnat/a-cofuve.ads1
-rw-r--r--gcc/ada/libgnat/a-cogeso.ads16
-rw-r--r--gcc/ada/libgnat/a-contai.ads4
-rw-r--r--gcc/ada/libgnat/a-dhfina.adb332
-rw-r--r--gcc/ada/libgnat/a-dhfina.ads70
-rw-r--r--gcc/ada/libgnat/a-direct.adb94
-rw-r--r--gcc/ada/libgnat/a-einuoc.adb6
-rw-r--r--gcc/ada/libgnat/a-except.adb1
-rw-r--r--gcc/ada/libgnat/a-except.ads22
-rw-r--r--gcc/ada/libgnat/a-exexpr.adb188
-rw-r--r--gcc/ada/libgnat/a-locale.ads16
-rw-r--r--gcc/ada/libgnat/a-tifiio.adb2
-rw-r--r--gcc/ada/libgnat/g-comlin.adb23
-rw-r--r--gcc/ada/libgnat/g-comlin.ads4
-rw-r--r--gcc/ada/libgnat/g-sercom__mingw.adb2
-rw-r--r--gcc/ada/libgnat/g-socket.adb2
-rw-r--r--gcc/ada/libgnat/s-os_lib.adb18
-rw-r--r--gcc/ada/libgnat/s-os_lib.ads11
-rw-r--r--gcc/ada/libgnat/s-win32.ads3
-rw-r--r--gcc/ada/opt.ads6
-rw-r--r--gcc/ada/par-prag.adb2
-rw-r--r--gcc/ada/repinfo.adb12
-rw-r--r--gcc/ada/sem.adb9
-rw-r--r--gcc/ada/sem.ads1
-rw-r--r--gcc/ada/sem_aux.adb6
-rw-r--r--gcc/ada/sem_ch12.adb223
-rw-r--r--gcc/ada/sem_ch12.ads4
-rw-r--r--gcc/ada/sem_ch13.adb466
-rw-r--r--gcc/ada/sem_ch3.adb406
-rw-r--r--gcc/ada/sem_ch4.adb75
-rw-r--r--gcc/ada/sem_ch5.adb7
-rw-r--r--gcc/ada/sem_ch6.adb40
-rw-r--r--gcc/ada/sem_ch7.adb106
-rw-r--r--gcc/ada/sem_ch8.adb153
-rw-r--r--gcc/ada/sem_dim.adb20
-rw-r--r--gcc/ada/sem_disp.adb8
-rw-r--r--gcc/ada/sem_disp.ads3
-rw-r--r--gcc/ada/sem_elab.adb8
-rw-r--r--gcc/ada/sem_eval.adb44
-rw-r--r--gcc/ada/sem_prag.adb201
-rw-r--r--gcc/ada/sem_prag.ads14
-rw-r--r--gcc/ada/sem_res.adb88
-rw-r--r--gcc/ada/sem_spark.adb382
-rw-r--r--gcc/ada/sem_spark.ads9
-rw-r--r--gcc/ada/sem_util.adb301
-rw-r--r--gcc/ada/sem_util.ads41
-rw-r--r--gcc/ada/sem_warn.adb77
-rw-r--r--gcc/ada/sinfo.ads2
-rw-r--r--gcc/ada/snames.ads-tmpl7
-rw-r--r--gcc/ada/socket.c6
-rw-r--r--gcc/ada/sprint.ads2
-rw-r--r--gcc/ada/table.adb4
-rw-r--r--gcc/ada/table.ads17
-rw-r--r--gcc/ada/warnsw.adb301
-rw-r--r--gcc/ada/warnsw.ads105
-rw-r--r--gcc/alias.c12
-rw-r--r--gcc/attribs.c1
-rw-r--r--gcc/bitmap.c139
-rw-r--r--gcc/bitmap.h1
-rw-r--r--gcc/brig/ChangeLog75
-rw-r--r--gcc/builtins.c104
-rw-r--r--gcc/builtins.h1
-rw-r--r--gcc/c-family/ChangeLog187
-rw-r--r--gcc/c-family/c-attribs.c60
-rw-r--r--gcc/c-family/c-common.c7
-rw-r--r--gcc/c-family/c-format.c4
-rw-r--r--gcc/c-family/c-format.h1
-rw-r--r--gcc/c-family/c-opts.c4
-rw-r--r--gcc/c-family/c-pragma.h6
-rw-r--r--gcc/c-family/c-warn.c10
-rw-r--r--gcc/c-family/c.opt4
-rw-r--r--gcc/c/ChangeLog144
-rw-r--r--gcc/c/c-decl.c33
-rw-r--r--gcc/c/c-parser.c144
-rw-r--r--gcc/c/c-typeck.c44
-rw-r--r--gcc/calls.c12
-rw-r--r--gcc/cfgrtl.c11
-rw-r--r--gcc/cgraph.c73
-rw-r--r--gcc/cgraph.h60
-rw-r--r--gcc/cgraphclones.c9
-rw-r--r--gcc/cgraphunit.c9
-rw-r--r--gcc/cif-code.def4
-rw-r--r--gcc/common.opt6
-rw-r--r--gcc/common/config/riscv/riscv-common.c7
-rw-r--r--gcc/config.gcc101
-rw-r--r--gcc/config/aarch64/aarch64-builtins.c90
-rw-r--r--gcc/config/aarch64/aarch64-c.c2
-rw-r--r--gcc/config/aarch64/aarch64-cores.def2
-rw-r--r--gcc/config/aarch64/aarch64-option-extensions.def92
-rw-r--r--gcc/config/aarch64/aarch64-protos.h51
-rw-r--r--gcc/config/aarch64/aarch64-simd-builtins.def2
-rw-r--r--gcc/config/aarch64/aarch64-simd.md4
-rw-r--r--gcc/config/aarch64/aarch64-sve.md5935
-rw-r--r--gcc/config/aarch64/aarch64-sve2.md8
-rw-r--r--gcc/config/aarch64/aarch64.c1894
-rw-r--r--gcc/config/aarch64/aarch64.h13
-rw-r--r--gcc/config/aarch64/aarch64.md145
-rw-r--r--gcc/config/aarch64/arm_acle.h55
-rw-r--r--gcc/config/aarch64/check-sve-md.awk66
-rw-r--r--gcc/config/aarch64/constraints.md59
-rw-r--r--gcc/config/aarch64/iterators.md405
-rw-r--r--gcc/config/aarch64/predicates.md125
-rw-r--r--gcc/config/aarch64/t-aarch647
-rw-r--r--gcc/config/alpha/alpha.c8
-rw-r--r--gcc/config/arc/arc-protos.h7
-rw-r--r--gcc/config/arc/arc.c743
-rw-r--r--gcc/config/arc/arc.md139
-rw-r--r--gcc/config/arc/builtins.def2
-rw-r--r--gcc/config/arc/predicates.md2
-rw-r--r--gcc/config/arm/arm-builtins.c4
-rw-r--r--gcc/config/arm/arm.md56
-rw-r--r--gcc/config/arm/arm_cmse.h2
-rw-r--r--gcc/config/arm/thumb2.md18
-rw-r--r--gcc/config/arm/types.md7
-rw-r--r--gcc/config/arm/vfp.md26
-rw-r--r--gcc/config/avr/avr-c.c2
-rw-r--r--gcc/config/avr/avr.c4
-rw-r--r--gcc/config/bfin/bfin.c2
-rw-r--r--gcc/config/c6x/c6x.c2
-rw-r--r--gcc/config/darwin.c17
-rw-r--r--gcc/config/darwin.h5
-rw-r--r--gcc/config/darwin.opt6
-rw-r--r--gcc/config/frv/frv.c2
-rw-r--r--gcc/config/gcn/gcn-valu.md15
-rw-r--r--gcc/config/gcn/gcn.c17
-rw-r--r--gcc/config/gcn/gcn.md62
-rw-r--r--gcc/config/gnu-user.h4
-rw-r--r--gcc/config/i386/avx512fintrin.h42
-rw-r--r--gcc/config/i386/avxintrin.h62
-rw-r--r--gcc/config/i386/darwin.h23
-rw-r--r--gcc/config/i386/darwin32-biarch.h58
-rw-r--r--gcc/config/i386/darwin64-biarch.h (renamed from gcc/config/i386/darwin64.h)3
-rw-r--r--gcc/config/i386/i386-builtins.c6
-rw-r--r--gcc/config/i386/i386-expand.c47
-rw-r--r--gcc/config/i386/i386-features.c471
-rw-r--r--gcc/config/i386/i386-features.h13
-rw-r--r--gcc/config/i386/i386.c99
-rw-r--r--gcc/config/i386/i386.h67
-rw-r--r--gcc/config/i386/i386.md162
-rw-r--r--gcc/config/i386/mmx.md310
-rw-r--r--gcc/config/i386/sse.md52
-rw-r--r--gcc/config/i386/t-darwin32-biarch (renamed from gcc/config/i386/t-darwin)0
-rw-r--r--gcc/config/i386/t-darwin64-biarch (renamed from gcc/config/i386/t-darwin64)0
-rw-r--r--gcc/config/i386/x86-tune-costs.h1238
-rw-r--r--gcc/config/ia64/ia64.c6
-rw-r--r--gcc/config/iq2000/iq2000.c2
-rw-r--r--gcc/config/mips/mips.c2
-rw-r--r--gcc/config/msp430/driver-msp430.c751
-rw-r--r--gcc/config/msp430/msp430-devices.c970
-rw-r--r--gcc/config/msp430/msp430-devices.h31
-rw-r--r--gcc/config/msp430/msp430-protos.h3
-rw-r--r--gcc/config/msp430/msp430.c1278
-rw-r--r--gcc/config/msp430/msp430.h97
-rw-r--r--gcc/config/msp430/msp430.opt9
-rw-r--r--gcc/config/msp430/t-msp430236
-rw-r--r--gcc/config/nds32/nds32-intrinsic.c2
-rw-r--r--gcc/config/nios2/nios2.c2
-rw-r--r--gcc/config/nvptx/nvptx.c2
-rw-r--r--gcc/config/pa/pa-netbsd.h137
-rw-r--r--gcc/config/pa/pa.c2
-rw-r--r--gcc/config/pa/pa32-netbsd.h37
-rw-r--r--gcc/config/pru/pru.c2
-rwxr-xr-xgcc/config/riscv/multilib-generator37
-rw-r--r--gcc/config/riscv/riscv-builtins.c2
-rw-r--r--gcc/config/riscv/riscv.c120
-rw-r--r--gcc/config/rs6000/darwin.h30
-rw-r--r--gcc/config/rs6000/darwin32-biarch.h49
-rw-r--r--gcc/config/rs6000/darwin64-biarch.h (renamed from gcc/config/rs6000/darwin64.h)12
-rw-r--r--gcc/config/rs6000/default64.h4
-rw-r--r--gcc/config/rs6000/dfp.md214
-rw-r--r--gcc/config/rs6000/eabialtivec.h3
-rw-r--r--gcc/config/rs6000/freebsd64.h6
-rw-r--r--gcc/config/rs6000/future.md521
-rw-r--r--gcc/config/rs6000/linux.h13
-rw-r--r--gcc/config/rs6000/linux64.h20
-rw-r--r--gcc/config/rs6000/linuxaltivec.h3
-rw-r--r--gcc/config/rs6000/predicates.md2
-rw-r--r--gcc/config/rs6000/rs6000-c.c2
-rw-r--r--gcc/config/rs6000/rs6000-call.c27
-rw-r--r--gcc/config/rs6000/rs6000.c16
-rw-r--r--gcc/config/rs6000/rs6000.h17
-rw-r--r--gcc/config/rs6000/rs6000.md1
-rw-r--r--gcc/config/rs6000/rs6000.opt7
-rw-r--r--gcc/config/rs6000/rtems.h3
-rw-r--r--gcc/config/rs6000/sysv4.h2
-rw-r--r--gcc/config/rs6000/t-darwin32-biarch (renamed from gcc/config/rs6000/t-darwin8)0
-rw-r--r--gcc/config/rs6000/t-darwin64-biarch (renamed from gcc/config/rs6000/t-darwin64)0
-rw-r--r--gcc/config/rs6000/t-rs60001
-rw-r--r--gcc/config/rs6000/vector.md13
-rw-r--r--gcc/config/rx/rx.c2
-rw-r--r--gcc/config/s390/predicates.md6
-rw-r--r--gcc/config/s390/s390-c.c2
-rw-r--r--gcc/config/s390/s390-modes.def14
-rw-r--r--gcc/config/s390/s390.c12
-rw-r--r--gcc/config/s390/s390.md144
-rw-r--r--gcc/config/sh/sh.c2
-rw-r--r--gcc/config/sparc/sparc.c6
-rw-r--r--gcc/config/spu/spu-c.c2
-rw-r--r--gcc/config/spu/spu.c2
-rw-r--r--gcc/config/stormy16/stormy16.c2
-rw-r--r--gcc/config/tilegx/tilegx.c2
-rw-r--r--gcc/config/tilepro/tilepro.c2
-rw-r--r--gcc/config/xtensa/xtensa.c4
-rw-r--r--gcc/convert.c86
-rw-r--r--gcc/coverage.c2
-rw-r--r--gcc/cp/ChangeLog547
-rw-r--r--gcc/cp/call.c21
-rw-r--r--gcc/cp/class.c98
-rw-r--r--gcc/cp/constexpr.c194
-rw-r--r--gcc/cp/constraint.cc4
-rw-r--r--gcc/cp/cp-gimplify.c14
-rw-r--r--gcc/cp/cp-objcp-common.c1
-rw-r--r--gcc/cp/cp-tree.h38
-rw-r--r--gcc/cp/cvt.c12
-rw-r--r--gcc/cp/decl.c136
-rw-r--r--gcc/cp/decl2.c26
-rw-r--r--gcc/cp/error.c2
-rw-r--r--gcc/cp/init.c12
-rw-r--r--gcc/cp/lambda.c30
-rw-r--r--gcc/cp/lex.c2
-rw-r--r--gcc/cp/name-lookup.c50
-rw-r--r--gcc/cp/parser.c203
-rw-r--r--gcc/cp/pt.c134
-rw-r--r--gcc/cp/semantics.c134
-rw-r--r--gcc/cp/tree.c49
-rw-r--r--gcc/cp/typeck.c40
-rw-r--r--gcc/cp/typeck2.c6
-rw-r--r--gcc/d/ChangeLog49
-rw-r--r--gcc/d/d-codegen.cc8
-rw-r--r--gcc/d/d-convert.cc1
-rw-r--r--gcc/d/intrinsics.cc5
-rw-r--r--gcc/d/runtime.cc8
-rw-r--r--gcc/data-streamer-in.c11
-rw-r--r--gcc/data-streamer-out.c9
-rw-r--r--gcc/data-streamer.h2
-rw-r--r--gcc/diagnostic.c3
-rw-r--r--gcc/diagnostic.h5
-rw-r--r--gcc/doc/extend.texi43
-rw-r--r--gcc/doc/include/gpl_v3.texi2
-rw-r--r--gcc/doc/install.texi7
-rw-r--r--gcc/doc/invoke.texi92
-rw-r--r--gcc/doc/md.texi6
-rw-r--r--gcc/doc/sourcebuild.texi88
-rw-r--r--gcc/doc/tm.texi10
-rw-r--r--gcc/doc/tm.texi.in2
-rw-r--r--gcc/doc/ux.texi2
-rw-r--r--gcc/domwalk.c15
-rw-r--r--gcc/dwarf2cfi.c7
-rw-r--r--gcc/fold-const-call.c38
-rw-r--r--gcc/fold-const.c206
-rw-r--r--gcc/fold-const.h2
-rw-r--r--gcc/fortran/ChangeLog358
-rw-r--r--gcc/fortran/arith.c50
-rw-r--r--gcc/fortran/arith.h5
-rw-r--r--gcc/fortran/array.c18
-rw-r--r--gcc/fortran/check.c690
-rw-r--r--gcc/fortran/decl.c36
-rw-r--r--gcc/fortran/dependency.c38
-rw-r--r--gcc/fortran/dependency.h3
-rw-r--r--gcc/fortran/dump-parse-tree.c33
-rw-r--r--gcc/fortran/expr.c84
-rw-r--r--gcc/fortran/frontend-passes.c127
-rw-r--r--gcc/fortran/gfortran.h27
-rw-r--r--gcc/fortran/gfortran.texi7
-rw-r--r--gcc/fortran/interface.c37
-rw-r--r--gcc/fortran/intrinsic.c56
-rw-r--r--gcc/fortran/intrinsic.texi10
-rw-r--r--gcc/fortran/invoke.texi34
-rw-r--r--gcc/fortran/lang.opt8
-rw-r--r--gcc/fortran/libgfortran.h2
-rw-r--r--gcc/fortran/match.c38
-rw-r--r--gcc/fortran/misc.c12
-rw-r--r--gcc/fortran/module.c16
-rw-r--r--gcc/fortran/options.c2
-rw-r--r--gcc/fortran/parse.c13
-rw-r--r--gcc/fortran/primary.c108
-rw-r--r--gcc/fortran/resolve.c168
-rw-r--r--gcc/fortran/simplify.c66
-rw-r--r--gcc/fortran/symbol.c115
-rw-r--r--gcc/fortran/target-memory.c43
-rw-r--r--gcc/fortran/trans-common.c73
-rw-r--r--gcc/fortran/trans-decl.c111
-rw-r--r--gcc/fortran/trans-expr.c3
-rw-r--r--gcc/fortran/trans-intrinsic.c10
-rw-r--r--gcc/fortran/trans.c81
-rw-r--r--gcc/fortran/trans.h3
-rw-r--r--gcc/function.c26
-rw-r--r--gcc/gcc.c42
-rw-r--r--gcc/gcc.h1
-rw-r--r--gcc/gensupport.c7
-rw-r--r--gcc/gimple-fold.c107
-rw-r--r--gcc/gimple-loop-versioning.cc2
-rw-r--r--gcc/gimple-ssa-evrp-analyze.c41
-rw-r--r--gcc/gimple-ssa-evrp-analyze.h6
-rw-r--r--gcc/gimple-ssa-evrp.c7
-rw-r--r--gcc/gimple-ssa-isolate-paths.c2
-rw-r--r--gcc/gimple-ssa-sprintf.c6
-rw-r--r--gcc/gimple.c26
-rw-r--r--gcc/gimple.h2
-rw-r--r--gcc/gimplify.c132
-rw-r--r--gcc/go/ChangeLog10
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc8
-rw-r--r--gcc/go/gofrontend/lex.cc279
-rw-r--r--gcc/go/gofrontend/lex.h8
-rw-r--r--gcc/go/gofrontend/runtime.def7
-rw-r--r--gcc/go/gofrontend/statements.cc42
-rw-r--r--gcc/go/gofrontend/statements.h19
-rw-r--r--gcc/inchash.h2
-rw-r--r--gcc/int-vector-builder.h9
-rw-r--r--gcc/internal-fn.c4
-rw-r--r--gcc/internal-fn.def4
-rw-r--r--gcc/ipa-cp.c10
-rw-r--r--gcc/ipa-devirt.c14
-rw-r--r--gcc/ipa-fnsummary.c26
-rw-r--r--gcc/ipa-icf.c214
-rw-r--r--gcc/ipa-inline-transform.c42
-rw-r--r--gcc/ipa-inline.c29
-rw-r--r--gcc/ipa-param-manipulation.c14
-rw-r--r--gcc/ipa-predicate.c4
-rw-r--r--gcc/ipa-predicate.h4
-rw-r--r--gcc/ipa-profile.c4
-rw-r--r--gcc/ipa-prop.c11
-rw-r--r--gcc/ipa-prop.h2
-rw-r--r--gcc/ipa-pure-const.c2
-rw-r--r--gcc/ipa-split.c5
-rw-r--r--gcc/jit/ChangeLog13
-rw-r--r--gcc/jit/jit-playback.c5
-rw-r--r--gcc/langhooks.c6
-rw-r--r--gcc/lra-constraints.c28
-rw-r--r--gcc/lra-int.h8
-rw-r--r--gcc/lra-lives.c8
-rw-r--r--gcc/lra-remat.c9
-rw-r--r--gcc/lra-spills.c13
-rw-r--r--gcc/lra.c66
-rw-r--r--gcc/lto-streamer-out.c10
-rw-r--r--gcc/lto-wrapper.c167
-rw-r--r--gcc/lto/ChangeLog282
-rw-r--r--gcc/lto/Make-lang.in2
-rw-r--r--gcc/lto/lto-common.c4
-rw-r--r--gcc/lto/lto-symtab.c3
-rw-r--r--gcc/machmode.h9
-rw-r--r--gcc/match.pd156
-rw-r--r--gcc/objc/ChangeLog92
-rw-r--r--gcc/objcp/ChangeLog20
-rw-r--r--gcc/omp-low.c106
-rw-r--r--gcc/omp-simd-clone.c13
-rw-r--r--gcc/optabs.c12
-rw-r--r--gcc/optabs.def3
-rw-r--r--gcc/optabs.h6
-rw-r--r--gcc/opts-common.c10
-rw-r--r--gcc/opts.c92
-rw-r--r--gcc/opts.h3
-rw-r--r--gcc/params.def22
-rw-r--r--gcc/passes.c68
-rw-r--r--gcc/po/ChangeLog8
-rw-r--r--gcc/po/uk.po96
-rw-r--r--gcc/predict.c78
-rw-r--r--gcc/print-tree.c6
-rw-r--r--gcc/profile.c40
-rw-r--r--gcc/reload1.c7
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/rtlanal.c17
-rw-r--r--gcc/rtx-vector-builder.h16
-rw-r--r--gcc/simplify-rtx.c178
-rw-r--r--gcc/sort.cc60
-rw-r--r--gcc/stmt.c57
-rw-r--r--gcc/symtab.c16
-rw-r--r--gcc/system.h9
-rw-r--r--gcc/target.def13
-rw-r--r--gcc/targhooks.c9
-rw-r--r--gcc/targhooks.h5
-rw-r--r--gcc/testsuite/ChangeLog1810
-rw-r--r--gcc/testsuite/ChangeLog-20184
-rw-r--r--gcc/testsuite/c-c++-common/array-1.c247
-rw-r--r--gcc/testsuite/c-c++-common/asan/memcmp-1.c4
-rw-r--r--gcc/testsuite/c-c++-common/gomp/clause-dups-1.c222
-rw-r--r--gcc/testsuite/c-c++-common/gomp/declare-target-2.c2
-rw-r--r--gcc/testsuite/c-c++-common/gomp/declare-target-4.c44
-rw-r--r--gcc/testsuite/c-c++-common/gomp/if-4.c60
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pr91401-1.c10
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pr91401-2.c15
-rw-r--r--gcc/testsuite/c-c++-common/gomp/target-data-1.c30
-rw-r--r--gcc/testsuite/c-c++-common/guality/Og-dce-1.c14
-rw-r--r--gcc/testsuite/c-c++-common/guality/Og-dce-2.c19
-rw-r--r--gcc/testsuite/c-c++-common/guality/Og-dce-3.c29
-rw-r--r--gcc/testsuite/c-c++-common/guality/Og-global-dse-1.c17
-rw-r--r--gcc/testsuite/c-c++-common/guality/Og-static-wo-1.c15
-rw-r--r--gcc/testsuite/c-c++-common/pr89888.c4
-rw-r--r--gcc/testsuite/c-c++-common/pr90590-1.c15
-rw-r--r--gcc/testsuite/c-c++-common/pr90590-1.h2
-rw-r--r--gcc/testsuite/c-c++-common/pr90590-2.c11
-rw-r--r--gcc/testsuite/c-c++-common/pr90590-2.h4
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/object-size-9.c2
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle53.C5
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle73.C96
-rw-r--r--gcc/testsuite/g++.dg/concepts/pr89036.C10
-rw-r--r--gcc/testsuite/g++.dg/conversion/simd4.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/Wnarrowing17.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/desig1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/enum20.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/enum28.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/gen-attrs-68.C40
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/gen-attrs-69.C40
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic9.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nontype2.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nontype3.C32
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nontype4.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nullptr42.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/range-for19.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/auto-fn56.C19
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-79520.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-neg1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const1.C72
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const10.C22
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const11.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const12.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const13.C20
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const14.C38
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const2.C23
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const3.C22
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const4.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const5.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const6.C22
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const7.C23
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const8.C23
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const9.C23
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-pretty1.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-init16.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/new1.C73
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/new2.C39
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/constexpr-if29.C28
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/nodiscard6.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/comma1.C26
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/comma2.C27
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/comma3.C27
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/comma4.C27
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/comma5.C21
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/cond-triv1.C46
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/cond-triv1a.C46
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/inline-asm1.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/inline-asm2.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/inline-asm3.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/nontype-class23.C102
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/typename17.C6
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-ctad-neg.C24
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-ctad-neg2.C20
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-ctad.C24
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-neg.C12
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-neg2.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp.C16
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/delete1.C14
-rw-r--r--gcc/testsuite/g++.dg/expr/cond15.C13
-rw-r--r--gcc/testsuite/g++.dg/expr/cond16.C25
-rw-r--r--gcc/testsuite/g++.dg/gcov/pr16855.C10
-rw-r--r--gcc/testsuite/g++.dg/guality/guality.exp18
-rw-r--r--gcc/testsuite/g++.dg/init/array53.C33
-rw-r--r--gcc/testsuite/g++.dg/ipa/ipa-icf-2.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/ipa-icf-3.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/ipa-icf-4.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/ipa-icf-6.C2
-rw-r--r--gcc/testsuite/g++.dg/lookup/missing-std-include-5.C1
-rw-r--r--gcc/testsuite/g++.dg/lookup/missing-std-include-6.C9
-rw-r--r--gcc/testsuite/g++.dg/lookup/missing-std-include-8.C9
-rw-r--r--gcc/testsuite/g++.dg/lto/devirt-19_0.C2
-rw-r--r--gcc/testsuite/g++.dg/lto/pr87906_0.C1
-rw-r--r--gcc/testsuite/g++.dg/lto/pr89330_0.C52
-rw-r--r--gcc/testsuite/g++.dg/lto/pr89330_1.C36
-rw-r--r--gcc/testsuite/g++.dg/other/friend3.C4
-rw-r--r--gcc/testsuite/g++.dg/parse/dtor5.C10
-rw-r--r--gcc/testsuite/g++.dg/parse/friend7.C6
-rw-r--r--gcc/testsuite/g++.dg/parse/typedef9.C4
-rw-r--r--gcc/testsuite/g++.dg/pr60517.C22
-rw-r--r--gcc/testsuite/g++.dg/template/error22.C2
-rw-r--r--gcc/testsuite/g++.dg/tls/thread_local-ice5.C7
-rw-r--r--gcc/testsuite/g++.dg/torture/pr90313.cc33
-rw-r--r--gcc/testsuite/g++.dg/torture/pr91270.C10
-rw-r--r--gcc/testsuite/g++.dg/torture/pr91280.C223
-rw-r--r--gcc/testsuite/g++.dg/torture/pr91334.C14
-rw-r--r--gcc/testsuite/g++.dg/tree-prof/devirt.C2
-rw-r--r--gcc/testsuite/g++.dg/tree-prof/indir-call-prof.C2
-rw-r--r--gcc/testsuite/g++.dg/tree-prof/morefunc.C2
-rw-r--r--gcc/testsuite/g++.dg/tree-prof/reorder.C2
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr19807.C3
-rw-r--r--gcc/testsuite/g++.dg/ubsan/vla-1.C10
-rw-r--r--gcc/testsuite/g++.dg/warn/Wsign-conversion-5.C18
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/err-msg5.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.eh/cond1.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/cond5.C4
-rw-r--r--gcc/testsuite/g++.target/aarch64/return_address_sign_ab_exception.C1
-rw-r--r--gcc/testsuite/g++.target/aarch64/return_address_sign_b_exception.C1
-rw-r--r--gcc/testsuite/g++.target/aarch64/sve/dup_sel_1.C21
-rw-r--r--gcc/testsuite/g++.target/aarch64/sve/dup_sel_2.C20
-rw-r--r--gcc/testsuite/g++.target/aarch64/sve/dup_sel_3.C21
-rw-r--r--gcc/testsuite/g++.target/aarch64/sve/dup_sel_4.C20
-rw-r--r--gcc/testsuite/g++.target/aarch64/sve/dup_sel_5.C18
-rw-r--r--gcc/testsuite/g++.target/aarch64/sve/dup_sel_6.C18
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr88140.c (renamed from gcc/testsuite/gcc.c-torture/pr88140.c)0
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c59
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-14.c56
-rw-r--r--gcc/testsuite/gcc.dg/attr-nonstring-2.c8
-rw-r--r--gcc/testsuite/gcc.dg/enum-redef-1.c29
-rw-r--r--gcc/testsuite/gcc.dg/format/pr80619.c89
-rw-r--r--gcc/testsuite/gcc.dg/gomp/pr91216.c20
-rw-r--r--gcc/testsuite/gcc.dg/guality/guality.exp18
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-10.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-11.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-12.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-13.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-16.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-18.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-20.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-21.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-23.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-25.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-26.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-27.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-35.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-36.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-37.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-39.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-7.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-8.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-icf-merge-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr64307.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr90555.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr79983.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr80170.c6
-rw-r--r--gcc/testsuite/gcc.dg/spellcheck-options-21.c3
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-44.c2
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-70.c331
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-71.c223
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-72.c69
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-73.c135
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-74.c175
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-75.c118
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-76.c174
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-77.c84
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-8.c8
-rw-r--r--gcc/testsuite/gcc.dg/struct-ret-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr91178-2.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr91267.c21
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr91323.c51
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr91445.c22
-rw-r--r--gcc/testsuite/gcc.dg/torture/ssa-fre-5.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/ssa-fre-6.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/ssa-fre-7.c1
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/ic-misattribution-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/indir-call-prof.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/stringop-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/stringop-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/val-prof-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/val-prof-7.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/forwprop-31.c7
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr86061.c20
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr91091-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-77.c2
-rw-r--r--gcc/testsuite/gcc.dg/type-convert-var.c9
-rw-r--r--gcc/testsuite/gcc.dg/uninit-pr50476.c18
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr91293-1.c19
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr91293-2.c19
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr91293-3.c20
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-cond-arith-7.c60
-rw-r--r--gcc/testsuite/gcc.misc-tests/help.exp28
-rw-r--r--gcc/testsuite/gcc.misc-tests/options.exp3
-rw-r--r--gcc/testsuite/gcc.target/aarch64/acle/tme.c34
-rw-r--r--gcc/testsuite/gcc.target/aarch64/asm-x-constraint-1.c34
-rw-r--r--gcc/testsuite/gcc.target/aarch64/asm-y-constraint-1.c36
-rw-r--r--gcc/testsuite/gcc.target/aarch64/fmul_scvtf_1.c140
-rw-r--r--gcc/testsuite/gcc.target/aarch64/no-inline-lrint_3.c17
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_2.c20
-rw-r--r--gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-2.c16
-rw-r--r--gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-3.c24
-rw-r--r--gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute.c16
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/adr_1.c46
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/adr_1_run.c31
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/adr_2.c21
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/adr_2_run.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/adr_3.c21
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/adr_3_run.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/adr_4.c9
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/adr_4_run.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/adr_5.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/adr_5_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/clastb_8.c25
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/clrsb_1.c22
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/clrsb_1_run.c50
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/clz_1.c22
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/clz_1_run.c50
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cnot_1.c30
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_abd_1.c42
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_abd_1_run.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_abd_2.c42
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_abd_2_run.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_abd_3.c46
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_abd_3_run.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_abd_4.c42
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_abd_4_run.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_abd_5.c46
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_abd_5_run.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_1.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_1_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_2.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_2_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_3.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_3_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_convert_1.c37
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_convert_1_run.c29
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_convert_2.c36
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_convert_2_run.c28
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_convert_3.c40
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_convert_3_run.c28
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_convert_4.c37
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_convert_4_run.c29
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_convert_5.c36
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_convert_5_run.c28
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_convert_6.c40
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_convert_6_run.c28
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_1.c29
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_1_run.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_2.c29
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_2_run.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_3.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_3_run.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_4.c29
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_4_run.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_5.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_5_run.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_1.c62
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_1_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_2.c56
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_2_run.c31
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_3.c65
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_3_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_4.c64
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_4_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_1.c55
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_1_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_2.c48
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_2_run.c31
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_3.c54
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_3_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_4.c53
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_4_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_1.c29
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_1_run.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_2.c23
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_2_run.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_3.c28
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_3_run.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_4.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_4_run.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_1.c47
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_1_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_2.c44
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_2_run.c31
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_3.c50
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_3_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_4.c49
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_4_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_1.c47
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_1_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_2.c44
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_2_run.c31
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_3.c50
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_3_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_4.c49
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_4_run.c32
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_logical_1.c62
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_logical_1_run.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_logical_2.c63
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_logical_2_run.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_logical_3.c66
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_logical_3_run.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_logical_4.c62
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_logical_4_run.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_logical_5.c66
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_logical_5_run.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_1.c52
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_1_run.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_2.c53
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_2_run.c36
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_3.c52
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_3_run.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_4.c56
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_4_run.c36
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_5.c56
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_5_run.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_6.c53
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_6_run.c35
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_7.c62
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_7_run.c34
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_8.c62
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_mla_8_run.c34
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_1.c48
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_1_run.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_2.c52
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_2_run.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_3.c48
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_3_run.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_4.c52
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_4_run.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_5.c38
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_5_run.c28
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_6.c33
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_6_run.c28
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_7.c40
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_7_run.c28
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_8.c38
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_8_run.c28
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_9.c40
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_shift_9_run.c28
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_unary_1.c59
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_unary_1_run.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_unary_2.c61
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_unary_2_run.c28
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_unary_3.c58
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_unary_3_run.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_unary_4.c62
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_unary_4_run.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_1.c40
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_1_run.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_2.c40
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_2_run.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_3.c39
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_3_run.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_4.c36
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_4_run.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/const_1.c13
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/const_2.c20
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/const_3.c20
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/ext_2.c3
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/ext_3.c17
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/fmaxnm_1.c45
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/fminnm_1.c21
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/init_1.c20
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/init_10.c24
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/init_11.c22
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/init_12.c27
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/init_13.c17
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/init_2.c24
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/init_3.c21
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/init_4.c26
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/init_5.c20
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/init_6.c22
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/init_7.c30
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/init_8.c30
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/init_9.c20
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/ld1r_2.c22
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/loop_add_4.c6
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/mask_load_1.c12
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/peel_ind_1.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/peel_ind_2.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/pr91166.c20
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/revb_1.c6
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/revb_2.c10
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/revh_1.c6
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/revh_2.c9
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/revw_1.c6
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/revw_2.c8
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/shift_1.c6
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/single_1.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/single_2.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/single_3.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/single_4.c5
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/slp_2.c9
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/slp_3.c11
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/slp_4.c8
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/smax_1.c71
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/smin_1.c71
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/spill_2.c17
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/spill_4.c9
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/umax_1.c65
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/umin_1.c65
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/vcond_17.c94
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/vcond_17_run.c54
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/vcond_18.c44
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/vcond_18_run.c30
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/vcond_19.c46
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/vcond_19_run.c30
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/vcond_20.c46
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/vcond_20_run.c30
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/vcond_21.c34
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/vcond_21_run.c31
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/while_10.c25
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/while_6.c25
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/while_7.c25
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/while_8.c25
-rw-r--r--gcc/testsuite/gcc.target/aarch64/sve/while_9.c25
-rw-r--r--gcc/testsuite/gcc.target/aarch64/vect-clz.c2
-rw-r--r--gcc/testsuite/gcc.target/arc/arc.exp18
-rw-r--r--gcc/testsuite/gcc.target/arc/builtin_special.c2
-rw-r--r--gcc/testsuite/gcc.target/arc/interrupt-1.c4
-rw-r--r--gcc/testsuite/gcc.target/arc/interrupt-10.c36
-rw-r--r--gcc/testsuite/gcc.target/arc/interrupt-11.c16
-rw-r--r--gcc/testsuite/gcc.target/arc/interrupt-12.c16
-rw-r--r--gcc/testsuite/gcc.target/arc/interrupt-6.c5
-rw-r--r--gcc/testsuite/gcc.target/arm/cmse/cmse-17.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/asm-4.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-ceil-sfix-2-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-ceil-sfix-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-ceil-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-ceilf-sfix-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-ceilf-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-cvt-2-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-cvt-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-floor-sfix-2-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-floor-sfix-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-floor-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-floorf-sfix-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-floorf-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-loadu2-m128-1.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-loadu2-m128-2.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-loadu2-m128d-1.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-loadu2-m128d-2.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-loadu2-m128i-1.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-loadu2-m128i-2.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-rint-sfix-2-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-rint-sfix-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-rint-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-rintf-sfix-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-rintf-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-round-sfix-2-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-round-sfix-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-round-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-roundf-sfix-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-roundf-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-storeu2-m128-1.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-storeu2-m128-2.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-storeu2-m128d-1.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-storeu2-m128d-2.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-storeu2-m128i-1.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-storeu2-m128i-2.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-trunc-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-truncf-vec.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-typecast-1.c83
-rw-r--r--gcc/testsuite/gcc.target/i386/avx-typecast-2.c46
-rw-r--r--gcc/testsuite/gcc.target/i386/avx2-pr91201.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-pr91150.c37
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-pr91201.c6
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-ceil-sfix-vec-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-ceil-vec-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-ceilf-sfix-vec-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-ceilf-vec-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-floor-sfix-vec-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-floor-vec-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-floorf-sfix-vec-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-floorf-vec-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-rint-sfix-vec-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-rintf-sfix-vec-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-round-sfix-vec-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-roundf-sfix-vec-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-trunc-vec-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-truncf-vec-1.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-typecast-2.c71
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vfixupimmpd-2.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vfixupimmps-2.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vfixupimmsd-2.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vfixupimmss-2.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vp2intersect-2intersect-1b.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vp2intersect-2intersectvl-1b.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/math_m_pi.h10
-rw-r--r--gcc/testsuite/gcc.target/i386/minmax-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/minmax-2.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/minmax-3.c27
-rw-r--r--gcc/testsuite/gcc.target/i386/minmax-4.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/minmax-5.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/minmax-6.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/pr73350.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr80969-3.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr85044.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/pr85693-1.c21
-rw-r--r--gcc/testsuite/gcc.target/i386/pr85693.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91154.c20
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91223.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91385.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91408.c29
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91469-1.c17
-rw-r--r--gcc/testsuite/gcc.target/i386/pr91469-2.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/sse2-cvt-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse2-mul-1.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/sse2-pr91201-2.c21
-rw-r--r--gcc/testsuite/gcc.target/i386/sse2-pr91201-3.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/sse2-pr91201-4.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/sse2-pr91201-5.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/sse2-pr91201-6.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/sse2-pr91201.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-blendps-2.c7
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-blendps.c7
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-ceil-sfix-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-ceil-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-ceilf-sfix-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-ceilf-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-floor-sfix-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-floor-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-floorf-sfix-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-floorf-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-pr91201.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-rint-sfix-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-rint-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-rintf-sfix-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-rintf-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-round-sfix-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-round-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-round.h2
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundf-sfix-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundf-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundpd-1.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundpd-2.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundpd-3.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundps-1.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundps-2.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundps-3.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundsd-1.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundsd-2.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundsd-3.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundsd-4.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundss-1.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundss-2.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundss-3.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-roundss-4.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-trunc-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/sse4_1-truncf-vec.c3
-rw-r--r--gcc/testsuite/gcc.target/i386/xop-vshift-1.c9
-rw-r--r--gcc/testsuite/gcc.target/msp430/asm-register-names-lower-case.c25
-rw-r--r--gcc/testsuite/gcc.target/msp430/asm-register-names-upper-case.c25
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices-main.c6
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/README17
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/bad-devices-1.c5
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/bad-devices-1.csv3
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/bad-devices-2.c5
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/bad-devices-2.csv3
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/bad-devices-3.c5
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/bad-devices-3.csv3
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/bad-devices-4.c5
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/bad-devices-4.csv3
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/bad-devices-5.c5
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/bad-devices-5.csv3
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/bad-devices-6.c5
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/bad-devices-6.csv3
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-device-order.c11
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430_00.c7
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430_01.c7
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430_02.c7
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430_04.c7
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430_08.c7
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430_10.c6
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430_11.c6
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430_12.c6
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430_14.c6
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430_18.c6
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430_20.c6
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430_21.c6
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430_22.c6
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430_24.c6
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430_28.c6
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/csv-msp430fr5969.c11
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/devices.csv22
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/hard-cc430f5123.c7
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/hard-foo.c6
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/hard-msp430afe253.c8
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/hard-msp430cg4616.c7
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/hard-msp430f4783.c8
-rw-r--r--gcc/testsuite/gcc.target/msp430/devices/hard-rf430frl154h_rom.c8
-rw-r--r--gcc/testsuite/gcc.target/msp430/msp430.exp96
-rw-r--r--gcc/testsuite/gcc.target/msp430/pr78818-data-region.c3
-rw-r--r--gcc/testsuite/gcc.target/msp430/pr80993.c1
-rw-r--r--gcc/testsuite/gcc.target/msp430/region-attribute-misuse.c16
-rw-r--r--gcc/testsuite/gcc.target/msp430/region-misuse-code-data.c4
-rw-r--r--gcc/testsuite/gcc.target/msp430/region-misuse-code.c4
-rw-r--r--gcc/testsuite/gcc.target/msp430/region-misuse-data.c4
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bmi2-bzhi64-1a.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/direct-move.h2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vec-rotate-1.c39
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vec-rotate-2.c18
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vec-rotate-3.c40
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vec-rotate-4.c19
-rw-r--r--gcc/testsuite/gcc.target/riscv/attribute-10.c6
-rw-r--r--gcc/testsuite/gcc.target/riscv/flattened-struct-abi-1.c9
-rw-r--r--gcc/testsuite/gcc.target/riscv/flattened-struct-abi-2.c9
-rw-r--r--gcc/testsuite/gcc.target/riscv/pr91441.c10
-rw-r--r--gcc/testsuite/gcc.target/riscv/promote-type-for-libcall.c37
-rw-r--r--gcc/testsuite/gcc.target/s390/addsub-signed-overflow-1.c81
-rw-r--r--gcc/testsuite/gcc.target/s390/addsub-signed-overflow-2.c80
-rw-r--r--gcc/testsuite/gcc.target/s390/mul-signed-overflow-1.c56
-rw-r--r--gcc/testsuite/gcc.target/s390/mul-signed-overflow-2.c56
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54236-6.c2
-rw-r--r--gcc/testsuite/gcc.target/sparc/setjmp-1.c4
-rw-r--r--gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/gen.cc2
-rw-r--r--gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/ms-sysv.c2
-rw-r--r--gcc/testsuite/gdc.dg/pr90601.d22
-rw-r--r--gcc/testsuite/gdc.dg/pr91238.d18
-rw-r--r--gcc/testsuite/gfortran.dg/achar_5.f905
-rw-r--r--gcc/testsuite/gfortran.dg/allocated_1.f9024
-rw-r--r--gcc/testsuite/gfortran.dg/allocated_2.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/altreturn_10.f902
-rw-r--r--gcc/testsuite/gfortran.dg/argument_checking_19.f9018
-rw-r--r--gcc/testsuite/gfortran.dg/arithmetic_overflow_1.f906
-rw-r--r--gcc/testsuite/gfortran.dg/auto_in_equiv_1.f9036
-rw-r--r--gcc/testsuite/gfortran.dg/auto_in_equiv_2.f9038
-rw-r--r--gcc/testsuite/gfortran.dg/auto_in_equiv_3.f9063
-rw-r--r--gcc/testsuite/gfortran.dg/boz_1.f9026
-rw-r--r--gcc/testsuite/gfortran.dg/boz_11.f9011
-rw-r--r--gcc/testsuite/gfortran.dg/boz_12.f907
-rw-r--r--gcc/testsuite/gfortran.dg/boz_3.f9023
-rw-r--r--gcc/testsuite/gfortran.dg/boz_4.f9035
-rw-r--r--gcc/testsuite/gfortran.dg/boz_5.f902
-rw-r--r--gcc/testsuite/gfortran.dg/boz_6.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/boz_7.f904
-rw-r--r--gcc/testsuite/gfortran.dg/boz_8.f909
-rw-r--r--gcc/testsuite/gfortran.dg/boz_bge.f9022
-rw-r--r--gcc/testsuite/gfortran.dg/boz_complex_1.f9017
-rw-r--r--gcc/testsuite/gfortran.dg/boz_complex_2.f9015
-rw-r--r--gcc/testsuite/gfortran.dg/boz_complex_3.f9015
-rw-r--r--gcc/testsuite/gfortran.dg/boz_dble.f906
-rw-r--r--gcc/testsuite/gfortran.dg/boz_dshift_1.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/boz_dshift_2.f9012
-rw-r--r--gcc/testsuite/gfortran.dg/boz_float_1.f904
-rw-r--r--gcc/testsuite/gfortran.dg/boz_float_2.f905
-rw-r--r--gcc/testsuite/gfortran.dg/boz_float_3.f907
-rw-r--r--gcc/testsuite/gfortran.dg/boz_iand_1.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/boz_iand_2.f9017
-rw-r--r--gcc/testsuite/gfortran.dg/boz_int.f9013
-rw-r--r--gcc/testsuite/gfortran.dg/dec_structure_6.f906
-rw-r--r--gcc/testsuite/gfortran.dg/dec_union_1.f906
-rw-r--r--gcc/testsuite/gfortran.dg/dec_union_11.f902
-rw-r--r--gcc/testsuite/gfortran.dg/dec_union_2.f907
-rw-r--r--gcc/testsuite/gfortran.dg/dec_union_5.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/deferred_character_34.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/dependency_54.f9024
-rw-r--r--gcc/testsuite/gfortran.dg/do_subscript_3.f9022
-rw-r--r--gcc/testsuite/gfortran.dg/do_subscript_4.f9011
-rw-r--r--gcc/testsuite/gfortran.dg/do_subscript_5.f9020
-rw-r--r--gcc/testsuite/gfortran.dg/dshift_3.f902
-rw-r--r--gcc/testsuite/gfortran.dg/equiv_10.f9015
-rw-r--r--gcc/testsuite/gfortran.dg/gnu_logical_1.F91
-rw-r--r--gcc/testsuite/gfortran.dg/gnu_logical_2.f9024
-rw-r--r--gcc/testsuite/gfortran.dg/hollerith8.f906
-rw-r--r--gcc/testsuite/gfortran.dg/ibits.f904
-rw-r--r--gcc/testsuite/gfortran.dg/illegal_boz_arg_1.f909
-rw-r--r--gcc/testsuite/gfortran.dg/inquire_recl_f2018.f907
-rw-r--r--gcc/testsuite/gfortran.dg/int_conv_1.f9021
-rw-r--r--gcc/testsuite/gfortran.dg/integer_exponentiation_2.f9024
-rw-r--r--gcc/testsuite/gfortran.dg/ishft_1.f901
-rw-r--r--gcc/testsuite/gfortran.dg/merge_bits_3.f905
-rw-r--r--gcc/testsuite/gfortran.dg/merge_bits_4.f907
-rw-r--r--gcc/testsuite/gfortran.dg/nan_4.f908
-rw-r--r--gcc/testsuite/gfortran.dg/no_range_check_3.f906
-rw-r--r--gcc/testsuite/gfortran.dg/pr16433.f4
-rw-r--r--gcc/testsuite/gfortran.dg/pr41011.f2
-rw-r--r--gcc/testsuite/gfortran.dg/pr44491.f902
-rw-r--r--gcc/testsuite/gfortran.dg/pr58027.f902
-rw-r--r--gcc/testsuite/gfortran.dg/pr70754.f9013
-rw-r--r--gcc/testsuite/gfortran.dg/pr71649.f908
-rw-r--r--gcc/testsuite/gfortran.dg/pr78719_1.f9029
-rw-r--r--gcc/testsuite/gfortran.dg/pr78719_2.f9032
-rw-r--r--gcc/testsuite/gfortran.dg/pr78719_3.f9032
-rw-r--r--gcc/testsuite/gfortran.dg/pr78739.f9015
-rw-r--r--gcc/testsuite/gfortran.dg/pr81509_2.f904
-rw-r--r--gcc/testsuite/gfortran.dg/pr87991.f9011
-rw-r--r--gcc/testsuite/gfortran.dg/pr87993.f908
-rw-r--r--gcc/testsuite/gfortran.dg/pr88072.f9030
-rw-r--r--gcc/testsuite/gfortran.dg/pr89647.f9033
-rw-r--r--gcc/testsuite/gfortran.dg/pr90985.f9014
-rw-r--r--gcc/testsuite/gfortran.dg/pr91296.f9027
-rw-r--r--gcc/testsuite/gfortran.dg/pr91359_1.f16
-rw-r--r--gcc/testsuite/gfortran.dg/pr91359_2.f16
-rw-r--r--gcc/testsuite/gfortran.dg/pr91372.f909
-rw-r--r--gcc/testsuite/gfortran.dg/pr91471.f9014
-rw-r--r--gcc/testsuite/gfortran.dg/pr91485.f9024
-rw-r--r--gcc/testsuite/gfortran.dg/random_seed_1.f907
-rw-r--r--gcc/testsuite/gfortran.dg/unf_io_convert_1.f9012
-rw-r--r--gcc/testsuite/gfortran.dg/unf_io_convert_2.f9012
-rw-r--r--gcc/testsuite/gfortran.dg/unlimited_polymorphic_28.f902
-rw-r--r--gcc/testsuite/gfortran.dg/use_15.f904
-rw-r--r--gcc/testsuite/gfortran.dg/use_rename_8.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/whole_file_1.f904
-rw-r--r--gcc/testsuite/gfortran.dg/whole_file_2.f904
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_fraction_exponent.f9018
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mvbits.f904
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.f9011
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/execute/seq_io.f9012
-rw-r--r--gcc/testsuite/gnat.dg/aggr26.adb10
-rw-r--r--gcc/testsuite/gnat.dg/aggr27.adb26
-rw-r--r--gcc/testsuite/gnat.dg/alignment15.adb17
-rw-r--r--gcc/testsuite/gnat.dg/allocator2.adb6
-rw-r--r--gcc/testsuite/gnat.dg/allocator2.ads15
-rw-r--r--gcc/testsuite/gnat.dg/anon3.adb6
-rw-r--r--gcc/testsuite/gnat.dg/anon3.ads4
-rw-r--r--gcc/testsuite/gnat.dg/array37.adb19
-rw-r--r--gcc/testsuite/gnat.dg/assert2.adb5
-rw-r--r--gcc/testsuite/gnat.dg/assert2.ads15
-rw-r--r--gcc/testsuite/gnat.dg/case_optimization3.adb25
-rw-r--r--gcc/testsuite/gnat.dg/case_optimization3.ads10
-rw-r--r--gcc/testsuite/gnat.dg/casesi.adb28
-rw-r--r--gcc/testsuite/gnat.dg/casesi.ads4
-rw-r--r--gcc/testsuite/gnat.dg/discr56.adb5
-rw-r--r--gcc/testsuite/gnat.dg/discr56.ads9
-rw-r--r--gcc/testsuite/gnat.dg/discr56_pkg1.adb6
-rw-r--r--gcc/testsuite/gnat.dg/discr56_pkg1.ads14
-rw-r--r--gcc/testsuite/gnat.dg/discr56_pkg2.ads11
-rw-r--r--gcc/testsuite/gnat.dg/discr57.adb17
-rw-r--r--gcc/testsuite/gnat.dg/elab8.adb12
-rw-r--r--gcc/testsuite/gnat.dg/elab8_gen.adb12
-rw-r--r--gcc/testsuite/gnat.dg/elab8_gen.ads8
-rw-r--r--gcc/testsuite/gnat.dg/elab8_pkg.adb5
-rw-r--r--gcc/testsuite/gnat.dg/elab8_pkg.ads5
-rw-r--r--gcc/testsuite/gnat.dg/equal10.adb5
-rw-r--r--gcc/testsuite/gnat.dg/equal10.ads7
-rw-r--r--gcc/testsuite/gnat.dg/equal11.adb37
-rw-r--r--gcc/testsuite/gnat.dg/equal11_interface.ads7
-rw-r--r--gcc/testsuite/gnat.dg/equal11_record.adb10
-rw-r--r--gcc/testsuite/gnat.dg/equal11_record.ads21
-rw-r--r--gcc/testsuite/gnat.dg/expr_func9.adb24
-rw-r--r--gcc/testsuite/gnat.dg/float_value1.adb2
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst10.adb26
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst10_pkg.ads11
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst11.adb9
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst11_pkg.adb21
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst11_pkg.ads5
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst12.adb12
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst12_pkg1.adb13
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst12_pkg1.ads11
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst12_pkg2.ads3
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst7.adb11
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst7_pkg.adb12
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst7_pkg.ads8
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst7_types.ads15
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst8.adb8
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst8.ads7
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst8_g.adb12
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst8_g.ads17
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst9.adb5
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst9.ads11
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst9_pkg1-operator.ads10
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst9_pkg1.ads12
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst9_pkg2.adb9
-rw-r--r--gcc/testsuite/gnat.dg/generic_inst9_pkg2.ads17
-rw-r--r--gcc/testsuite/gnat.dg/inline18.adb6
-rw-r--r--gcc/testsuite/gnat.dg/inline18.ads6
-rw-r--r--gcc/testsuite/gnat.dg/inline18_gen1-inner_g.ads8
-rw-r--r--gcc/testsuite/gnat.dg/inline18_gen1.adb9
-rw-r--r--gcc/testsuite/gnat.dg/inline18_gen1.ads14
-rw-r--r--gcc/testsuite/gnat.dg/inline18_gen2.adb10
-rw-r--r--gcc/testsuite/gnat.dg/inline18_gen2.ads11
-rw-r--r--gcc/testsuite/gnat.dg/inline18_gen3.adb12
-rw-r--r--gcc/testsuite/gnat.dg/inline18_gen3.ads13
-rw-r--r--gcc/testsuite/gnat.dg/inline18_pkg1.adb8
-rw-r--r--gcc/testsuite/gnat.dg/inline18_pkg1.ads19
-rw-r--r--gcc/testsuite/gnat.dg/inline18_pkg2-child.ads9
-rw-r--r--gcc/testsuite/gnat.dg/inline18_pkg2.ads2
-rw-r--r--gcc/testsuite/gnat.dg/inline19.adb17
-rw-r--r--gcc/testsuite/gnat.dg/inline19.ads8
-rw-r--r--gcc/testsuite/gnat.dg/no_caching.adb29
-rw-r--r--gcc/testsuite/gnat.dg/no_caching.ads8
-rw-r--r--gcc/testsuite/gnat.dg/null_check.adb19
-rw-r--r--gcc/testsuite/gnat.dg/openacc1.adb12
-rw-r--r--gcc/testsuite/gnat.dg/opt81.adb20
-rw-r--r--gcc/testsuite/gnat.dg/opt81.ads15
-rw-r--r--gcc/testsuite/gnat.dg/predicate12.adb6
-rw-r--r--gcc/testsuite/gnat.dg/predicate12.ads42
-rw-r--r--gcc/testsuite/gnat.dg/range_check6.adb28
-rw-r--r--gcc/testsuite/gnat.dg/range_check7.adb22
-rw-r--r--gcc/testsuite/gnat.dg/renaming15.adb32
-rw-r--r--gcc/testsuite/gnat.dg/rep_clause9.adb23
-rw-r--r--gcc/testsuite/gnat.dg/slice10.adb29
-rw-r--r--gcc/testsuite/gnat.dg/suppress_initialization2.adb5
-rw-r--r--gcc/testsuite/gnat.dg/suppress_initialization2.ads13
-rw-r--r--gcc/testsuite/gnat.dg/tag2.adb20
-rw-r--r--gcc/testsuite/gnat.dg/tag2_pkg.ads16
-rw-r--r--gcc/testsuite/gnat.dg/tagged3.adb42
-rw-r--r--gcc/testsuite/gnat.dg/tagged3_pkg.adb12
-rw-r--r--gcc/testsuite/gnat.dg/tagged3_pkg.ads9
-rw-r--r--gcc/testsuite/gnat.dg/tagged4.adb28
-rw-r--r--gcc/testsuite/gnat.dg/task5.adb26
-rw-r--r--gcc/testsuite/gnat.dg/test_casesi.adb12
-rw-r--r--gcc/testsuite/gnat.dg/valid_scalars2.adb25
-rw-r--r--gcc/testsuite/gnat.dg/warn27.adb10
-rw-r--r--gcc/testsuite/gnat.dg/warn28.adb36
-rw-r--r--gcc/testsuite/gnat.dg/warn28.ads9
-rw-r--r--gcc/testsuite/gnat.dg/warn29.adb11
-rw-r--r--gcc/testsuite/gnat.dg/warn29.ads4
-rw-r--r--gcc/testsuite/lib/options.exp27
-rw-r--r--gcc/testsuite/lib/scanasm.exp178
-rw-r--r--gcc/testsuite/lib/target-supports.exp38
-rw-r--r--gcc/testsuite/obj-c++.dg/stubify-1.mm2
-rw-r--r--gcc/testsuite/obj-c++.dg/stubify-2.mm2
-rw-r--r--gcc/testsuite/objc.dg/stubify-1.m2
-rw-r--r--gcc/testsuite/objc.dg/stubify-2.m2
-rw-r--r--gcc/timevar.def2
-rw-r--r--gcc/toplev.c14
-rw-r--r--gcc/trans-mem.c3
-rw-r--r--gcc/tree-call-cdce.c4
-rw-r--r--gcc/tree-cfg.c3
-rw-r--r--gcc/tree-core.h48
-rw-r--r--gcc/tree-if-conv.c4
-rw-r--r--gcc/tree-inline.c2
-rw-r--r--gcc/tree-nested.c26
-rw-r--r--gcc/tree-pretty-print.c22
-rw-r--r--gcc/tree-scalar-evolution.c407
-rw-r--r--gcc/tree-sra.c6
-rw-r--r--gcc/tree-ssa-ccp.c9
-rw-r--r--gcc/tree-ssa-dce.c86
-rw-r--r--gcc/tree-ssa-dom.c2
-rw-r--r--gcc/tree-ssa-forwprop.c313
-rw-r--r--gcc/tree-ssa-loop-im.c30
-rw-r--r--gcc/tree-ssa-math-opts.c78
-rw-r--r--gcc/tree-ssa-pre.c6
-rw-r--r--gcc/tree-ssa-propagate.c9
-rw-r--r--gcc/tree-ssa-sccvn.c307
-rw-r--r--gcc/tree-ssa-sccvn.h23
-rw-r--r--gcc/tree-ssa-strlen.c526
-rw-r--r--gcc/tree-ssa-strlen.h2
-rw-r--r--gcc/tree-ssa-structalias.c113
-rw-r--r--gcc/tree-ssa-threadedge.c3
-rw-r--r--gcc/tree-ssanames.c8
-rw-r--r--gcc/tree-streamer-in.c20
-rw-r--r--gcc/tree-streamer-out.c5
-rw-r--r--gcc/tree-tailcall.c29
-rw-r--r--gcc/tree-vect-patterns.c2
-rw-r--r--gcc/tree-vect-slp.c3
-rw-r--r--gcc/tree-vect-stmts.c5
-rw-r--r--gcc/tree-vector-builder.c97
-rw-r--r--gcc/tree-vector-builder.h20
-rw-r--r--gcc/tree-vectorizer.c5
-rw-r--r--gcc/tree-vrp.c540
-rw-r--r--gcc/tree-vrp.h26
-rw-r--r--gcc/tree.c93
-rw-r--r--gcc/tree.def5
-rw-r--r--gcc/tree.h140
-rw-r--r--gcc/value-prof.c157
-rw-r--r--gcc/value-prof.h9
-rw-r--r--gcc/varasm.c11
-rw-r--r--gcc/vec.c21
-rw-r--r--gcc/vec.h81
-rw-r--r--gcc/vector-builder.h209
-rw-r--r--gcc/vr-values.c238
-rw-r--r--gcc/vr-values.h11
-rw-r--r--gcc/wide-int.h18
-rw-r--r--include/ChangeLog5
-rw-r--r--include/libiberty.h4
-rw-r--r--libcpp/po/ChangeLog4
-rw-r--r--libcpp/po/zh_TW.po46
-rw-r--r--libgcc/ChangeLog13
-rw-r--r--libgcc/config.host3
-rw-r--r--libgcc/config/arm/cmse.c1
-rw-r--r--libgcc/config/pa/t-netbsd9
-rw-r--r--libgfortran/ChangeLog42
-rw-r--r--libgfortran/gfortran.map5
-rw-r--r--libgfortran/intrinsics/random.c216
-rw-r--r--libgfortran/io/inquire.c4
-rw-r--r--libgfortran/libgfortran.h4
-rw-r--r--libgfortran/runtime/error.c46
-rw-r--r--libgo/go/runtime/mcentral.go9
-rw-r--r--libgo/go/runtime/mgcmark.go5
-rw-r--r--libgo/go/runtime/mgcsweep.go38
-rw-r--r--libgo/go/runtime/mwbbuf.go9
-rw-r--r--libgo/go/runtime/panic.go38
-rw-r--r--libgo/go/runtime/runtime1.go19
-rw-r--r--libgo/go/runtime/runtime2.go9
-rw-r--r--libgo/go/runtime/stack_test.go62
-rw-r--r--libgomp/ChangeLog49
-rw-r--r--libgomp/target.c35
-rw-r--r--libgomp/testsuite/libgomp.c++/for-27.C169
-rw-r--r--libgomp/testsuite/libgomp.c++/loop-13.C298
-rw-r--r--libgomp/testsuite/libgomp.c++/loop-14.C301
-rw-r--r--libgomp/testsuite/libgomp.c++/loop-15.C417
-rw-r--r--libgomp/testsuite/libgomp.c++/target-22.C99
-rw-r--r--libgomp/testsuite/libgomp.c++/target-9.C43
-rw-r--r--libgomp/testsuite/libgomp.c/target-18.c30
-rw-r--r--libgomp/testsuite/libgomp.c/target-37.c71
-rw-r--r--libgomp/testsuite/libgomp.fortran/appendix-a/a.28.5.f902
-rw-r--r--libgomp/testsuite/libgomp.fortran/reduction4.f9056
-rw-r--r--libgomp/testsuite/libgomp.fortran/reduction5.f9010
-rw-r--r--libgomp/testsuite/libgomp.oacc-fortran/routine-7.f902
-rw-r--r--libiberty/ChangeLog17
-rw-r--r--libiberty/Makefile.in14
-rw-r--r--libiberty/filedescriptor.c47
-rw-r--r--libiberty/simple-object-elf.c4
-rw-r--r--libquadmath/ChangeLog6
-rw-r--r--libquadmath/quadmath.h28
-rw-r--r--libsanitizer/ChangeLog60
-rw-r--r--libsanitizer/LOCAL_PATCHES9
-rw-r--r--libsanitizer/MERGE2
-rw-r--r--libsanitizer/asan/Makefile.am63
-rw-r--r--libsanitizer/asan/Makefile.in128
-rw-r--r--libsanitizer/asan/asan_activation.cpp (renamed from libsanitizer/asan/asan_activation.cc)7
-rw-r--r--libsanitizer/asan/asan_activation.h5
-rw-r--r--libsanitizer/asan/asan_activation_flags.inc5
-rw-r--r--libsanitizer/asan/asan_allocator.cpp (renamed from libsanitizer/asan/asan_allocator.cc)18
-rw-r--r--libsanitizer/asan/asan_allocator.h44
-rw-r--r--libsanitizer/asan/asan_debugging.cpp (renamed from libsanitizer/asan/asan_debugging.cc)7
-rw-r--r--libsanitizer/asan/asan_descriptions.cpp (renamed from libsanitizer/asan/asan_descriptions.cc)7
-rw-r--r--libsanitizer/asan/asan_descriptions.h7
-rw-r--r--libsanitizer/asan/asan_errors.cpp (renamed from libsanitizer/asan/asan_errors.cc)22
-rw-r--r--libsanitizer/asan/asan_errors.h27
-rw-r--r--libsanitizer/asan/asan_fake_stack.cpp (renamed from libsanitizer/asan/asan_fake_stack.cc)7
-rw-r--r--libsanitizer/asan/asan_fake_stack.h7
-rw-r--r--libsanitizer/asan/asan_flags.cpp (renamed from libsanitizer/asan/asan_flags.cc)13
-rw-r--r--libsanitizer/asan/asan_flags.h5
-rw-r--r--libsanitizer/asan/asan_flags.inc9
-rw-r--r--libsanitizer/asan/asan_fuchsia.cpp (renamed from libsanitizer/asan/asan_fuchsia.cc)20
-rw-r--r--libsanitizer/asan/asan_globals.cpp (renamed from libsanitizer/asan/asan_globals.cc)31
-rw-r--r--libsanitizer/asan/asan_globals_win.cpp (renamed from libsanitizer/asan/asan_globals_win.cc)7
-rw-r--r--libsanitizer/asan/asan_init_version.h5
-rw-r--r--libsanitizer/asan/asan_interceptors.cpp (renamed from libsanitizer/asan/asan_interceptors.cc)18
-rw-r--r--libsanitizer/asan/asan_interceptors.h32
-rw-r--r--libsanitizer/asan/asan_interceptors_memintrinsics.cpp (renamed from libsanitizer/asan/asan_interceptors_memintrinsics.cc)7
-rw-r--r--libsanitizer/asan/asan_interceptors_memintrinsics.h7
-rw-r--r--libsanitizer/asan/asan_interceptors_vfork.S12
-rw-r--r--libsanitizer/asan/asan_interface.inc6
-rw-r--r--libsanitizer/asan/asan_interface_internal.h7
-rw-r--r--libsanitizer/asan/asan_internal.h22
-rw-r--r--libsanitizer/asan/asan_linux.cpp (renamed from libsanitizer/asan/asan_linux.cc)14
-rw-r--r--libsanitizer/asan/asan_mac.cpp (renamed from libsanitizer/asan/asan_mac.cc)11
-rw-r--r--libsanitizer/asan/asan_malloc_linux.cpp (renamed from libsanitizer/asan/asan_malloc_linux.cc)17
-rw-r--r--libsanitizer/asan/asan_malloc_local.h30
-rw-r--r--libsanitizer/asan/asan_malloc_mac.cpp (renamed from libsanitizer/asan/asan_malloc_mac.cc)46
-rw-r--r--libsanitizer/asan/asan_malloc_win.cc259
-rw-r--r--libsanitizer/asan/asan_malloc_win.cpp553
-rw-r--r--libsanitizer/asan/asan_mapping.h25
-rw-r--r--libsanitizer/asan/asan_mapping_myriad.h5
-rw-r--r--libsanitizer/asan/asan_mapping_sparc64.h5
-rw-r--r--libsanitizer/asan/asan_memory_profile.cpp (renamed from libsanitizer/asan/asan_memory_profile.cc)7
-rw-r--r--libsanitizer/asan/asan_new_delete.cpp (renamed from libsanitizer/asan/asan_new_delete.cc)37
-rw-r--r--libsanitizer/asan/asan_poisoning.cpp (renamed from libsanitizer/asan/asan_poisoning.cc)7
-rw-r--r--libsanitizer/asan/asan_poisoning.h15
-rw-r--r--libsanitizer/asan/asan_posix.cpp (renamed from libsanitizer/asan/asan_posix.cc)53
-rw-r--r--libsanitizer/asan/asan_preinit.cpp (renamed from libsanitizer/asan/asan_preinit.cc)7
-rw-r--r--libsanitizer/asan/asan_premap_shadow.cpp (renamed from libsanitizer/asan/asan_premap_shadow.cc)7
-rw-r--r--libsanitizer/asan/asan_premap_shadow.h5
-rw-r--r--libsanitizer/asan/asan_report.cpp (renamed from libsanitizer/asan/asan_report.cc)16
-rw-r--r--libsanitizer/asan/asan_report.h7
-rw-r--r--libsanitizer/asan/asan_rtems.cpp (renamed from libsanitizer/asan/asan_rtems.cc)17
-rw-r--r--libsanitizer/asan/asan_rtl.cpp (renamed from libsanitizer/asan/asan_rtl.cc)45
-rw-r--r--libsanitizer/asan/asan_scariness_score.h5
-rw-r--r--libsanitizer/asan/asan_shadow_setup.cpp (renamed from libsanitizer/asan/asan_shadow_setup.cc)11
-rw-r--r--libsanitizer/asan/asan_stack.cc38
-rw-r--r--libsanitizer/asan/asan_stack.cpp88
-rw-r--r--libsanitizer/asan/asan_stack.h47
-rw-r--r--libsanitizer/asan/asan_stats.cpp (renamed from libsanitizer/asan/asan_stats.cc)7
-rw-r--r--libsanitizer/asan/asan_stats.h5
-rw-r--r--libsanitizer/asan/asan_suppressions.cpp (renamed from libsanitizer/asan/asan_suppressions.cc)7
-rw-r--r--libsanitizer/asan/asan_suppressions.h7
-rw-r--r--libsanitizer/asan/asan_thread.cpp (renamed from libsanitizer/asan/asan_thread.cc)34
-rw-r--r--libsanitizer/asan/asan_thread.h22
-rw-r--r--libsanitizer/asan/asan_win.cpp (renamed from libsanitizer/asan/asan_win.cc)115
-rw-r--r--libsanitizer/asan/asan_win_dll_thunk.cpp (renamed from libsanitizer/asan/asan_win_dll_thunk.cc)10
-rw-r--r--libsanitizer/asan/asan_win_dynamic_runtime_thunk.cpp (renamed from libsanitizer/asan/asan_win_dynamic_runtime_thunk.cc)9
-rw-r--r--libsanitizer/asan/asan_win_weak_interception.cpp (renamed from libsanitizer/asan/asan_win_weak_interception.cc)7
-rw-r--r--libsanitizer/builtins/assembly.h36
-rw-r--r--libsanitizer/configure.tgt3
-rw-r--r--libsanitizer/include/sanitizer/allocator_interface.h5
-rw-r--r--libsanitizer/include/sanitizer/asan_interface.h407
-rw-r--r--libsanitizer/include/sanitizer/common_interface_defs.h507
-rw-r--r--libsanitizer/include/sanitizer/coverage_interface.h5
-rw-r--r--libsanitizer/include/sanitizer/dfsan_interface.h11
-rw-r--r--libsanitizer/include/sanitizer/esan_interface.h48
-rw-r--r--libsanitizer/include/sanitizer/hwasan_interface.h26
-rw-r--r--libsanitizer/include/sanitizer/linux_syscall_hooks.h5
-rw-r--r--libsanitizer/include/sanitizer/lsan_interface.h5
-rw-r--r--libsanitizer/include/sanitizer/msan_interface.h8
-rw-r--r--libsanitizer/include/sanitizer/netbsd_syscall_hooks.h51
-rw-r--r--libsanitizer/include/sanitizer/scudo_interface.h5
-rw-r--r--libsanitizer/include/sanitizer/tsan_interface.h23
-rw-r--r--libsanitizer/include/sanitizer/tsan_interface_atomic.h7
-rw-r--r--libsanitizer/interception/Makefile.am8
-rw-r--r--libsanitizer/interception/Makefile.in16
-rw-r--r--libsanitizer/interception/interception.h15
-rw-r--r--libsanitizer/interception/interception_linux.cc53
-rw-r--r--libsanitizer/interception/interception_linux.cpp83
-rw-r--r--libsanitizer/interception/interception_linux.h29
-rw-r--r--libsanitizer/interception/interception_mac.cpp (renamed from libsanitizer/interception/interception_mac.cc)7
-rw-r--r--libsanitizer/interception/interception_mac.h5
-rw-r--r--libsanitizer/interception/interception_type_test.cpp (renamed from libsanitizer/interception/interception_type_test.cc)7
-rw-r--r--libsanitizer/interception/interception_win.cpp (renamed from libsanitizer/interception/interception_win.cc)13
-rw-r--r--libsanitizer/interception/interception_win.h5
-rw-r--r--libsanitizer/lsan/Makefile.am20
-rw-r--r--libsanitizer/lsan/Makefile.in28
-rw-r--r--libsanitizer/lsan/lsan.cpp (renamed from libsanitizer/lsan/lsan.cc)29
-rw-r--r--libsanitizer/lsan/lsan.h27
-rw-r--r--libsanitizer/lsan/lsan_allocator.cpp (renamed from libsanitizer/lsan/lsan_allocator.cc)21
-rw-r--r--libsanitizer/lsan/lsan_allocator.h34
-rw-r--r--libsanitizer/lsan/lsan_common.cpp (renamed from libsanitizer/lsan/lsan_common.cc)7
-rw-r--r--libsanitizer/lsan/lsan_common.h11
-rw-r--r--libsanitizer/lsan/lsan_common_linux.cpp (renamed from libsanitizer/lsan/lsan_common_linux.cc)14
-rw-r--r--libsanitizer/lsan/lsan_common_mac.cpp (renamed from libsanitizer/lsan/lsan_common_mac.cc)11
-rw-r--r--libsanitizer/lsan/lsan_flags.inc5
-rw-r--r--libsanitizer/lsan/lsan_interceptors.cpp (renamed from libsanitizer/lsan/lsan_interceptors.cc)15
-rw-r--r--libsanitizer/lsan/lsan_linux.cpp (renamed from libsanitizer/lsan/lsan_linux.cc)13
-rw-r--r--libsanitizer/lsan/lsan_mac.cpp (renamed from libsanitizer/lsan/lsan_mac.cc)7
-rw-r--r--libsanitizer/lsan/lsan_malloc_mac.cpp (renamed from libsanitizer/lsan/lsan_malloc_mac.cc)9
-rw-r--r--libsanitizer/lsan/lsan_preinit.cpp (renamed from libsanitizer/lsan/lsan_preinit.cc)7
-rw-r--r--libsanitizer/lsan/lsan_thread.cpp (renamed from libsanitizer/lsan/lsan_thread.cc)11
-rw-r--r--libsanitizer/lsan/lsan_thread.h8
-rwxr-xr-xlibsanitizer/merge.sh3
-rw-r--r--libsanitizer/sanitizer_common/Makefile.am119
-rw-r--r--libsanitizer/sanitizer_common/Makefile.in181
-rw-r--r--libsanitizer/sanitizer_common/sancov_begin.S5
-rw-r--r--libsanitizer/sanitizer_common/sancov_end.S5
-rw-r--r--libsanitizer/sanitizer_common/sancov_flags.cpp (renamed from libsanitizer/sanitizer_common/sancov_flags.cc)9
-rw-r--r--libsanitizer/sanitizer_common/sancov_flags.h5
-rw-r--r--libsanitizer/sanitizer_common/sancov_flags.inc5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_addrhashmap.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_allocator.cc)19
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator.h11
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_bytemap.h17
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_checks.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_allocator_checks.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_checks.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_combined.h19
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_interface.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_internal.h34
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_local_cache.h12
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_primary32.h21
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h35
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_report.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_allocator_report.cc)19
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_report.h7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_secondary.h52
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h8
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_allocator_stats.h7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_asm.h16
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_atomic.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_atomic_clang.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h6
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_atomic_clang_x86.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_bitvector.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_bvgraph.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_common.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common.h42
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc2616
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_interceptors_format.inc5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_interceptors_ioctl.inc5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S43
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S49
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S63
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S41
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_interface.inc5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_interface_posix.inc5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_libcdep.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_common_libcdep.cc)11
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_nolibc.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_common_nolibc.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc17
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cc)12
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_coverage_interface.inc5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_coverage_win_dll_thunk.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_coverage_win_dll_thunk.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cc)13
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cc)52
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_coverage_win_weak_interception.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_coverage_win_weak_interception.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_dbghelp.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_deadlock_detector.h12
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_deadlock_detector_interface.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_errno.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_errno.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_errno.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_errno_codes.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_file.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_file.cc)9
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_file.h8
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_flag_parser.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_flag_parser.cc)36
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_flag_parser.h24
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_flags.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_flags.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_flags.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_flags.inc16
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_freebsd.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_fuchsia.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_fuchsia.cc)38
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_fuchsia.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_getauxval.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_hash.h43
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc88
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_interface_internal.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_internal_defs.h8
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_lfstack.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_libc.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_libc.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_libc.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_libignore.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_libignore.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_libignore.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_linux.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_linux.cc)155
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_linux.h34
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc)47
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_linux_mips64.S23
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_linux_s390.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_linux_s390.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_linux_x86_64.S25
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_list.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_local_address_space_view.h76
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_mac.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_mac.cc)146
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_mac.h7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_malloc_mac.inc101
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_mutex.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_netbsd.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_netbsd.cc)36
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_openbsd.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_openbsd.cc)13
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_persistent_allocator.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_persistent_allocator.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_persistent_allocator.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_placement_new.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform.h26
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h69
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.cpp525
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.h656
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc)9
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cc)422
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h229
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc)90
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h142
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_posix.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_posix.cc)133
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_posix.h28
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc)89
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_printf.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_printf.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_procmaps.h6
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cc)8
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_procmaps_common.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_procmaps_common.cc)13
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cc)8
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cc)11
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cc)22
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_quarantine.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_report_decorator.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_ring_buffer.h7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_rtems.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_rtems.cc)15
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_rtems.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_solaris.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_solaris.cc)16
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stackdepot.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_stackdepot.cc)30
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stackdepot.h7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stackdepotbase.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_stacktrace.cc)15
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stacktrace.h61
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cc)15
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cc)11
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc)27
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stoptheworld.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp356
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_suppressions.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_suppressions.cc)38
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_suppressions.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_symbolizer.cc)17
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer.h33
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.h8
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h32
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cc)88
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cc)12
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_markup.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_symbolizer_markup.cc)15
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cc)13
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_rtems.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cc)10
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_syscall_linux_aarch64.inc5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_syscall_linux_arm.inc5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_syscall_linux_x86_64.inc5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_syscalls_netbsd.inc43
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_termination.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_termination.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_thread_registry.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_thread_registry.cc)30
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_thread_registry.h18
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_tls_get_addr.h7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_type_traits.cpp20
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_type_traits.h62
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cc)19
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_unwind_win.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_unwind_win.cc)14
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_vector.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_win.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_win.cc)86
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_win.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_win_defs.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.h5
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cc)13
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cpp (renamed from libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cc)7
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_win_weak_interception.h5
-rw-r--r--libsanitizer/tsan/Makefile.am67
-rw-r--r--libsanitizer/tsan/Makefile.in83
-rw-r--r--libsanitizer/tsan/tsan_clock.cpp (renamed from libsanitizer/tsan/tsan_clock.cc)9
-rw-r--r--libsanitizer/tsan/tsan_clock.h5
-rw-r--r--libsanitizer/tsan/tsan_debugging.cpp (renamed from libsanitizer/tsan/tsan_debugging.cc)57
-rw-r--r--libsanitizer/tsan/tsan_defs.h5
-rw-r--r--libsanitizer/tsan/tsan_dense_alloc.h5
-rw-r--r--libsanitizer/tsan/tsan_dispatch_defs.h66
-rw-r--r--libsanitizer/tsan/tsan_external.cpp (renamed from libsanitizer/tsan/tsan_external.cc)7
-rw-r--r--libsanitizer/tsan/tsan_fd.cpp (renamed from libsanitizer/tsan/tsan_fd.cc)7
-rw-r--r--libsanitizer/tsan/tsan_fd.h5
-rw-r--r--libsanitizer/tsan/tsan_flags.cpp (renamed from libsanitizer/tsan/tsan_flags.cc)16
-rw-r--r--libsanitizer/tsan/tsan_flags.h8
-rw-r--r--libsanitizer/tsan/tsan_flags.inc7
-rw-r--r--libsanitizer/tsan/tsan_ignoreset.cpp (renamed from libsanitizer/tsan/tsan_ignoreset.cc)7
-rw-r--r--libsanitizer/tsan/tsan_ignoreset.h5
-rw-r--r--libsanitizer/tsan/tsan_interceptors.cpp (renamed from libsanitizer/tsan/tsan_interceptors.cc)203
-rw-r--r--libsanitizer/tsan/tsan_interceptors.h12
-rw-r--r--libsanitizer/tsan/tsan_interceptors_mac.cpp (renamed from libsanitizer/tsan/tsan_interceptors_mac.cc)104
-rw-r--r--libsanitizer/tsan/tsan_interface.cpp (renamed from libsanitizer/tsan/tsan_interface.cc)33
-rw-r--r--libsanitizer/tsan/tsan_interface.h7
-rw-r--r--libsanitizer/tsan/tsan_interface_ann.cpp (renamed from libsanitizer/tsan/tsan_interface_ann.cc)7
-rw-r--r--libsanitizer/tsan/tsan_interface_ann.h5
-rw-r--r--libsanitizer/tsan/tsan_interface_atomic.cpp (renamed from libsanitizer/tsan/tsan_interface_atomic.cc)9
-rw-r--r--libsanitizer/tsan/tsan_interface_inl.h5
-rw-r--r--libsanitizer/tsan/tsan_interface_java.cpp (renamed from libsanitizer/tsan/tsan_interface_java.cc)7
-rw-r--r--libsanitizer/tsan/tsan_interface_java.h7
-rw-r--r--libsanitizer/tsan/tsan_libdispatch.cpp (renamed from libsanitizer/tsan/tsan_libdispatch_mac.cc)198
-rw-r--r--libsanitizer/tsan/tsan_malloc_mac.cpp (renamed from libsanitizer/tsan/tsan_malloc_mac.cc)21
-rw-r--r--libsanitizer/tsan/tsan_md5.cpp (renamed from libsanitizer/tsan/tsan_md5.cc)15
-rw-r--r--libsanitizer/tsan/tsan_mman.cpp (renamed from libsanitizer/tsan/tsan_mman.cc)17
-rw-r--r--libsanitizer/tsan/tsan_mman.h6
-rw-r--r--libsanitizer/tsan/tsan_mutex.cpp (renamed from libsanitizer/tsan/tsan_mutex.cc)7
-rw-r--r--libsanitizer/tsan/tsan_mutex.h5
-rw-r--r--libsanitizer/tsan/tsan_mutexset.cpp (renamed from libsanitizer/tsan/tsan_mutexset.cc)7
-rw-r--r--libsanitizer/tsan/tsan_mutexset.h5
-rw-r--r--libsanitizer/tsan/tsan_new_delete.cpp (renamed from libsanitizer/tsan/tsan_new_delete.cc)13
-rw-r--r--libsanitizer/tsan/tsan_platform.h6
-rw-r--r--libsanitizer/tsan/tsan_platform_linux.cpp (renamed from libsanitizer/tsan/tsan_platform_linux.cc)117
-rw-r--r--libsanitizer/tsan/tsan_platform_mac.cpp (renamed from libsanitizer/tsan/tsan_platform_mac.cc)67
-rw-r--r--libsanitizer/tsan/tsan_platform_posix.cpp (renamed from libsanitizer/tsan/tsan_platform_posix.cc)16
-rw-r--r--libsanitizer/tsan/tsan_platform_windows.cpp (renamed from libsanitizer/tsan/tsan_platform_windows.cc)7
-rw-r--r--libsanitizer/tsan/tsan_preinit.cpp (renamed from libsanitizer/tsan/tsan_preinit.cc)7
-rw-r--r--libsanitizer/tsan/tsan_report.cpp (renamed from libsanitizer/tsan/tsan_report.cc)78
-rw-r--r--libsanitizer/tsan/tsan_report.h8
-rw-r--r--libsanitizer/tsan/tsan_rtl.cpp (renamed from libsanitizer/tsan/tsan_rtl.cc)47
-rw-r--r--libsanitizer/tsan/tsan_rtl.h52
-rw-r--r--libsanitizer/tsan/tsan_rtl_aarch64.S196
-rw-r--r--libsanitizer/tsan/tsan_rtl_amd64.S48
-rw-r--r--libsanitizer/tsan/tsan_rtl_mutex.cpp (renamed from libsanitizer/tsan/tsan_rtl_mutex.cc)7
-rw-r--r--libsanitizer/tsan/tsan_rtl_proc.cpp (renamed from libsanitizer/tsan/tsan_rtl_proc.cc)7
-rw-r--r--libsanitizer/tsan/tsan_rtl_report.cpp (renamed from libsanitizer/tsan/tsan_rtl_report.cc)15
-rw-r--r--libsanitizer/tsan/tsan_rtl_thread.cpp (renamed from libsanitizer/tsan/tsan_rtl_thread.cc)57
-rw-r--r--libsanitizer/tsan/tsan_stack_trace.cpp (renamed from libsanitizer/tsan/tsan_stack_trace.cc)20
-rw-r--r--libsanitizer/tsan/tsan_stack_trace.h5
-rw-r--r--libsanitizer/tsan/tsan_stat.cpp (renamed from libsanitizer/tsan/tsan_stat.cc)7
-rw-r--r--libsanitizer/tsan/tsan_stat.h5
-rw-r--r--libsanitizer/tsan/tsan_suppressions.cpp (renamed from libsanitizer/tsan/tsan_suppressions.cc)63
-rw-r--r--libsanitizer/tsan/tsan_suppressions.h5
-rw-r--r--libsanitizer/tsan/tsan_symbolize.cpp (renamed from libsanitizer/tsan/tsan_symbolize.cc)7
-rw-r--r--libsanitizer/tsan/tsan_symbolize.h5
-rw-r--r--libsanitizer/tsan/tsan_sync.cpp (renamed from libsanitizer/tsan/tsan_sync.cc)7
-rw-r--r--libsanitizer/tsan/tsan_sync.h5
-rw-r--r--libsanitizer/tsan/tsan_trace.h5
-rw-r--r--libsanitizer/tsan/tsan_update_shadow_word_inl.h29
-rw-r--r--libsanitizer/ubsan/Makefile.am20
-rw-r--r--libsanitizer/ubsan/Makefile.in28
-rw-r--r--libsanitizer/ubsan/ubsan_checks.inc12
-rw-r--r--libsanitizer/ubsan/ubsan_diag.cpp (renamed from libsanitizer/ubsan/ubsan_diag.cc)25
-rw-r--r--libsanitizer/ubsan/ubsan_diag.h8
-rw-r--r--libsanitizer/ubsan/ubsan_diag_standalone.cc36
-rw-r--r--libsanitizer/ubsan/ubsan_diag_standalone.cpp40
-rw-r--r--libsanitizer/ubsan/ubsan_flags.cpp (renamed from libsanitizer/ubsan/ubsan_flags.cc)9
-rw-r--r--libsanitizer/ubsan/ubsan_flags.h5
-rw-r--r--libsanitizer/ubsan/ubsan_flags.inc9
-rw-r--r--libsanitizer/ubsan/ubsan_handlers.cpp (renamed from libsanitizer/ubsan/ubsan_handlers.cc)109
-rw-r--r--libsanitizer/ubsan/ubsan_handlers.h27
-rw-r--r--libsanitizer/ubsan/ubsan_handlers_cxx.cpp (renamed from libsanitizer/ubsan/ubsan_handlers_cxx.cc)51
-rw-r--r--libsanitizer/ubsan/ubsan_handlers_cxx.h21
-rw-r--r--libsanitizer/ubsan/ubsan_init.cpp (renamed from libsanitizer/ubsan/ubsan_init.cc)7
-rw-r--r--libsanitizer/ubsan/ubsan_init.h5
-rw-r--r--libsanitizer/ubsan/ubsan_init_standalone.cpp (renamed from libsanitizer/ubsan/ubsan_init_standalone.cc)7
-rw-r--r--libsanitizer/ubsan/ubsan_init_standalone_preinit.cpp (renamed from libsanitizer/ubsan/ubsan_init_standalone_preinit.cc)7
-rw-r--r--libsanitizer/ubsan/ubsan_interface.inc11
-rw-r--r--libsanitizer/ubsan/ubsan_monitor.cpp (renamed from libsanitizer/ubsan/ubsan_monitor.cc)7
-rw-r--r--libsanitizer/ubsan/ubsan_monitor.h5
-rw-r--r--libsanitizer/ubsan/ubsan_platform.h5
-rw-r--r--libsanitizer/ubsan/ubsan_signals_standalone.cpp (renamed from libsanitizer/ubsan/ubsan_signals_standalone.cc)16
-rw-r--r--libsanitizer/ubsan/ubsan_signals_standalone.h7
-rw-r--r--libsanitizer/ubsan/ubsan_type_hash.cpp (renamed from libsanitizer/ubsan/ubsan_type_hash.cc)9
-rw-r--r--libsanitizer/ubsan/ubsan_type_hash.h9
-rw-r--r--libsanitizer/ubsan/ubsan_type_hash_itanium.cpp (renamed from libsanitizer/ubsan/ubsan_type_hash_itanium.cc)20
-rw-r--r--libsanitizer/ubsan/ubsan_type_hash_win.cpp (renamed from libsanitizer/ubsan/ubsan_type_hash_win.cc)11
-rw-r--r--libsanitizer/ubsan/ubsan_value.cpp (renamed from libsanitizer/ubsan/ubsan_value.cc)7
-rw-r--r--libsanitizer/ubsan/ubsan_value.h5
-rw-r--r--libsanitizer/ubsan/ubsan_win_dll_thunk.cpp (renamed from libsanitizer/ubsan/ubsan_win_dll_thunk.cc)7
-rw-r--r--libsanitizer/ubsan/ubsan_win_dynamic_runtime_thunk.cpp (renamed from libsanitizer/ubsan/ubsan_win_dynamic_runtime_thunk.cc)7
-rw-r--r--libsanitizer/ubsan/ubsan_win_weak_interception.cpp (renamed from libsanitizer/ubsan/ubsan_win_weak_interception.cc)7
-rw-r--r--libstdc++-v3/ChangeLog320
-rw-r--r--libstdc++-v3/config/abi/post/alpha-linux-gnu/baseline_symbols.txt441
-rw-r--r--libstdc++-v3/doc/xml/manual/documentation_hacking.xml12
-rw-r--r--libstdc++-v3/include/Makefile.am1
-rw-r--r--libstdc++-v3/include/Makefile.in1
-rw-r--r--libstdc++-v3/include/bits/algorithmfwd.h114
-rw-r--r--libstdc++-v3/include/bits/cpp_type_traits.h1
-rw-r--r--libstdc++-v3/include/bits/move.h3
-rw-r--r--libstdc++-v3/include/bits/predefined_ops.h45
-rw-r--r--libstdc++-v3/include/bits/std_function.h10
-rw-r--r--libstdc++-v3/include/bits/stl_algo.h150
-rw-r--r--libstdc++-v3/include/bits/stl_algobase.h137
-rw-r--r--libstdc++-v3/include/bits/stl_heap.h22
-rw-r--r--libstdc++-v3/include/bits/stl_iterator.h4
-rw-r--r--libstdc++-v3/include/bits/unique_ptr.h30
-rw-r--r--libstdc++-v3/include/experimental/array2
-rw-r--r--libstdc++-v3/include/ext/random15
-rw-r--r--libstdc++-v3/include/ext/random.tcc8
-rw-r--r--libstdc++-v3/include/precompiled/stdc++.h3
-rw-r--r--libstdc++-v3/include/std/array47
-rw-r--r--libstdc++-v3/include/std/bit37
-rw-r--r--libstdc++-v3/include/std/functional4
-rw-r--r--libstdc++-v3/include/std/memory5
-rw-r--r--libstdc++-v3/include/std/numbers208
-rw-r--r--libstdc++-v3/include/std/tuple26
-rw-r--r--libstdc++-v3/include/std/type_traits55
-rw-r--r--libstdc++-v3/include/std/utility6
-rw-r--r--libstdc++-v3/include/std/version7
-rw-r--r--libstdc++-v3/libsupc++/cxxabi.h9
-rw-r--r--libstdc++-v3/libsupc++/guard_error.cc4
-rw-r--r--libstdc++-v3/src/c++17/string-inst.cc6
-rw-r--r--libstdc++-v3/testsuite/18_support/51333.cc22
-rw-r--r--libstdc++-v3/testsuite/20_util/exchange/constexpr.cc34
-rw-r--r--libstdc++-v3/testsuite/20_util/function/91456.cc37
-rw-r--r--libstdc++-v3/testsuite/20_util/function_objects/bind_front/1.cc2
-rw-r--r--libstdc++-v3/testsuite/20_util/function_objects/bind_front/2.cc91
-rw-r--r--libstdc++-v3/testsuite/20_util/is_invocable/91456.cc34
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/apply/2.cc62
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/make_from_tuple/2.cc63
-rw-r--r--libstdc++-v3/testsuite/20_util/unique_ptr/assign/91308.cc46
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/comparison_operators/constexpr.cc33
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/creation/1.cc57
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/creation/2.cc27
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/creation/3_neg.cc56
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc6
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/adjacent_find/constexpr.cc43
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/all_of/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/any_of/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/binary_search/constexpr.cc43
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/constexpr_macro.cc27
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/copy/58982.cc3
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/copy/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/copy/move_iterators/69478.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/copy_backward/constexpr.cc42
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/copy_backward/move_iterators/69478.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/copy_if/constexpr.cc42
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/copy_n/58982.cc3
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/copy_n/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/count/constexpr.cc40
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/count_if/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/equal/constexpr.cc45
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/equal_range/constexpr.cc40
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/fill/constexpr.cc39
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/fill_n/constexpr.cc40
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/find/constexpr.cc40
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/find_end/constexpr.cc47
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/find_first_of/constexpr.cc46
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/find_if/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/find_if_not/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/for_each/constexpr.cc42
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/generate/constexpr.cc40
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/generate_n/constexpr.cc40
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/headers/algorithm/synopsis.cc107
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/is_heap/constexpr.cc47
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/is_heap_until/constexpr.cc48
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/is_partitioned/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/is_permutation/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/is_sorted/constexpr.cc43
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/is_sorted_until/constexpr.cc43
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/iter_swap/constexpr.cc42
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/lexicographical_compare/constexpr.cc46
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/lower_bound/constexpr.cc43
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/make_heap/constexpr.cc47
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/merge/constexpr.cc48
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/mismatch/constexpr.cc44
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/move/69478.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/move_backward/69478.cc1
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/next_permutation/constexpr.cc42
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/none_of/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/nth_element/constexpr.cc47
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/partial_sort/constexpr.cc46
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/partial_sort_copy/constexpr.cc47
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/partition/constexpr.cc44
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/partition_copy/constexpr.cc44
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/partition_point/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/pop_heap/constexpr.cc53
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/prev_permutation/constexpr.cc42
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/push_heap/constexpr.cc52
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/remove/constexpr.cc40
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/remove_copy/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/remove_copy_if/constexpr.cc42
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/remove_if/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/replace_copy/constexpr.cc43
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/replace_copy_if/constexpr.cc43
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/replace_if/constexpr.cc40
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/reverse/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/reverse_copy/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/rotate/constexpr.cc41
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/rotate_copy/constexpr.cc42
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/search/constexpr.cc43
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/search_n/constexpr.cc43
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/set_difference/constexpr.cc47
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/set_intersection/constexpr.cc48
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/set_symmetric_difference/constexpr.cc47
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/set_union/constexpr.cc47
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/sort/constexpr.cc46
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/sort_heap/constexpr.cc56
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/swap/constexpr.cc47
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/swap_ranges/constexpr.cc44
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/transform/constexpr.cc47
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/unique/constexpr.cc43
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/unique_copy/constexpr.cc44
-rw-r--r--libstdc++-v3/testsuite/25_algorithms/upper_bound/constexpr.cc43
-rw-r--r--libstdc++-v3/testsuite/26_numerics/endian/1.cc (renamed from libstdc++-v3/testsuite/20_util/endian/1.cc)2
-rw-r--r--libstdc++-v3/testsuite/26_numerics/endian/2.cc27
-rw-r--r--libstdc++-v3/testsuite/26_numerics/endian/3.cc27
-rw-r--r--libstdc++-v3/testsuite/26_numerics/endian/4.cc25
-rw-r--r--libstdc++-v3/testsuite/26_numerics/numbers/1.cc99
-rw-r--r--libstdc++-v3/testsuite/26_numerics/numbers/2.cc27
-rw-r--r--libstdc++-v3/testsuite/26_numerics/numbers/3.cc25
-rw-r--r--libstdc++-v3/testsuite/26_numerics/numbers/float128.cc41
-rw-r--r--libstdc++-v3/testsuite/26_numerics/numbers/nonfloat_neg.cc36
-rw-r--r--libstdc++-v3/testsuite/ext/bitmap_allocator/check_delete.cc2
-rw-r--r--libstdc++-v3/testsuite/ext/bitmap_allocator/check_new.cc2
-rw-r--r--libstdc++-v3/testsuite/ext/new_allocator/check_delete.cc2
-rw-r--r--libstdc++-v3/testsuite/ext/new_allocator/check_new.cc2
-rw-r--r--libstdc++-v3/testsuite/ext/random/beta_distribution/operators/serialize.cc2
-rw-r--r--libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/serialize.cc1
-rw-r--r--libstdc++-v3/testsuite/ext/random/normal_mv_distribution/operators/serialize.cc2
-rw-r--r--libstdc++-v3/testsuite/ext/random/triangular_distribution/operators/serialize.cc2
-rw-r--r--libstdc++-v3/testsuite/ext/random/von_mises_distribution/operators/serialize.cc2
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_iterators.h4
-rw-r--r--maintainer-scripts/ChangeLog5
-rwxr-xr-xmaintainer-scripts/update_web_docs_svn2
1904 files changed, 67404 insertions, 18296 deletions
diff --git a/ChangeLog b/ChangeLog
index 9693c62..801ae7d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2019-08-19 Tom Tromey <tom@tromey.com>
+
+ * configure: Rebuild.
+ * configure.ac: Add --with-static-standard-libraries.
+
+2019-08-16 Alexandre Oliva <oliva@gnu.org>
+
+ * MAINTAINERS: aoliva from @redhat.com to @gcc.gnu.org.
+
+2019-08-13 Mark Eggleston <mark.eggleston@codethink.co.uk>
+
+ * MAINTAINERS (Write After Approval): Add myself.
+
2019-07-08 Kito Cheng <kito.cheng@sifive.com>
* MAINTAINERS (Write After Approval): Remove myself, already listed in
diff --git a/MAINTAINERS b/MAINTAINERS
index 7c1eebc..5d84029 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -64,7 +64,7 @@ c-sky port Yunhai Shang <yunhai_shang@c-sky.com>
epiphany port Joern Rennecke <gnu@amylaar.uk>
fr30 port Nick Clifton <nickc@redhat.com>
frv port Nick Clifton <nickc@redhat.com>
-frv port Alexandre Oliva <aoliva@redhat.com>
+frv port Alexandre Oliva <aoliva@gcc.gnu.org>
ft32 port James Bowman <james.bowman@ftdichip.com>
h8 port Jeff Law <law@redhat.com>
hppa port Jeff Law <law@redhat.com>
@@ -83,7 +83,7 @@ microblaze Michael Eager <eager@eagercon.com>
mips port Matthew Fortune <mfortune@gmail.com>
mmix port Hans-Peter Nilsson <hp@bitrange.com>
mn10300 port Jeff Law <law@redhat.com>
-mn10300 port Alexandre Oliva <aoliva@redhat.com>
+mn10300 port Alexandre Oliva <aoliva@gcc.gnu.org>
moxie port Anthony Green <green@moxielogic.com>
msp430 port Nick Clifton <nickc@redhat.com>
nds32 port Chung-Ju Wu <jasonwucj@gmail.com>
@@ -105,7 +105,7 @@ rx port Nick Clifton <nickc@redhat.com>
s390 port Hartmut Penner <hepenner@us.ibm.com>
s390 port Ulrich Weigand <uweigand@de.ibm.com>
s390 port Andreas Krebbel <krebbel@linux.ibm.com>
-sh port Alexandre Oliva <aoliva@redhat.com>
+sh port Alexandre Oliva <aoliva@gcc.gnu.org>
sh port Oleg Endo <olegendo@gcc.gnu.org>
sparc port David S. Miller <davem@redhat.com>
sparc port Eric Botcazou <ebotcazou@libertysurf.fr>
@@ -213,7 +213,7 @@ diagnostic messages Dodji Seketeli <dodji@redhat.com>
diagnostic messages David Malcolm <dmalcolm@redhat.com>
build machinery (*.in) Paolo Bonzini <bonzini@gnu.org>
build machinery (*.in) Nathanael Nerode <neroden@gcc.gnu.org>
-build machinery (*.in) Alexandre Oliva <aoliva@redhat.com>
+build machinery (*.in) Alexandre Oliva <aoliva@gcc.gnu.org>
build machinery (*.in) Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
docs co-maintainer Gerald Pfeifer <gerald@pfeifer.com>
docs co-maintainer Joseph Myers <joseph@codesourcery.com>
@@ -371,6 +371,7 @@ Benoit Dupont de Dinechin <benoit.dupont-de-dinechin@st.com>
Jason Eckhardt <jle@rice.edu>
Bernd Edlinger <bernd.edlinger@hotmail.de>
Phil Edwards <pme@gcc.gnu.org>
+Mark Eggleston <mark.eggleston@codethink.co.uk>
Steve Ellcey <sellcey@caviumnetworks.com>
Mohan Embar <gnustuff@thisiscool.com>
Revital Eres <eres@il.ibm.com>
diff --git a/configure b/configure
index 63b1e33..c3ec920 100755
--- a/configure
+++ b/configure
@@ -806,6 +806,7 @@ with_gmp
with_gmp_include
with_gmp_lib
with_stage1_libs
+with_static_standard_libraries
with_stage1_ldflags
with_boot_libs
with_boot_ldflags
@@ -1579,6 +1580,9 @@ Optional Packages:
--with-gmp-include=PATH specify directory for installed GMP include files
--with-gmp-lib=PATH specify directory for the installed GMP library
--with-stage1-libs=LIBS libraries for stage1
+ --with-static-standard-libraries
+ use -static-libstdc++ and -static-libgcc
+ (default=auto)
--with-stage1-ldflags=FLAGS
linker flags for stage1
--with-boot-libs=LIBS libraries for stage2 and later
@@ -5877,6 +5881,23 @@ fi
+# Whether or not to use -static-libstdc++ and -static-libgcc. The
+# default is yes if gcc is being built; no otherwise. The reason for
+# this default is that gdb is sometimes linked against GNU Source
+# Highlight, which is a shared library that uses C++ exceptions. In
+# this case, -static-libstdc++ will cause crashes.
+
+# Check whether --with-static-standard-libraries was given.
+if test "${with_static_standard_libraries+set}" = set; then :
+ withval=$with_static_standard_libraries;
+else
+ with_static_standard_libraries=auto
+fi
+
+if test "$with_static_standard_libraries" = auto; then
+ with_static_standard_libraries=$have_compiler
+fi
+
# Linker flags to use for stage1 or when not bootstrapping.
# Check whether --with-stage1-ldflags was given.
@@ -5891,7 +5912,8 @@ else
# In stage 1, default to linking libstdc++ and libgcc statically with GCC
# if supported. But if the user explicitly specified the libraries to use,
# trust that they are doing what they want.
- if test "$stage1_libs" = "" -a "$have_static_libs" = yes; then
+ if test "$with_static_standard_libraries" = yes -a "$stage1_libs" = "" \
+ -a "$have_static_libs" = yes; then
stage1_ldflags="-static-libstdc++ -static-libgcc"
fi
fi
diff --git a/configure.ac b/configure.ac
index dcc89fb..1fe97c0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1640,6 +1640,19 @@ AC_ARG_WITH(stage1-libs,
[stage1_libs=])
AC_SUBST(stage1_libs)
+# Whether or not to use -static-libstdc++ and -static-libgcc. The
+# default is yes if gcc is being built; no otherwise. The reason for
+# this default is that gdb is sometimes linked against GNU Source
+# Highlight, which is a shared library that uses C++ exceptions. In
+# this case, -static-libstdc++ will cause crashes.
+AC_ARG_WITH(static-standard-libraries,
+[AS_HELP_STRING([--with-static-standard-libraries],
+ [use -static-libstdc++ and -static-libgcc (default=auto)])],
+[], [with_static_standard_libraries=auto])
+if test "$with_static_standard_libraries" = auto; then
+ with_static_standard_libraries=$have_compiler
+fi
+
# Linker flags to use for stage1 or when not bootstrapping.
AC_ARG_WITH(stage1-ldflags,
[AS_HELP_STRING([--with-stage1-ldflags=FLAGS], [linker flags for stage1])],
@@ -1652,7 +1665,8 @@ AC_ARG_WITH(stage1-ldflags,
# In stage 1, default to linking libstdc++ and libgcc statically with GCC
# if supported. But if the user explicitly specified the libraries to use,
# trust that they are doing what they want.
- if test "$stage1_libs" = "" -a "$have_static_libs" = yes; then
+ if test "$with_static_standard_libraries" = yes -a "$stage1_libs" = "" \
+ -a "$have_static_libs" = yes; then
stage1_ldflags="-static-libstdc++ -static-libgcc"
fi])
AC_SUBST(stage1_ldflags)
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index aff6b13..fd7df43 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,7 @@
+2019-08-13 Uros Bizjak <ubizjak@gmail.com>
+
+ * test_summary: Do not escape "=".
+
2019-07-02 Janne Blomqvist <jb@gcc.gnu.org>
PR other/91048
diff --git a/contrib/test_summary b/contrib/test_summary
index 3560a64..5760b05 100755
--- a/contrib/test_summary
+++ b/contrib/test_summary
@@ -127,7 +127,7 @@ NR == 1 {
if (lang == "") lang = " "$2" "; else lang = " ";
}
$2 == "version" { save = $0; $1 = ""; $2 = ""; version = $0; gsub(/^ */, "", version); gsub(/\r$/, "", version); $0 = save; }
-/\===.*Summary/ { print ""; print; blanks=1; }
+/===.*Summary/ { print ""; print; blanks=1; }
/tests ===/ || /^(Target|Host|Native)/ || $2 == "version" { print; blanks=1; }
/^(XPASS|FAIL|UNRESOLVED|WARNING|ERROR|# of )/ { sub ("\r", ""); print; }
/^using:/ { print ""; print; print ""; }
diff --git a/fixincludes/ChangeLog b/fixincludes/ChangeLog
index be02029..03c2313 100644
--- a/fixincludes/ChangeLog
+++ b/fixincludes/ChangeLog
@@ -1,3 +1,12 @@
+2019-08-18 C.G. Dogan <gcc+cgdogan.00@gmail.com>
+ Iain Sandoe <iain@sandoe.co.uk>
+
+ PR target/83531
+ * inclhack.def (darwin_api_availability): New, strip leading
+ underscores from API_XXXX defines.
+ * fixincl.x: Regenerate.
+ * tests/base/os/availability.h: New file.
+
2019-06-21 Iain Sandoe <iain@sandoe.co.uk>
* inclhack.def: Replace the complex test using __STRICT_ANSI__ and
diff --git a/fixincludes/fixincl.x b/fixincludes/fixincl.x
index b9e0298..e5ae601 100644
--- a/fixincludes/fixincl.x
+++ b/fixincludes/fixincl.x
@@ -2,11 +2,11 @@
*
* DO NOT EDIT THIS FILE (fixincl.x)
*
- * It has been AutoGen-ed June 21, 2019 at 08:06:27 PM by AutoGen 5.17.4
+ * It has been AutoGen-ed June 21, 2019 at 09:13:33 PM by AutoGen 5.17.4
* From the definitions inclhack.def
* and the template file fixincl
*/
-/* DO NOT SVN-MERGE THIS FILE, EITHER Fri Jun 21 20:06:27 BST 2019
+/* DO NOT SVN-MERGE THIS FILE, EITHER Fri Jun 21 21:13:33 BST 2019
*
* You must regenerate it. Use the ./genfixes script.
*
@@ -15,7 +15,7 @@
* certain ANSI-incompatible system header files which are fixed to work
* correctly with ANSI C and placed in a directory that GNU C will search.
*
- * This file contains 255 fixup descriptions.
+ * This file contains 256 fixup descriptions.
*
* See README for more information.
*
@@ -269,6 +269,56 @@ static const char* apzAab_Darwin7_9_Long_Double_FuncsPatch[] = {
/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
+ * Description of Darwin_Api_Availability fix
+ */
+tSCC zDarwin_Api_AvailabilityName[] =
+ "darwin_api_availability";
+
+/*
+ * File name selection pattern
+ */
+tSCC zDarwin_Api_AvailabilityList[] =
+ "os/availability.h\0";
+/*
+ * Machine/OS name selection pattern
+ */
+tSCC* apzDarwin_Api_AvailabilityMachs[] = {
+ "*-*-darwin*",
+ (const char*)NULL };
+
+/*
+ * content selection pattern - do fix if pattern found
+ */
+tSCC zDarwin_Api_AvailabilitySelect0[] =
+ " *#define __API_AVAILABLE.*\n\
+ *#define __API_DEPRECATED.*\n\
+ *#define __API_DEPRECATED_WITH_REPLACEMENT.*\n\
+ *#define __API_UNAVAILABLE.*\n";
+
+/*
+ * content bypass pattern - skip fix if pattern found
+ */
+tSCC zDarwin_Api_AvailabilityBypass0[] =
+ "__IPHONE_OS_VERSION_MIN_REQUIRED";
+
+#define DARWIN_API_AVAILABILITY_TEST_CT 2
+static tTestDesc aDarwin_Api_AvailabilityTests[] = {
+ { TT_NEGREP, zDarwin_Api_AvailabilityBypass0, (regex_t*)NULL },
+ { TT_EGREP, zDarwin_Api_AvailabilitySelect0, (regex_t*)NULL }, };
+
+/*
+ * Fix Command Arguments for Darwin_Api_Availability
+ */
+static const char* apzDarwin_Api_AvailabilityPatch[] = {
+ "format",
+ " #define API_AVAILABLE(...)\n\
+ #define API_DEPRECATED(...)\n\
+ #define API_DEPRECATED_WITH_REPLACEMENT(...)\n\
+ #define API_UNAVAILABLE(...)\n",
+ (char*)NULL };
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
* Description of Aab_Fd_Zero_Asm_Posix_Types_H fix
*/
tSCC zAab_Fd_Zero_Asm_Posix_Types_HName[] =
@@ -10346,9 +10396,9 @@ static const char* apzX11_SprintfPatch[] = {
*
* List of all fixes
*/
-#define REGEX_COUNT 293
+#define REGEX_COUNT 295
#define MACH_LIST_SIZE_LIMIT 187
-#define FIX_COUNT 255
+#define FIX_COUNT 256
/*
* Enumerate the fixes
@@ -10357,6 +10407,7 @@ typedef enum {
AAB_AIX_STDIO_FIXIDX,
AAB_AIX_FCNTL_FIXIDX,
AAB_DARWIN7_9_LONG_DOUBLE_FUNCS_FIXIDX,
+ DARWIN_API_AVAILABILITY_FIXIDX,
AAB_FD_ZERO_ASM_POSIX_TYPES_H_FIXIDX,
AAB_FD_ZERO_GNU_TYPES_H_FIXIDX,
AAB_FD_ZERO_SELECTBITS_H_FIXIDX,
@@ -10627,6 +10678,11 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
AAB_DARWIN7_9_LONG_DOUBLE_FUNCS_TEST_CT, FD_MACH_ONLY | FD_REPLACEMENT,
aAab_Darwin7_9_Long_Double_FuncsTests, apzAab_Darwin7_9_Long_Double_FuncsPatch, 0 },
+ { zDarwin_Api_AvailabilityName, zDarwin_Api_AvailabilityList,
+ apzDarwin_Api_AvailabilityMachs,
+ DARWIN_API_AVAILABILITY_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+ aDarwin_Api_AvailabilityTests, apzDarwin_Api_AvailabilityPatch, 0 },
+
{ zAab_Fd_Zero_Asm_Posix_Types_HName, zAab_Fd_Zero_Asm_Posix_Types_HList,
apzAab_Fd_Zero_Asm_Posix_Types_HMachs,
AAB_FD_ZERO_ASM_POSIX_TYPES_H_TEST_CT, FD_MACH_ONLY | FD_REPLACEMENT,
diff --git a/fixincludes/inclhack.def b/fixincludes/inclhack.def
index 861532c..3c6b48d 100644
--- a/fixincludes/inclhack.def
+++ b/fixincludes/inclhack.def
@@ -195,6 +195,33 @@ fix = {
};
/*
+ * SDKs for 10.13 and 10.14 omit the definitions for API_AVAILABLE where
+ * __attribute__((availability)) is not supported.
+ */
+fix = {
+ hackname = darwin_api_availability;
+ mach = "*-*-darwin*";
+ files = os/availability.h;
+ bypass = "__IPHONE_OS_VERSION_MIN_REQUIRED";
+ select =
+ " *#define __API_AVAILABLE.*\n"
+ " *#define __API_DEPRECATED.*\n"
+ " *#define __API_DEPRECATED_WITH_REPLACEMENT.*\n"
+ " *#define __API_UNAVAILABLE.*\n";
+ c_fix = format;
+ c_fix_arg =
+ " #define API_AVAILABLE(...)\n"
+ " #define API_DEPRECATED(...)\n"
+ " #define API_DEPRECATED_WITH_REPLACEMENT(...)\n"
+ " #define API_UNAVAILABLE(...)\n";
+ test_text =
+ "#define __API_AVAILABLE(...)\n"
+ "#define __API_DEPRECATED(...)\n"
+ "#define __API_DEPRECATED_WITH_REPLACEMENT(...)\n"
+ "#define __API_UNAVAILABLE(...)\n";
+};
+
+/*
* This fixes __FD_ZERO bug for linux 2.x.y (x <= 2 && y <= some n)
*/
fix = {
diff --git a/fixincludes/tests/base/os/availability.h b/fixincludes/tests/base/os/availability.h
new file mode 100644
index 0000000..e8696b1
--- /dev/null
+++ b/fixincludes/tests/base/os/availability.h
@@ -0,0 +1,18 @@
+/* DO NOT EDIT THIS FILE.
+
+ It has been auto-edited by fixincludes from:
+
+ "fixinc/tests/inc/os/availability.h"
+
+ This had to be done to correct non-standard usages in the
+ original, manufacturer supplied header file. */
+
+
+
+#if defined( DARWIN_API_AVAILABILITY_CHECK )
+ #define API_AVAILABLE(...)
+ #define API_DEPRECATED(...)
+ #define API_DEPRECATED_WITH_REPLACEMENT(...)
+ #define API_UNAVAILABLE(...)
+
+#endif /* DARWIN_API_AVAILABILITY_CHECK */
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d405921..895e5f1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,13 +1,2974 @@
+2019-08-19 Joel Hutton <Joel.Hutton@arm.com>
+
+ * config/aarch64/aarch64-protos.h (aarch64_fpconst_pow2_recip): New prototype
+ * config/aarch64/aarch64.c (aarch64_fpconst_pow2_recip): New function
+ * config/aarch64/aarch64.md (*aarch64_<su_optab>cvtf<fcvt_target><GPF:mode>2_mult): New pattern
+ (*aarch64_<su_optab>cvtf<fcvt_iesize><GPF:mode>2_mult): New pattern
+ * config/aarch64/constraints.md (Dt): New constraint
+ * config/aarch64/predicates.md (aarch64_fpconst_pow2_recip): New predicate
+
+2019-08-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91403
+ * tree-scalar-evolution.c (follow_ssa_edge_binary): Inline
+ cases we can handle with tail-recursion...
+ (follow_ssa_edge_expr): ... here. Do so.
+
+2019-08-19 Kito Cheng <kito.cheng@sifive.com>
+
+ PR target/91441
+ * toplev.c (process_options): Check TARGET_ASAN_SHADOW_OFFSET is
+ implemented for -fsanitize=kernel-address, and merge check logic
+ with -fsanitize=address.
+
+2019-08-18 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config/rs6000/darwin.h (TARGET_OS_CPP_BUILTINS): Add asserts
+ for cpu and machine. Factor 64/32b builtins.
+
+2019-08-18 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/install.texi (Specific, bfin): blackfin.uclinux.org is
+ gone, point to sourceforge.net.
+
+2019-08-17 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/ux.texi (User Experience Guidelines): Update reference.
+
+2019-08-17 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/include/gpl_v3.texi (Copying): Adjust the link to "Why
+ not LGPL".
+
+2019-08-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-sra.c (build_reconstructed_reference): Return NULL_TREE instead
+ of NULL. Add guard for broken VIEW_CONVERT_EXPRs.
+
+2019-08-16 Martin Sebor <msebor@redhat.com>
+
+ * tree.def (TYPE_SIZE): Clarify.
+ * tree.h (TYPE_SIZE, TYPE_SIZE_UNIT, DECL_SIZE): Add comments.
+
+2019-08-16 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR tree-optimization/91109
+ * lra-int.h (lra_need_for_scratch_reg_p): Declare.
+ * lra.c (lra): Use lra_need_for_scratch_reg_p.
+ * lra-spills.c (lra_need_for_scratch_reg_p): New function.
+
+2019-08-16 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/mmx.md (mmxdoublemode): New mode attribute.
+ (mmx_uavg<mode>3): Macroize expaner from mmx_uavgv8qi3 and
+ mmx_uavgv4hi3 using MMXMODE12 mode iterator.
+ (uavg<mode>3_ceil): New expander.
+ * config/i386/sse.md (uavg<mode>3_ceil): Use ssedoublemode
+ mode iterator when creating CONST1_RTX.
+ (<sse2_avx2>_uavg<mode>3<mask_name>): Ditto.
+ (*<sse2_avx2>_uavg<mode>3<mask_name>): Use ssedoublemode
+ mode iterator for const1_operand predicate.
+
+2019-08-16 Richard Biener <rguenther@suse.de>
+
+ * tree-scalar-evolution.c (follow_ssa_edge_expr): Declare.
+ (follow_ssa_edge_binary): Call follow_ssa_edge_expr instead of
+ follow_ssa_edge.
+ (follow_ssa_edge_in_condition_phi_branch): Likewise.
+ (analyze_evolution_in_loop): Likewise.
+ (follow_ssa_edge, follow_ssa_edge_in_rhs): Inline into ...
+ (follow_ssa_edge_expr): ... here. Refactor code.
+
+2019-08-16 Richard Biener <rguenther@suse.de>
+
+ PR target/91469
+ * config/i386/i386-features.c
+ (general_scalar_chain::replace_with_subreg): Stop at memory operands.
+
+2019-08-16 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR other/91255
+ * gensupport.c (has_subst_attribute): Error out on set_attr_alternative
+ only if subst_name matches curr_attr string.
+
+2019-08-16 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-forwprop.c (simplify_builtin_call): Do not remove
+ stmt at gsi_p, instead replace it with a NOP removed later.
+ (pass_forwprop::execute): Fully propagate lattice, DCE stmts
+ that became dead because of that.
+
+2019-08-16 Aldy Hernandez <aldyh@redhat.com>
+
+ * gimple-ssa-evrp-analyze.c (record_ranges_from_phis): Skip PHIs
+ for which we can't represent a range.
+ * ipa-cp.c (ipcp_vr_lattice::set_to_bottom): Pass type to
+ set_varying.
+ * tree-ssa-threadedge.c (record_temporary_equivalences_from_phis):
+ Set VR_UNDEFINED if type is not supported.
+ * tree-ssanames.c (get_range_info): Pass type to set_varying.
+ * tree-vrp.c (value_range_base::check): Assert that a varying has
+ min/max set.
+ (value_range_base::equal_p): Early bail for undefines.
+ (value_range_base::set_varying): Accept a type.
+ (value_range::set_varying): Same.
+ (value_range_base::type): VARYING can have a type, while UNDEFINE
+ is typeless.
+ (value_range_base::dump): Print type for VARYING nodes.
+ (value_range_base::set): Add type to VARYING.
+ (extract_range_from_multiplicative_op): Pass type to set_varying.
+ (extract_range_from_binary_expr): Same.
+ (value_range_base::intersect_helper): Same.
+ (value_range_base::union_helper): Same.
+ (value_range_base::normalize_symbolics): Same.
+ (determine_value_range_1): Same.
+ * tree-vrp.h (class value_range_base): Add type to set_varying.
+ Add prototype for dump(void).
+ Add prototype for supports_type_p.
+ (class value_range): Add type to set_varying.
+ Add prototype for dump(void).
+ * vr-values.c (set_value_range_to_truthvalue): Pass type to
+ set_varying.
+ (vr_values::get_lattice_entry): Set varying even if propagation
+ finished.
+ Pass type to set_varying.
+ (vr_values::get_value_range): Remove vr_const_varying.
+ Reallocate the lattice if needed.
+ (vr_values::update_value_range): Pass type to set_varying.
+ (vr_values::extract_range_for_var_from_comparison_expr): Same.
+ (vr_values::extract_range_from_binary_expr): Same.
+ (vr_values::extract_range_from_unary_expr): Same.
+ (vr_values::extract_range_from_cond_expr): Same.
+ (vr_values::check_for_binary_op_overflow): Same.
+ (vr_values::extract_range_basic): Same.
+ (vr_values::extract_range_from_assignment): Same.
+ (vr_values::vr_values): Increase size of num_vr_values.
+ (vr_values::extract_range_from_phi_node): Pass type to
+ set_varying.
+
+2019-08-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/90878
+ * config/i386/i386.c (inline_memory_move_cost): Use hard_register
+ for costs of hard register moves.
+ (ix86_register_move_cost): Likewise.
+ * config/i386/i386.h (processor_costs): Move costs of hard
+ register moves to hard_register. Add int_load, int_store,
+ xmm_move, ymm_move, zmm_move, sse_to_integer, integer_to_sse,
+ sse_load, sse_store, sse_unaligned_load and sse_unaligned_store
+ for costs of RTL expressions.
+ * config/i386/x86-tune-costs.h: Move costs of hard register
+ moves to hard_register. Duplicate int_load, int_store,
+ xmm_move, ymm_move, zmm_move, sse_to_integer, integer_to_sse,
+ sse_load, sse_store for costs of RTL expressions.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * target.def (setup_incoming_vararg_bounds): Remove.
+ * doc/tm.texi.in (TARGET_SETUP_INCOMING_VARARG_BOUNDS): Remove.
+ * doc/tm.texi: Regenerate.
+ * targhooks.c (default_setup_incoming_vararg_bounds): Delete.
+ * targhooks.h (default_setup_incoming_vararg_bounds): Likewise.
+ * config/i386/i386.c (ix86_setup_incoming_vararg_bounds): Likewise.
+ (TARGET_SETUP_INCOMING_VARARG_BOUNDS): Likewise.
+
+2019-08-15 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ MSP430: Fix lines over 80 characters long in
+ config/msp430/*.{c,h} files
+
+ * config/msp430/driver-msp430.c (msp430_select_cpu): Fix format
+ specifier in string.
+ (msp430_select_hwmult_lib): Split line more than 80 characters long.
+ * config/msp430/msp430-devices.c (msp430_extract_mcu_data): Remove
+ redundant old comment.
+ * config/msp430/msp430-protos.h (msp430_output_aligned_decl_common):
+ Split line more than 80 characters long.
+ * config/msp430/msp430.c (msp430_option_override): Likewise.
+ (msp430_return_in_memory): Likewise.
+ (msp430_gimplify_va_arg_expr): Likewise.
+ (TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P): Likewise.
+ (msp430_legitimate_constant): Likewise.
+ (TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS): Likewise.
+ (msp430_attr): Likewise.
+ (msp430_data_attr): Likewise.
+ (msp430_start_function): Likewise.
+ (gen_prefix): Likewise.
+ (msp430_init_sections): Likewise.
+ (msp430_select_section): Likewise.
+ (msp430_function_section): Likewise.
+ (msp430_unique_section): Likewise.
+ (msp430_output_aligned_decl_common): Likewise.
+ (msp430_do_not_relax_short_jumps): Likewise.
+ (msp430_init_builtins): Likewise.
+ (msp430_expand_delay_cycles): Likewise.
+ (msp430_expand_prologue): Likewise.
+ (msp430_expand_epilogue): Likewise.
+ (msp430_expand_helper): Likewise.
+ (msp430_split_movsi): Likewise.
+ (msp430_print_operand): Likewise.
+ (msp430_return_addr_rtx): Likewise.
+ (msp430x_extendhisi): Likewise.
+ * config/msp430/msp430.h (STARTFILE_SPEC): Likewise.
+ (ASM_SPEC): Likewise.
+ Remove very obvious comments.
+ (LIB_SPEC): Split line more than 80 characters long.
+ (EH_RETURN_HANDLER_RTX): Likewise.
+ (HARD_REGNO_CALLER_SAVE_MODE): Likewise.
+
+2019-08-15 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ MSP430: Fix whitespace errors and incorrect indentation in
+ config/msp430/*.{c,h} files
+
+ * config/msp430/driver-msp430.c (msp430_select_cpu): Fix indentation.
+ (msp430_select_hwmult_lib): Likewise.
+ * config/msp430/msp430-devices.c (parse_devices_csv_1): Likewise.
+ (msp430_extract_mcu_data): Likewise.
+ (struct t_msp430_mcu_data): Likewise.
+ * config/msp430/msp430.c (struct machine_function): Remove whitespace
+ before left square bracket.
+ (msp430_option_override): Fix indentation.
+ (msp430_hard_regno_nregs_with_padding): Likewise.
+ (msp430_initial_elimination_offset): Likewise.
+ (msp430_special_register_convention_p): Remove whitespace before left
+ square bracket and after exclamation mark.
+ (msp430_evaluate_arg): Likewise.
+ (msp430_callee_copies): Fix indentation.
+ (msp430_gimplify_va_arg_expr): Likewise.
+ (msp430_function_arg_advance): Remove whitespace before left square
+ bracket.
+ (reg_ok_for_addr): Likewise.
+ (msp430_preserve_reg_p): Likewise.
+ (msp430_compute_frame_info): Likewise.
+ (msp430_asm_output_addr_const_extra): Add space between function name
+ and open parenthesis.
+ (has_section_name): Fix indentation.
+ (msp430_attr): Remove trailing whitespace.
+ (msp430_section_attr): Likewise.
+ (msp430_data_attr): Likewise.
+ (struct msp430_attribute_table): Fix comment and whitespace.
+ (msp430_start_function): Remove whitespace before left square bracket.
+ Add space between function name and open parenthesis.
+ (msp430_select_section): Remove trailing whitespace.
+ (msp430_section_type_flags): Remove trailing whitespace.
+ (msp430_unique_section): Remove space before closing parenthesis.
+ (msp430_output_aligned_decl_common): Change 8 spaces to a tab.
+ (msp430_builtins): Remove whitespace before left square bracket.
+ (msp430_init_builtins): Fix indentation.
+ (msp430_expand_prologue): Remove whitespace before left square bracket.
+ Remove space before closing parenthesis.
+ (msp430_expand_epilogue): Remove whitespace before left square bracket.
+ (msp430_split_movsi): Remove space before closing parenthesis.
+ (helper_function_name_mappings): Fix indentation.
+ (msp430_use_f5_series_hwmult): Fix whitespace.
+ (use_32bit_hwmult): Likewise.
+ (msp430_no_hwmult): Likewise.
+ (msp430_output_labelref): Remove whitespace before left square bracket.
+ (msp430_print_operand_raw): Likewise.
+ (msp430_print_operand_addr): Likewise.
+ (msp430_print_operand): Add two spaces after '.' in comment.
+ Fix trailing whitespace.
+ (msp430x_extendhisi): Fix indentation.
+ * config/msp430/msp430.h (TARGET_CPU_CPP_BUILTINS): Change 8 spaces to
+ tab.
+ (PC_REGNUM): Likewise.
+ (STACK_POINTER_REGNUM): Likewise.
+ (CC_REGNUM): Likewise.
+
+2019-08-15 Richard Biener <rguenther@suse.de>
+
+ PR target/91454
+ * config/i386/i386-features.c (gen_gpr_to_xmm_move_src): New
+ helper.
+ (general_scalar_chain::make_vector_copies): Use it.
+
+2019-08-15 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * function.c (assign_parm_setup_reg): Handle misaligned stack arguments.
+
+2019-08-15 Martin Liska <mliska@suse.cz>
+
+ * tree-ssa-dce.c (propagate_necessity): We can't reach now
+ operators with no arguments.
+ (eliminate_unnecessary_stmts): Likewise here.
+
+2019-08-15 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386-features.c (general_scalar_chain::convert_insn)
+ <case COMPARE>: Revert 2019-08-14 change.
+ (convertible_comparison_p): Revert 2019-08-14 change. Return false
+ for (TARGET_64BIT || mode != DImode).
+
+2019-08-15 Aldy Hernandez <aldyh@redhat.com>
+
+ * tree-vrp.c (value_range_base::set): Merge in code from
+ value_range_base::set_and_canonicalize.
+ Enforce canonicalization at set time.
+ Normalize [MIN, MAX] into VARYING and ~[MIN, MAX] into UNDEFINED.
+ (value_range_base::set_undefined): Inline call to set().
+ (value_range_base::set_varying): Same.
+ (value_range_base::singleton_p): Handle VR_ANTI_RANGEs.
+ (vrp_val_max): New argument handle_pointers.
+ (vrp_val_min): Same.
+ (ranges_from_anti_range): Same.
+ (extract_range_into_wide_ints): Use tree argument instead of sign
+ and precision.
+ (extract_range_from_multiplicative_op): Take in tree type instead
+ of precision and sign. Adapt function for canonicalized ranges.
+ (extract_range_from_binary_expr): Pass type to
+ extract_range_from_multiplicative_op.
+ Adapt for canonicalized ranges.
+ (extract_range_from_unary_expr): Same.
+ (value_range_base::intersect_helper): Adjust for canonicalized
+ ranges.
+ (value_range_base::union_helper): Same.
+ (value_range_base::normalize_symbolics): New.
+ * tree-vrp.h (class value_range_base): Remove
+ set_and_canonicalize.
+ New prototype for normalize_symbolics.
+ (class value_range): Remove set_and_canonicalize.
+ (vrp_val_min): Adjust prototype.
+ (vrp_val_max): Same.
+ * vr-values.c
+ (vr_values::extract_range_for_var_from_comparison_expr): Call set
+ instead of set_and_canonicalize.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR middle-end/91444
+ * tree-vect-stmts.c (vectorizable_call): Check that the function
+ is a BUILT_IN_MD function before passing it to
+ targetm.vectorize.builtin_md_vectorized_function.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-protos.h (aarch64_sve_mode_p): Declare.
+ * config/aarch64/aarch64.c (aarch64_sve_mode_p): New function.
+ (aarch64_select_early_remat_modes): Use it.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_simd_vector_alignment): Return
+ 16 for SVE predicates even if they are fixed-length.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md (and<PRED_ALL:mode>3): Make the
+ operand order match the MOV /Z alias.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_output_sve_cnt_immediate): Take
+ the vector pattern as an aarch64_svpattern argument. Update the
+ overloaded caller accordingly.
+ (aarch64_output_sve_scalar_inc_dec): Update call accordingly.
+ (aarch64_output_sve_vector_inc_dec): Likewise.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_add_offset): In the fallback
+ multiplication case, try to compute VG * (lowest set bit) directly
+ rather than always basing the multiplication on VG. Use
+ expand_mult for the multiplication if we can.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-protos.h
+ (aarch64_sve_scalar_inc_dec_immediate_p): Declare.
+ (aarch64_sve_inc_dec_immediate_p): Rename to...
+ (aarch64_sve_vector_inc_dec_immediate_p): ...this.
+ (aarch64_output_sve_addvl_addpl): Take a single rtx argument.
+ (aarch64_output_sve_scalar_inc_dec): Declare.
+ (aarch64_output_sve_inc_dec_immediate): Rename to...
+ (aarch64_output_sve_vector_inc_dec): ...this.
+ * config/aarch64/aarch64.c (aarch64_sve_scalar_inc_dec_immediate_p)
+ (aarch64_output_sve_scalar_inc_dec): New functions.
+ (aarch64_output_sve_addvl_addpl): Remove the base and offset
+ arguments. Only handle true ADDVL and ADDPL instructions;
+ don't emit an INC or DEC.
+ (aarch64_sve_inc_dec_immediate_p): Rename to...
+ (aarch64_sve_vector_inc_dec_immediate_p): ...this.
+ (aarch64_output_sve_inc_dec_immediate): Rename to...
+ (aarch64_output_sve_vector_inc_dec): ...this. Update call to
+ aarch64_sve_vector_inc_dec_immediate_p.
+ * config/aarch64/predicates.md (aarch64_sve_scalar_inc_dec_immediate)
+ (aarch64_sve_plus_immediate): New predicates.
+ (aarch64_pluslong_operand): Accept aarch64_sve_plus_immediate
+ rather than aarch64_sve_addvl_addpl_immediate.
+ (aarch64_sve_inc_dec_immediate): Rename to...
+ (aarch64_sve_vector_inc_dec_immediate): ...this. Update call to
+ aarch64_sve_vector_inc_dec_immediate_p.
+ (aarch64_sve_add_operand): Update accordingly.
+ * config/aarch64/constraints.md (Uai): New constraint.
+ (vsi): Update call to aarch64_sve_vector_inc_dec_immediate_p.
+ * config/aarch64/aarch64.md (add<GPI:mode>3): Don't force the second
+ operand into a register if it satisfies aarch64_sve_plus_immediate.
+ (*add<GPI:mode>3_aarch64, *add<GPI:mode>3_poly_1): Add an alternative
+ for Uai. Update calls to aarch64_output_sve_addvl_addpl.
+ * config/aarch64/aarch64-sve.md (add<mode>3): Call
+ aarch64_output_sve_vector_inc_dec instead of
+ aarch64_output_sve_inc_dec_immediate.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/iterators.md (UNSPEC_REVB, UNSPEC_REVH)
+ (UNSPEC_REVW): New constants.
+ (elem_bits): New mode attribute.
+ (SVE_INT_UNARY): New int iterator.
+ (optab): Handle UNSPEC_REV[BHW].
+ (sve_int_op): New int attribute.
+ (min_elem_bits): Handle VNx16QI and the predicate modes.
+ * config/aarch64/aarch64-sve.md (*aarch64_sve_rev64<mode>)
+ (*aarch64_sve_rev32<mode>, *aarch64_sve_rev16vnx16qi): Delete.
+ (@aarch64_pred_<SVE_INT_UNARY:optab><SVE_I:mode>): New pattern.
+ * config/aarch64/aarch64.c (aarch64_sve_data_mode): New function.
+ (aarch64_sve_int_mode, aarch64_sve_rev_unspec): Likewise.
+ (aarch64_split_sve_subreg_move): Use UNSPEC_REV[BHW] instead of
+ unspecs based on the total width of the reversed data.
+ (aarch64_evpc_rev_local): Likewise (for SVE only). Use a
+ reinterpret followed by a subreg on big-endian targets.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * config/aarch64/aarch64-sve.md
+ (*cond_<SVE_COND_FP_TERNARY:optab><SVE_F:mode>_any): Add /z
+ alternatives in which one of the inputs is in the same register
+ as the output.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md (*vec_extract<mode><Vel>_ext)
+ (*aarch64_sve_ext<mode>): Add MOVPRFX alternatives.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md (*sub<SVE_F:mode>3): Remove immediate
+ FADD and FSUB alternatives. Add a MOVPRFX alternative for FSUBR.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * config/aarch64/aarch64-sve.md (add<SVE_I:mode>3, sub<SVE_I:mode>3)
+ (<LOGICAL:optab><SVE_I:mode>3, *add<SVE_F:mode>3, *mul<SVE_F:mode>3)
+ (*fabd<SVE_F:mode>3): Add more MOVPRFX alternatives.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+ Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ * config/aarch64/aarch64-sve.md (*v<ASHIFT:optab><SVE_I:mode>3):
+ Add an alternative that uses reversed shifts.
+
+2019-08-15 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/aarch64/aarch64-cores.def (cortex-a76): Use neoversen1 tuning
+ struct.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md (aarch64_<su>abd<mode>_3): Add
+ a commutativity marker.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * config/aarch64/aarch64-protos.h (aarch64_prepare_sve_int_fma)
+ (aarch64_prepare_sve_cond_int_fma): Declare.
+ * config/aarch64/aarch64.c (aarch64_convert_mult_to_shift)
+ (aarch64_prepare_sve_int_fma): New functions.
+ (aarch64_prepare_sve_cond_int_fma): Likewise.
+ * config/aarch64/aarch64-sve.md
+ (cond_<SVE_INT_BINARY:optab><SVE_I:mode>): Add a "@" marker.
+ (fma<SVE_I:mode>4, cond_fma<SVE_I:mode>, *cond_fma<SVE_I:mode>_2)
+ (*cond_fma<SVE_I:mode>_4, *cond_fma<SVE_I:mode>_any, fnma<SVE_I:mode>4)
+ (cond_fnma<SVE_I:mode>, *cond_fnma<SVE_I:mode>_2)
+ (*cond_fnma<SVE_I:mode>_4, *cond_fnma<SVE_I:mode>_any): New patterns.
+ (*madd<mode>): Rename to...
+ (*fma<mode>4): ...this.
+ (*msub<mode>): Rename to...
+ (*fnma<mode>4): ...this.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * config/aarch64/aarch64.c (aarch64_print_vector_float_operand):
+ Print 2.0 naturally.
+ (aarch64_sve_float_mul_immediate_p): Return true for 2.0.
+ * config/aarch64/predicates.md
+ (aarch64_sve_float_negated_arith_immediate): New predicate,
+ renamed from aarch64_sve_float_arith_with_sub_immediate.
+ (aarch64_sve_float_arith_with_sub_immediate): Test for both
+ positive and negative constants.
+ (aarch64_sve_float_arith_with_sub_operand): Redefine as a register
+ or an aarch64_sve_float_arith_with_sub_immediate.
+ * config/aarch64/constraints.md (vsN): Use
+ aarch64_sve_float_negated_arith_immediate.
+ * config/aarch64/iterators.md (SVE_COND_FP_BINARY_I1): New int
+ iterator.
+ (sve_pred_fp_rhs2_immediate): New int attribute.
+ * config/aarch64/aarch64-sve.md
+ (cond_<SVE_COND_FP_BINARY:optab><SVE_F:mode>): Use
+ sve_pred_fp_rhs1_operand and sve_pred_fp_rhs2_operand.
+ (*cond_<SVE_COND_FP_BINARY_I1:optab><SVE_F:mode>_2_const)
+ (*cond_<SVE_COND_FP_BINARY_I1:optab><SVE_F:mode>_any_const)
+ (*cond_add<SVE_F:mode>_2_const, *cond_add<SVE_F:mode>_any_const)
+ (*cond_sub<mode>_3_const, *cond_sub<mode>_any_const): New patterns.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * config/aarch64/aarch64-sve.md (*aarch64_cond_abd<SVE_F:mode>_2)
+ (*aarch64_cond_abd<SVE_F:mode>_3)
+ (*aarch64_cond_abd<SVE_F:mode>_any): New patterns.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * config/aarch64/aarch64-sve.md (*aarch64_cond_<su>abd<mode>_2)
+ (*aarch64_cond_<su>abd<mode>_any): New patterns.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+ Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ * internal-fn.def (IFN_COND_SHL, IFN_COND_SHR): New internal functions.
+ * internal-fn.c (FOR_EACH_CODE_MAPPING): Handle shifts.
+ * match.pd (UNCOND_BINARY, COND_BINARY): Likewise.
+ * optabs.def (cond_ashl_optab, cond_ashr_optab, cond_lshr_optab): New
+ optabs.
+ * optabs.h (create_convert_operand_from): Expand comment.
+ * optabs.c (maybe_legitimize_operand): Allow implicit broadcasts
+ when mapping scalar rtxes to vector operands.
+ * config/aarch64/iterators.md (SVE_INT_BINARY): Add ashift,
+ ashiftrt and lshiftrt.
+ (sve_int_op, sve_int_op_rev, sve_pred_int_rhs2_operand): Handle them.
+ * config/aarch64/aarch64-sve.md (*cond_<optab><mode>_2_const)
+ (*cond_<optab><mode>_any_const): New patterns.
+
+2019-08-15 Martin Liska <mliska@suse.cz>
+
+ PR ipa/91438
+ * cgraph.c (cgraph_node::remove): When setting
+ n->origin = NULL for all nested functions, reset
+ also next_nested.
+
+2019-08-15 Martin Liska <mliska@suse.cz>
+
+ * cgraph.c (cgraph_node::verify_node): Verify origin, nested
+ and next_nested.
+
+2019-08-15 Martin Liska <mliska@suse.cz>
+
+ PR ipa/91404
+ * passes.c (order): Remove.
+ (uid_hash_t): Likewise).
+ (remove_cgraph_node_from_order): Remove from set
+ of pointers (cgraph_node *).
+ (insert_cgraph_node_to_order): New.
+ (duplicate_cgraph_node_to_order): New.
+ (do_per_function_toporder): Register all 3 cgraph hooks.
+ Skip removed_nodes now as we know about all of them.
+
+2019-08-14 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386-expand.c (ix86_expand_vector_init_one_nonzero)
+ <case E_V8QImode>: Use vector_set path for
+ TARGET_MMX_WITH_SSE && TARGET_SSE4_1.
+ (ix86_expand_vector_init_one_var) <case E_V8QImode>:
+ Do not widen for TARGET_MMX_WITH_SSE && TARGET_SSE4_1.
+
+2019-08-14 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * builtins.c (expand_builtin_init_descriptor): Set memory alignment.
+
+2019-08-14 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/91294
+ * tree-ssa-strlen.c (handle_store): Avoid treating lower bound of
+ source length as exact.
+
+2019-08-14 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * doc/extend.texi: Add "noinit" attribute documentation.
+ * doc/sourcebuild.texi: Add noinit effective target documentation.
+ * varasm.c (default_section_type_flags): Add support for "noinit"
+ section.
+ (default_elf_select_section): Add support for "noinit" attribute.
+ * config/msp430/msp430.c (msp430_attribute_table): Remove
+ "noinit" entry.
+
+2019-08-14 Richard Biener <rguenther@suse.de>
+ Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/91154
+ * config/i386/i386-features.h (scalar_chain::scalar_chain): Add
+ mode arguments.
+ (scalar_chain::smode): New member.
+ (scalar_chain::vmode): Likewise.
+ (dimode_scalar_chain): Rename to...
+ (general_scalar_chain): ... this.
+ (general_scalar_chain::general_scalar_chain): Take mode arguments.
+ (timode_scalar_chain::timode_scalar_chain): Initialize scalar_chain
+ base with TImode and V1TImode.
+ * config/i386/i386-features.c (scalar_chain::scalar_chain): Adjust.
+ (general_scalar_chain::vector_const_cost): Adjust for SImode
+ chains.
+ (general_scalar_chain::compute_convert_gain): Likewise. Add
+ {S,U}{MIN,MAX} support.
+ (general_scalar_chain::replace_with_subreg): Use vmode/smode.
+ (general_scalar_chain::make_vector_copies): Likewise. Handle
+ non-DImode chains appropriately.
+ (general_scalar_chain::convert_reg): Likewise.
+ (general_scalar_chain::convert_op): Likewise.
+ (general_scalar_chain::convert_insn): Likewise. Add
+ fatal_insn_not_found if the result is not recognized.
+ (convertible_comparison_p): Pass in the scalar mode and use that.
+ (general_scalar_to_vector_candidate_p): Likewise. Rename from
+ dimode_scalar_to_vector_candidate_p. Add {S,U}{MIN,MAX} support.
+ (scalar_to_vector_candidate_p): Remove by inlining into single
+ caller.
+ (general_remove_non_convertible_regs): Rename from
+ dimode_remove_non_convertible_regs.
+ (remove_non_convertible_regs): Remove by inlining into single caller.
+ (convert_scalars_to_vector): Handle SImode and DImode chains
+ in addition to TImode chains.
+ * config/i386/i386.md (<maxmin><MAXMIN_IMODE>3): New expander.
+ (*<maxmin><MAXMIN_IMODE>3_1): New insn-and-split.
+ (*<maxmin>di3_doubleword): Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * config/aarch64/aarch64-sve.md (*cond_bic<mode>_2)
+ (*cond_bic<mode>_any): New patterns.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_print_operand): Allow %e to
+ take the equivalent mask, as well as a bit count.
+ * config/aarch64/predicates.md (aarch64_sve_uxtb_immediate)
+ (aarch64_sve_uxth_immediate, aarch64_sve_uxt_immediate)
+ (aarch64_sve_pred_and_operand): New predicates.
+ * config/aarch64/iterators.md (sve_pred_int_rhs2_operand): New
+ code attribute.
+ * config/aarch64/aarch64-sve.md
+ (cond_<SVE_INT_BINARY:optab><SVE_I:mode>): Use it.
+ (*cond_uxt<mode>_2, *cond_uxt<mode>_any): New patterns.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md
+ (*cond_<SVE_COND_FCVTI:optab>_nontrunc<SVE_F:mode><SVE_HSDI:mode>)
+ (*cond_<SVE_COND_ICVTF:optab>_nonextend<SVE_HSDI:mode><SVE_F:mode>):
+ New patterns.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * config/aarch64/aarch64-sve.md
+ (*cond_<SVE_COND_FP_UNARY:optab><SVE_F:mode>_2): New pattern.
+ (*cond_<SVE_COND_FP_UNARY:optab><SVE_F:mode>_any): Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * config/aarch64/aarch64-sve.md
+ (*cond_<SVE_INT_UNARY:optab><SVE_I:mode>_2): New pattern.
+ (*cond_<SVE_INT_UNARY:optab><SVE_I:mode>_any): Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/iterators.md (SVE_COND_FP_ABS_CMP): New iterator.
+ * config/aarch64/aarch64-sve.md (*aarch64_pred_fac<cmp_op><mode>):
+ New pattern.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * config/aarch64/aarch64-sve.md (*aarch64_sel_dup<mode>): New pattern.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * config/aarch64/aarch64.c (aarch64_bit_representation): New function.
+ (aarch64_print_vector_float_operand): Also handle 8-bit floats.
+ (aarch64_print_operand): Add support for %I.
+ (aarch64_sve_dup_immediate_p): Handle scalars as well as vectors.
+ Bitcast floating-point constants to the corresponding integer constant.
+ (aarch64_float_const_representable_p): Handle vectors as well
+ as scalars.
+ (aarch64_expand_sve_vcond): Make sure that the operands are valid
+ for the new vcond_mask_<mode><vpred> expander.
+ * config/aarch64/predicates.md (aarch64_sve_dup_immediate): Also
+ test aarch64_float_const_representable_p.
+ (aarch64_sve_reg_or_dup_imm): New predicate.
+ * config/aarch64/aarch64-sve.md (vec_extract<vpred><Vel>): Use
+ gen_vcond_mask_<mode><vpred> instead of
+ gen_aarch64_sve_dup<mode>_const.
+ (vcond_mask_<mode><vpred>): Turn into a define_expand that
+ accepts aarch64_sve_reg_or_dup_imm and aarch64_simd_reg_or_zero
+ for operands 1 and 2 respectively. Force operand 2 into a
+ register if operand 1 is a register. Fold old define_insn...
+ (aarch64_sve_dup<mode>_const): ...and this define_insn...
+ (*vcond_mask_<mode><vpred>): ...into this new pattern. Handle
+ floating-point constants that can be moved as integers. Add
+ alternatives for MOV /M and FMOV /M.
+ (vcond<mode><v_int_equiv>, vcondu<mode><v_int_equiv>)
+ (vcond<mode><v_fp_equiv>): Accept nonmemory_operand for operands
+ 1 and 2 respectively.
+ * config/aarch64/constraints.md (Ufc): Handle vectors as well
+ as scalars.
+ (vss): New constraint.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/predicates.md (aarch64_sve_float_maxmin_immediate)
+ (aarch64_sve_float_maxmin_operand): New predicates.
+ * config/aarch64/constraints.md (vsB): New constraint.
+ (vsM): Fix typo.
+ * config/aarch64/iterators.md (sve_pred_fp_rhs2_operand): Use
+ aarch64_sve_float_maxmin_operand for UNSPEC_COND_FMAXNM and
+ UNSPEC_COND_FMINNM.
+ * config/aarch64/aarch64-sve.md (<maxmin_uns><SVE_F:mode>3):
+ Use aarch64_sve_float_maxmin_operand for operand 2.
+ (*<SVE_COND_FP_MAXMIN_PUBLIC:optab><SVE_F:mode>3): Likewise.
+ Add alternatives for the constant forms.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/constraints.md (vsb): New constraint.
+ (vsm): Generalize description.
+ * config/aarch64/iterators.md (SVE_INT_BINARY_IMM): New code
+ iterator.
+ (sve_imm_con): Handle smax, smin, umax and umin.
+ (sve_imm_prefix): New code attribute.
+ * config/aarch64/predicates.md (aarch64_sve_vsb_immediate)
+ (aarch64_sve_vsb_operand): New predicates.
+ (aarch64_sve_mul_immediate): Rename to...
+ (aarch64_sve_vsm_immediate): ...this.
+ (aarch64_sve_mul_operand): Rename to...
+ (aarch64_sve_vsm_operand): ...this.
+ * config/aarch64/aarch64-sve.md (mul<mode>3): Generalize to...
+ (<SVE_INT_BINARY_IMM:optab><SVE_I:mode>3): ...this.
+ (*mul<mode>3, *post_ra_mul<mode>3): Generalize to...
+ (*<SVE_INT_BINARY_IMM:optab><SVE_I:mode>3)
+ (*post_ra_<SVE_INT_BINARY_IMM:optab><SVE_I:mode>3): ...these and
+ add movprfx support for the immediate alternatives.
+ (<su><maxmin><mode>3, *<su><maxmin><mode>3): Delete in favor
+ of the above.
+ (*<SVE_INT_BINARY_SD:optab><SVE_SDI:mode>3): Fix incorrect predicate
+ for operand 3.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/predicates.md (aarch64_simd_imm_one): New predicate.
+ * config/aarch64/aarch64-sve.md (*cnot<mode>): New pattern.
+ (*cond_cnot<mode>_2, *cond_cnot<mode>_any): Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/iterators.md (SVE_INT_UNARY): Add clrsb and clz.
+ (optab, sve_int_op): Handle them.
+ * config/aarch64/aarch64-sve.md: Expand comment.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/predicates.md (const_1_to_3_operand): New predicate.
+ * config/aarch64/aarch64-sve.md (*aarch64_adr_uxtw)
+ (*aarch64_adr<mode>_shift, *aarch64_adr_shift_uxtw): New patterns.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_expand_sve_const_pred_eor)
+ (aarch64_expand_sve_const_pred_trn): New functions.
+ (aarch64_expand_sve_const_pred_1): Add a recurse_p parameter and
+ use the above functions when the parameter is true.
+ (aarch64_expand_sve_const_pred): Update call accordingly.
+ * config/aarch64/aarch64-sve.md (*aarch64_sve_<perm_insn><mode>):
+ Rename to...
+ (@aarch64_sve_<perm_insn><mode>): ...this.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-protos.h (aarch64_sve_same_pred_for_ptest_p):
+ Declare.
+ * config/aarch64/aarch64.c (aarch64_sve_same_pred_for_ptest_p)
+ (aarch64_sve_emit_int_cmp): New functions.
+ (aarch64_convert_sve_data_to_pred): Use aarch64_sve_emit_int_cmp.
+ (aarch64_sve_cmp_operand_p, aarch64_emit_sve_ptrue_op_cc): Delete.
+ (aarch64_expand_sve_vec_cmp_int): Use aarch64_sve_emit_int_cmp.
+ * config/aarch64/aarch64.md (UNSPEC_MERGE_PTRUE): Delete.
+ (UNSPEC_PRED_Z): New unspec.
+ (set_clobber_cc_nzc): Delete.
+ * config/aarch64/aarch64-sve.md: Add a block comment about
+ UNSPEC_PRED_Z.
+ (*cmp<SVE_INT_CMP:cmp_op><mode>): Rename to...
+ (@aarch64_pred_cmp<SVE_INT_CMP:cmp_op><mode>): ...this, replacing
+ the old pattern with that name. Use UNSPEC_PRED_Z instead of
+ UNSPEC_MERGE_PTRUE.
+ (*cmp<SVE_INT_CMP:cmp_op><mode>_cc): Use UNSPEC_PRED_Z instead of
+ UNSPEC_MERGE_PTRUE. Use aarch64_sve_same_pred_for_ptest_p to
+ check for compatible predicates.
+ (*cmp<cmp_op><SVE_INT_CMP:mode>_ptest): Likewise.
+ (*cmp<cmp_op><mode>_and): Match a known-ptrue UNSPEC_PRED_Z instead
+ of UNSPEC_MERGE_PTRUE. Split into the new form of predicated
+ comparisons above.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64.md (UNSPEC_PRED_X): New unspec.
+ * config/aarch64/aarch64-sve.md: Add a section describing it.
+ (@aarch64_pred_mov<mode>, @aarch64_pred_mov<mode>)
+ (<SVE_INT_UNARY:optab><mode>2, *<SVE_INT_UNARY:optab><mode>2)
+ (aarch64_<su>abd<mode>_3, mul<SVE_I:mode>3, *mul<SVE_I:mode>3)
+ (<su>mul<mode>3_highpart, *<su>mul<mode>3_highpart)
+ (<SVE_INT_BINARY:optab><mode>3, *<SVE_INT_BINARY:optab><mode>3)
+ (*bic<mode>3, v<ASHIFT:optab><mode>3, *v<ASHIFT:optab><mode>3)
+ (<su><maxmin><mode>3, *<su><maxmin><mode>3, *madd<SVE_I:mode>)
+ (*msub<SVE_I:mode>3, *aarch64_sve_rev64<mode>)
+ (*aarch64_sve_rev32<mode>, *aarch64_sve_rev16vnx16qi): Use
+ UNSPEC_PRED_X instead of UNSPEC_MERGE_PTRUE.
+ * config/aarch64/aarch64-sve2.md (<u>avg<mode>3_floor)
+ (<u>avg<mode>3_ceil, *<sur>h<addsub><mode>): Likewise.
+ * config/aarch64/aarch64.c (aarch64_split_sve_subreg_move)
+ (aarch64_evpc_rev_local): Update accordingly.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/iterators.md (VNx4SI_ONLY, VNx2DF_ONLY): New mode
+ iterators.
+ (SVE_BHSI, SVE_SDI): Tweak comment.
+ (SVE_HSDI): Likewise. Fix definition.
+ (SVE_SDF): New mode iterator.
+ (elem_bits): New mode attribute.
+ (SVE_COND_FCVT): New int iterator.
+ * config/aarch64/aarch64-sve.md
+ (*<SVE_COND_ICVTF:optab>v16hsf<SVE_HSDI:mode>2)
+ (*<SVE_COND_ICVTF:optab>vnx4sf<SVE_SDI:mode>2)
+ (*<SVE_COND_ICVTF:optab>vnx2df<SVE_SDI:mode>2): Merge into...
+ (*aarch64_sve_<SVE_COND_ICVTF:optab>_nontrunc<SVE_F:mode><SVE_HSDI:mode>)
+ (*aarch64_sve_<SVE_COND_ICVTF:optab>_trunc<VNx2DF_ONLY:mode><VNx4SI_ONLY:mode>):
+ ...these new patterns.
+ (*<SVE_COND_FCVTI:optab><SVE_HSDI:mode>vnx8hf2)
+ (*<SVE_COND_FCVTI:optab><SVE_SDI:mode>vnx4sf2)
+ (aarch64_sve_<SVE_COND_FCVTI:optab><SVE_SDI:mode>vnx2df2):
+ Merge into...
+ (*aarch64_sve_<SVE_COND_FCVTI:optab>_nonextend<SVE_HSDI:mode><SVE_F:mode>)
+ (aarch64_sve_<SVE_COND_FCVTI:optab>_extend<VNx4SI_ONLY:mode><VNx2DF_ONLY:mode>):
+ ...these new patterns.
+ (vec_unpack<su_optab>_float_<perm_hilo>_vnx4si): Update accordingly.
+ (*trunc<Vwide><SVE_SDF:mode>2): Replace with...
+ (*aarch64_sve_<SVE_COND_FCVT:optab>_trunc<SVE_SDF:mode><SVE_HSF:mode>):
+ ...this new pattern.
+ (aarch64_sve_extend<SVE_HSDF:mode><Vwide>2): Replace with...
+ (aarch64_sve_<SVE_COND_FCVT:optab>_nontrunc<SVE_HSF:mode><SVE_SDF:mode>):
+ ...this new pattern.
+ (vec_unpacks_<perm_hilo>_<mode>): Update accordingly.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64.md (UNSPEC_FLOAT_CONVERT): Delete.
+ * config/aarch64/iterators.md (UNSPEC_COND_FCVT, UNSPEC_COND_FCVTZS)
+ (UNSPEC_COND_FCVTZU, UNSPEC_COND_SCVTF, UNSPEC_COND_UCVTF): New
+ unspecs.
+ (optab, su): Handle them.
+ (SVE_COND_FCVTI, SVE_COND_ICVTF): New int iterators.
+ * config/aarch64/aarch64-sve.md
+ (<fix_trunc_optab><SVE_F:mode><v_int_equiv>2): Replace with...
+ (<SVE_COND_FCVTI:optab><SVE_F:mode><v_int_equiv>2): ...this.
+ (*<fix_trunc_optab>v16hsf<:SVE_HSDImode>2): Replace with...
+ (*<SVE_COND_FCVTI:optab>v16hsf<SVE_F:mode>2): ...this.
+ (*<fix_trunc_optab>vnx4sf<SVE_SDI:mode>2): Replace with...
+ (*<SVE_COND_FCVTI:optab>vnx4sf<SVE_SDI:mode>2): ...this.
+ (*<fix_trunc_optab>vnx2df<SVE_SDI:mode>2): Replace with...
+ (*<SVE_COND_FCVTI:optab>vnx2df<SVE_SDI:mode>2): ...this.
+ (vec_pack_<su>fix_trunc_vnx2df): Use SVE_COND_FCVTI instead of
+ FIXUORS.
+ (<FLOATUORS:optab><v_int_equiv><SVE_F:mode>2): Replace with...
+ (<SVE_COND_ICVTF:optab><v_int_equiv><SVE_F:mode>2): ...this.
+ (*<FLOATUORS:optab><SVE_HSDI:mode>vnx8hf2): Replace with...
+ (*<SVE_COND_ICVTF:optab><SVE_HSDI:mode>vnx8hf2): ...this.
+ (*<FLOATUORS:optab><SVE_SDI:mode>vnx4sf2): Replace with...
+ (*<SVE_COND_ICVTF:optab><SVE_SDI:mode>vnx4sf2): ...this.
+ (aarch64_sve_<FLOATUORS:optab><SVE_SDI:mode>vnx2df2): Replace with...
+ (aarch64_sve_<SVE_COND_ICVTF:optab><SVE_SDI:mode>vnx2df2): ...this.
+ (vec_unpack<su_optab>_float_<perm_hilo>_vnx4si): Pass a GP strictness
+ operand to aarch64_sve_<SVE_COND_ICVTF:optab><SVE_SDI:mode>vnx2df2.
+ (vec_pack_trunc_<SVE_HSF:Vwide>, *trunc<Vwide><SVE_HSF:mode>2)
+ (aarch64_sve_extend<mode><Vwide>2): Use UNSPEC_COND_FCVT instead
+ of UNSPEC_FLOAT_CONVERT.
+ (vec_unpacks_<perm_hilo>_<mode>): Pass a GP strictness operand to
+ aarch64_sve_extend<mode><Vwide>2.
+
+2019-08-14 Richard Biener <rguenther@suse.de>
+
+ PR target/91154
+ * config/i386/i386-features.c
+ (dimode_scalar_chain::compute_convert_gain): Compute and dump
+ individual instruction gain. Fix reg-reg copy GRP cost. Use
+ ix86_cost->sse_op for vector instruction costs.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/iterators.md (UNSPEC_COND_FCMUO): New unspec.
+ (cmp_op): Handle it.
+ (SVE_COND_FP_CMP): Rename to...
+ (SVE_COND_FP_CMP_I0): ...this.
+ (SVE_FP_CMP): Remove.
+ * config/aarch64/aarch64-sve.md
+ (*fcm<SVE_FP_CMP:cmp_op><SVE_F:mode>): Replace with...
+ (*fcm<SVE_COND_FP_CMP_I0:cmp_op><SVE_F:mode>): ...this new pattern,
+ using unspecs to represent the comparison.
+ (*fcmuo<SVE_F:mode>): Use UNSPEC_COND_FCMUO.
+ (*fcm<cmp_op><mode>_and_combine, *fcmuo<mode>_and_combine): Update
+ accordingly.
+ * config/aarch64/aarch64.c (aarch64_emit_sve_ptrue_op): Delete.
+ (aarch64_unspec_cond_code): Move after integer code. Handle
+ UNORDERED.
+ (aarch64_emit_sve_predicated_cond): Replace with...
+ (aarch64_emit_sve_fp_cond): ...this new function.
+ (aarch64_emit_sve_or_conds): Replace with...
+ (aarch64_emit_sve_or_fp_conds): ...this new function.
+ (aarch64_emit_sve_inverted_cond): Replace with...
+ (aarch64_emit_sve_invert_fp_cond): ...this new function.
+ (aarch64_expand_sve_vec_cmp_float): Update accordingly.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/iterators.md (SVE_HSD): New mode iterator.
+ (V_FP_EQUIV, v_fp_equiv): Handle VNx8HI and VNx8HF.
+ * config/aarch64/aarch64-sve.md (vcond<mode><v_fp_equiv>): Use
+ SVE_HSD instead of SVE_SD.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * config/aarch64/iterators.md (SVE_COND_FP_BINARY_REG): New int
+ iterator.
+ (sve_pred_fp_rhs1_operand, sve_pred_fp_rhs1_operand): New int
+ attributes.
+ * config/aarch64/aarch64-sve.md (add<SVE_F:mode>3, sub<SVE_F:mode>3)
+ (mul<SVE_F:mode>3, div<SVE_F:mode>3)
+ (<SVE_COND_FP_MAXMIN_PUBLIC:optab><SVE_F:mode>3): Merge into...
+ (<SVE_COND_FP_BINARY:optab><SVE_F:mode>3): ...this new expander.
+ (*div<SVE_F:mode>3): Generalize to...
+ (*<SVE_COND_FP_BINARY:optab><SVE_F:mode>3): ...this.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * config/aarch64/aarch64.md (SVE_RELAXED_GP, SVE_STRICT_GP): New
+ constants.
+ * config/aarch64/predicates.md (aarch64_sve_gp_strictness): New
+ predicate.
+ * config/aarch64/aarch64-protos.h (aarch64_sve_pred_dominates_p):
+ Declare.
+ * config/aarch64/aarch64.c (aarch64_sve_pred_dominates_p): New
+ function.
+ * config/aarch64/aarch64-sve.md: Add a block comment about the
+ handling of predicated FP operations.
+ (<SVE_COND_FP_UNARY:optab><SVE_F:mode>2, add<SVE_F:mode>3)
+ (sub<SVE_F:mode>3, mul<SVE_F:mode>3, div<SVE_F:mode>3)
+ (<SVE_COND_FP_MAXMIN_PUBLIC:optab><SVE_F:mode>3)
+ (<SVE_COND_FP_MAXMIN_PUBLIC:maxmin_uns><SVE_F:mode>3)
+ (<SVE_COND_FP_TERNARY:optab><SVE_F:mode>4): Add an SVE_RELAXED_GP
+ operand.
+ (cond_<SVE_COND_FP_BINARY:optab><SVE_F:mode>)
+ (cond_<SVE_COND_FP_TERNARY:optab><SVE_F:mode>): Add an SVE_STRICT_GP
+ operand.
+ (*<SVE_COND_FP_UNARY:optab><SVE_F:mode>2)
+ (*cond_<SVE_COND_FP_BINARY:optab><SVE_F:mode>_2)
+ (*cond_<SVE_COND_FP_BINARY:optab><SVE_F:mode>_3)
+ (*cond_<SVE_COND_FP_BINARY:optab><SVE_F:mode>_any)
+ (*fabd<SVE_F:mode>3, *div<SVE_F:mode>3)
+ (*<SVE_COND_FP_MAXMIN_PUBLIC:optab><SVE_F:mode>3)
+ (*<SVE_COND_FP_TERNARY:optab><SVE_F:mode>4)
+ (*cond_<SVE_COND_FP_TERNARY:optab><SVE_F:mode>_2)
+ (*cond_<SVE_COND_FP_TERNARY:optab><SVE_F:mode>_4)
+ (*cond_<SVE_COND_FP_TERNARY:optab><SVE_F:mode>_any): Match the
+ strictness operands. Use aarch64_sve_pred_dominates_p to check
+ whether the predicate on the conditional operation is suitable
+ for merging. Split patterns into the canonical equal-predicate form.
+ (*add<SVE_F:mode>3, *sub<SVE_F:mode>3, *mul<SVE_F:mode>3): Likewise.
+ Restrict the unpredicated alternatives to SVE_RELAXED_GP.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * config/aarch64/aarch64-sve.md (add<mode>3, *add<mode>3)
+ (sub<mode>3, *sub<mode>3, *fabd<mode>3, mul<mode>3, *mul<mode>3)
+ (div<mode>3, *div<mode>3): Use SVE_COND_FP_* unspecs instead of
+ rtx codes.
+ (cond_<optab><mode>, *cond_<optab><mode>_2, *cond_<optab><mode>_3)
+ (*cond_<optab><mode>_any): Add the predicate to the SVE_COND_FP_*
+ unspecs.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * config/aarch64/aarch64-sve.md (bic<mode>3): Rename to...
+ (*bic<SVE_I:mode>3): ...this. Match the form that an SVE inverse
+ actually has, rather than relying on REG_EQUAL notes.
+ Make the insn operand order match the SVE operand order.
+ (*<nlogical><PRED_ALL:mode>3): Make the insn operand order match
+ the SVE operand order.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_target_reg): New function.
+ (aarch64_emit_set_immediate): Likewise.
+ (aarch64_ptrue_reg): Build a VNx16BI constant and then bitcast it.
+ (aarch64_pfalse_reg): Likewise.
+ (aarch64_convert_sve_data_to_pred): New function.
+ (aarch64_sve_move_pred_via_while): Take an optional target register
+ and the required register mode.
+ (aarch64_expand_sve_const_pred_1): New function.
+ (aarch64_expand_sve_const_pred): Likewise.
+ (aarch64_expand_mov_immediate): Build an all-true predicate
+ if the significant bits of the immediate are all true. Use
+ aarch64_expand_sve_const_pred for all compile-time predicate constants.
+ (aarch64_mov_operand_p): Force predicate constants to be VNx16BI
+ before register allocation.
+ * config/aarch64/aarch64-sve.md (*vec_duplicate<mode>_reg): Use
+ a VNx16BI PTRUE when splitting the memory alternative.
+ (vec_duplicate<mode>): Update accordingly.
+ (*pred_cmp<cmp_op><mode>): Rename to...
+ (@aarch64_pred_cmp<cmp_op><mode>): ...this.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-protos.h (aarch64_ptrue_all): Declare.
+ * config/aarch64/aarch64.c (aarch64_ptrue_all): New function.
+ * config/aarch64/aarch64.md (UNSPEC_PTEST_PTRUE): Delete.
+ (UNSPEC_PTEST): New unspec.
+ (SVE_MAYBE_NOT_PTRUE, SVE_KNOWN_PTRUE): New constants.
+ * config/aarch64/iterators.md (data_bytes): New mode attribute.
+ * config/aarch64/predicates.md (aarch64_sve_ptrue_flag): New predicate.
+ * config/aarch64/aarch64-sve.md: Add a new section describing the
+ handling of UNSPEC_PTEST.
+ (pred_<LOGICAL:optab><PRED_ALL:mode>3): Rename to...
+ (@aarch64_pred_<LOGICAL:optab><PRED_ALL:mode>_z): ...this.
+ (ptest_ptrue<mode>): Replace with...
+ (aarch64_ptest<mode>): ...this new pattern.
+ (cbranch<mode>4): Update after above changes.
+ (*<LOGICAL:optab><PRED_ALL:mode>3_cc): Use UNSPEC_PTEST instead of
+ UNSPEC_PTEST_PTRUE.
+ (*cmp<SVE_INT_CMP:cmp_op><SVE_I:mode>_cc): Likewise.
+ (*cmp<SVE_INT_CMP:cmp_op><SVE_I:mode>_ptest): Likewise.
+ (*while_ult<GPI:mode><PRED_ALL:mode>_cc): Likewise.
+
+2019-08-14 Xiong Hu Luo <luoxhu@linux.ibm.com>
+
+ PR lto/91287
+ * builtins.c (builtin_with_linkage_p): New function.
+ * builtins.h (builtin_with_linkage_p): New function.
+ * symtab.c (write_symbol): Remove redundant assert.
+ * lto-streamer-out.c (symtab_node::output_to_lto_symbol_table_p):
+ Remove FIXME and use builtin_with_linkage_p.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR middle-end/91421
+ * tree-core.h (function_decl::function_code): Change type to
+ unsigned int.
+ * tree.h (DECL_FUNCTION_CODE): Rename old definition to...
+ (DECL_UNCHECKED_FUNCTION_CODE): ...this.
+ (DECL_BUILT_IN_CLASS): Make an rvalue macro only.
+ (DECL_FUNCTION_CODE): New function. Assert that the built-in class
+ is BUILT_IN_NORMAL.
+ (DECL_MD_FUNCTION_CODE, DECL_FE_FUNCTION_CODE): New functions.
+ (set_decl_built_in_function, copy_decl_built_in_function): Likewise.
+ (fndecl_built_in_p): Change the type of the "name" argument to
+ unsigned int.
+ * builtins.c (expand_builtin): Move DECL_FUNCTION_CODE use
+ after check for DECL_BUILT_IN_CLASS.
+ * cgraphclones.c (build_function_decl_skip_args): Use
+ set_decl_built_in_function.
+ * ipa-param-manipulation.c (ipa_modify_formal_parameters): Likewise.
+ * ipa-split.c (split_function): Likewise.
+ * langhooks.c (add_builtin_function_common): Likewise.
+ * omp-simd-clone.c (simd_clone_create): Likewise.
+ * tree-streamer-in.c (unpack_ts_function_decl_value_fields): Likewise.
+ * config/darwin.c (darwin_init_cfstring_builtins): Likewise.
+ (darwin_fold_builtin): Use DECL_MD_FUNCTION_CODE instead of
+ DECL_FUNCTION_CODE.
+ * fold-const.c (operand_equal_p): Compare DECL_UNCHECKED_FUNCTION_CODE
+ instead of DECL_FUNCTION_CODE.
+ * lto-streamer-out.c (hash_tree): Use DECL_UNCHECKED_FUNCTION_CODE
+ instead of DECL_FUNCTION_CODE.
+ * tree-streamer-out.c (pack_ts_function_decl_value_fields): Likewise.
+ * print-tree.c (print_node): Use DECL_MD_FUNCTION_CODE when
+ printing DECL_BUILT_IN_MD. Handle DECL_BUILT_IN_FRONTEND.
+ * config/aarch64/aarch64-builtins.c (aarch64_expand_builtin)
+ (aarch64_fold_builtin, aarch64_gimple_fold_builtin): Use
+ DECL_MD_FUNCTION_CODE instead of DECL_FUNCTION_CODE.
+ * config/aarch64/aarch64.c (aarch64_builtin_reciprocal): Likewise.
+ * config/alpha/alpha.c (alpha_expand_builtin, alpha_fold_builtin):
+ (alpha_gimple_fold_builtin): Likewise.
+ * config/arc/arc.c (arc_expand_builtin): Likewise.
+ * config/arm/arm-builtins.c (arm_expand_builtin): Likewise.
+ * config/avr/avr-c.c (avr_resolve_overloaded_builtin): Likewise.
+ * config/avr/avr.c (avr_expand_builtin, avr_fold_builtin): Likewise.
+ * config/bfin/bfin.c (bfin_expand_builtin): Likewise.
+ * config/c6x/c6x.c (c6x_expand_builtin): Likewise.
+ * config/frv/frv.c (frv_expand_builtin): Likewise.
+ * config/gcn/gcn.c (gcn_expand_builtin_1): Likewise.
+ (gcn_expand_builtin): Likewise.
+ * config/i386/i386-builtins.c (ix86_builtin_reciprocal): Likewise.
+ (fold_builtin_cpu): Likewise.
+ * config/i386/i386-expand.c (ix86_expand_builtin): Likewise.
+ * config/i386/i386.c (ix86_fold_builtin): Likewise.
+ (ix86_gimple_fold_builtin): Likewise.
+ * config/ia64/ia64.c (ia64_fold_builtin): Likewise.
+ (ia64_expand_builtin): Likewise.
+ * config/iq2000/iq2000.c (iq2000_expand_builtin): Likewise.
+ * config/mips/mips.c (mips_expand_builtin): Likewise.
+ * config/msp430/msp430.c (msp430_expand_builtin): Likewise.
+ * config/nds32/nds32-intrinsic.c (nds32_expand_builtin_impl): Likewise.
+ * config/nios2/nios2.c (nios2_expand_builtin): Likewise.
+ * config/nvptx/nvptx.c (nvptx_expand_builtin): Likewise.
+ * config/pa/pa.c (pa_expand_builtin): Likewise.
+ * config/pru/pru.c (pru_expand_builtin): Likewise.
+ * config/riscv/riscv-builtins.c (riscv_expand_builtin): Likewise.
+ * config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin):
+ Likewise.
+ * config/rs6000/rs6000-call.c (htm_expand_builtin): Likewise.
+ (altivec_expand_dst_builtin, altivec_expand_builtin): Likewise.
+ (rs6000_gimple_fold_builtin, rs6000_expand_builtin): Likewise.
+ * config/rs6000/rs6000.c (rs6000_builtin_md_vectorized_function)
+ (rs6000_builtin_reciprocal): Likewise.
+ * config/rx/rx.c (rx_expand_builtin): Likewise.
+ * config/s390/s390-c.c (s390_resolve_overloaded_builtin): Likewise.
+ * config/s390/s390.c (s390_expand_builtin): Likewise.
+ * config/sh/sh.c (sh_expand_builtin): Likewise.
+ * config/sparc/sparc.c (sparc_expand_builtin): Likewise.
+ (sparc_fold_builtin): Likewise.
+ * config/spu/spu-c.c (spu_resolve_overloaded_builtin): Likewise.
+ * config/spu/spu.c (spu_expand_builtin): Likewise.
+ * config/stormy16/stormy16.c (xstormy16_expand_builtin): Likewise.
+ * config/tilegx/tilegx.c (tilegx_expand_builtin): Likewise.
+ * config/tilepro/tilepro.c (tilepro_expand_builtin): Likewise.
+ * config/xtensa/xtensa.c (xtensa_fold_builtin): Likewise.
+ (xtensa_expand_builtin): Likewise.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR middle-end/91421
+ * attribs.c (decl_attributes): Check the DECL_BUILT_IN_CLASS
+ before the DECL_FUNCTION_CODE.
+ * calls.c (maybe_warn_alloc_args_overflow): Use fndecl_built_in_p
+ to check for a BUILT_IN_ALLOCA call.
+ * ipa-cp.c (ipa_get_indirect_edge_target_1): Likewise for
+ BUILT_IN_UNREACHABLE. Don't check for a FUNCTION_TYPE.
+ * ipa-devirt.c (possible_polymorphic_call_target_p): Likewise.
+ * ipa-prop.c (try_make_edge_direct_virtual_call): Likewise.
+ * gimple-ssa-isolate-paths.c (is_addr_local): Check specifically
+ for BUILT_IN_NORMAL functions.
+ * trans-mem.c (expand_block_edges): Use gimple_call_builtin_p to
+ test for BUILT_IN_TM_ABORT.
+ * tree-ssa-ccp.c (optimize_stack_restore): Use fndecl_built_in_p
+ to check for a BUILT_IN_STACK_RESTORE call.
+ (optimize_stdarg_builtin): Remove redundant check for GIMPLE_CALL.
+ * tree-ssa-threadedge.c
+ (record_temporary_equivalences_from_stmts_at_dest): Check for a
+ BUILT_IN_NORMAL decl before checking its DECL_FUNCTION_CODE.
+ * tree-vect-patterns.c (vect_recog_pow_pattern): Use a positive
+ test for a BUILT_IN_NORMAL call instead of a negative test for
+ an internal function call.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ * tree.h (build_vector_a_then_b): Declare.
+ * tree.c (build_vector_a_then_b): New function.
+ * fold-const-call.c (fold_while_ult): Likewise.
+ (fold_const_call): Use it to handle IFN_WHILE_ULT.
+ * config/aarch64/aarch64-protos.h (AARCH64_FOR_SVPATTERN): New macro.
+ (aarch64_svpattern): New enum.
+ * config/aarch64/aarch64-sve.md (mov<PRED_ALL:mode>): Pass
+ constants through aarch64_expand_mov_immediate.
+ (*aarch64_sve_mov<PRED_ALL:mode>): Use aarch64_mov_operand rather
+ than general_operand as the predicate for operand 1.
+ (while_ult<GPI:mode><PRED_ALL:mode>): Add a '@' marker.
+ * config/aarch64/aarch64.c (simd_immediate_info::PTRUE): New
+ insn_type.
+ (simd_immediate_info::simd_immediate_info): New overload that
+ takes a scalar_int_mode and an svpattern.
+ (simd_immediate_info::u): Add a "pattern" field.
+ (svpattern_token): New function.
+ (aarch64_get_sve_pred_bits, aarch64_widest_sve_pred_elt_size)
+ (aarch64_partial_ptrue_length, aarch64_svpattern_for_vl)
+ (aarch64_sve_move_pred_via_while): New functions.
+ (aarch64_expand_mov_immediate): Try using
+ aarch64_sve_move_pred_via_while for predicates that contain N ones
+ followed by M zeros but that do not correspond to a VLnnn pattern.
+ (aarch64_sve_pred_valid_immediate): New function.
+ (aarch64_simd_valid_immediate): Use it instead of dealing directly
+ with PTRUE and PFALSE.
+ (aarch64_output_sve_mov_immediate): Handle new simd_immediate_info
+ forms.
+
+2019-08-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ * config/darwin.c (machopic_indirect_call_target): Rename symbol stub
+ flag.
+ (darwin_override_options): Likewise.
+ * config/darwin.h: Likewise.
+ * config/darwin.opt: Likewise.
+ * config/i386/i386.c (output_pic_addr_const): Likewise.
+ * config/rs6000/darwin.h: Likewise.
+ * config/rs6000/rs6000.c (rs6000_call_darwin_1): Likewise.
+ * config/i386/darwin.h (TARGET_MACHO_PICSYM_STUBS): Rename to ...
+ ... this TARGET_MACHO_SYMBOL_STUBS.
+ (FUNCTION_PROFILER):Likewise.
+ * config/i386/i386.h: Likewise.
+
+2019-08-13 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386-expand.c (ix86_expand_vector_extract)
+ <case E_V2SImode>: Use vec_extr path for
+ TARGET_MMX_WITH_SSE && TARGET_SSE4_1.
+ <case E_V8QImode>: Ditto.
+ * config/i386/mmx.md (*mmx_pextrw_zext): Rename from mmx_pextrw.
+ Use SWI48 mode iterator. Use %k to output operand 0.
+ (*mmx_pextrw): New insn pattern.
+ (*mmx_pextrb): Ditto.
+ (*mmx_pextrb_zext): Ditto.
+
+2019-08-13 Jonathan Wakely <jwakely@redhat.com>
+
+ * target.def (libc_has_function, libc_has_fast_function): Improve
+ documentation strings.
+ * doc/tm.texi: Regenerate.
+
+2019-08-13 Caroline Tice <cmtice@google.com>
+
+ PR other/91396
+ * config/gnu-user.h (GNU_USER_TARGET_ENDFILE_SPEC): Only add the
+ vtv_end.o or vtv_end_preinit.o files if !static.
+
+2019-08-13 Olivier Hainque <hainque@adacore.com>
+
+ * rtl.h (tablejump_casesi_pattern): Move declaration to proper spot.
+
+2019-08-13 Olivier Hainque <hainque@adacore.com>
+
+ * rtlanal.c (tablejump_casesi_pattern): New function, to
+ determine if a tablejump insn is a casesi dispatcher. Extracted
+ from patch_jump_insn.
+ * rtl.h (tablejump_casesi_pattern): Declare.
+ * cfgrtl.c (patch_jump_insn): Use it.
+ * dwarf2cfi.c (create_trace_edges): Use it.
+
+2019-08-13 Wilco Dijkstra <wdijkstr@arm.com>
+
+ PR target/81800
+ * gcc/config/aarch64/aarch64.md (lrint): Disable lrint pattern if GPF
+ operand is larger than a long int.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ * machmode.h (opt_mode::else_mode): New function.
+ (opt_mode::else_blk): Use it.
+ * config/aarch64/aarch64-protos.h (aarch64_vq_mode): Declare.
+ (aarch64_full_sve_mode, aarch64_sve_ld1rq_operand_p): Likewise.
+ (aarch64_gen_stepped_int_parallel): Likewise.
+ (aarch64_stepped_int_parallel_p): Likewise.
+ (aarch64_expand_mov_immediate): Remove the optional gen_vec_duplicate
+ argument.
+ * config/aarch64/aarch64.c
+ (aarch64_expand_sve_widened_duplicate): Delete.
+ (aarch64_expand_sve_dupq, aarch64_expand_sve_ld1rq): New functions.
+ (aarch64_expand_sve_const_vector): Rewrite to handle more cases.
+ (aarch64_expand_mov_immediate): Remove the optional gen_vec_duplicate
+ argument. Use early returns in the !CONST_INT_P handling.
+ Pass all SVE data vectors to aarch64_expand_sve_const_vector rather
+ than handling some inline.
+ (aarch64_full_sve_mode, aarch64_vq_mode): New functions, split out
+ from...
+ (aarch64_simd_container_mode): ...here.
+ (aarch64_gen_stepped_int_parallel, aarch64_stepped_int_parallel_p)
+ (aarch64_sve_ld1rq_operand_p): New functions.
+ * config/aarch64/predicates.md (descending_int_parallel)
+ (aarch64_sve_ld1rq_operand): New predicates.
+ * config/aarch64/constraints.md (UtQ): New constraint.
+ * config/aarch64/aarch64.md (UNSPEC_REINTERPRET): New unspec.
+ * config/aarch64/aarch64-sve.md (mov<SVE_ALL:mode>): Remove the
+ gen_vec_duplicate from call to aarch64_expand_mov_immediate.
+ (@aarch64_sve_reinterpret<mode>): New expander.
+ (*aarch64_sve_reinterpret<mode>): New pattern.
+ (@aarch64_vec_duplicate_vq<mode>_le): New pattern.
+ (@aarch64_vec_duplicate_vq<mode>_be): Likewise.
+ (*sve_ld1rq<Vesize>): Replace with...
+ (@aarch64_sve_ld1rq<mode>): ...this new pattern.
+
+2019-08-13 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * config/aarch64/aarch64.c (generic_tunings): Set function alignment to
+ 16:12.
+
+2019-08-13 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config/msp430/driver-msp430.c (msp430_set_driver_var): New.
+ * config/msp430/msp430-devices.c (canonicalize_path_dirsep): New.
+ (msp430_check_path_for_devices): New.
+ (parse_devices_csv_1): New.
+ (parse_devices_csv): New.
+ (msp430_extract_mcu_data): Try to find devices.csv and search for the
+ MCU data in devices.csv before using the hard-coded data.
+ Warn if devices.csv isn't found and the MCU wasn't found in the
+ hard-coded data either.
+ * config/msp430/msp430.h (DRIVER_SELF_SPECS): Call
+ msp430_set_driver_var for -mno-warn-devices-csv and -mdevices-csv-loc.
+ Search for devices.csv on -I and -L paths.
+ (EXTRA_SPEC_FUNCTIONS): Add msp430_check_path_for_devices and
+ msp430_set_driver_var.
+ * config/msp430/msp430.opt: Add -mwarn-devices-csv and
+ -mdevices-csv-loc=.
+ * doc/invoke.texi (-mmcu): Document that -I and -L paths are
+ searched for devices.csv.
+ (mwarn-devices-csv): Document option.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-protos.h (aarch64_output_ptrue): Delete.
+ * config/aarch64/aarch64-sve.md (*aarch64_sve_mov<PRED_ALL:mode>):
+ Use a single Dn alternative instead of separate Dz and Dm
+ alternatives. Use aarch64_output_sve_move_immediate.
+ * config/aarch64/aarch64.c (aarch64_sve_element_int_mode): New
+ function.
+ (aarch64_simd_valid_immediate): Fill in the simd_immediate_info
+ for predicates too.
+ (aarch64_output_sve_mov_immediate): Handle predicate modes.
+ (aarch64_output_ptrue): Delete.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64.c (simd_immediate_info::insn_type): Add
+ INDEX.
+ (simd_immediate_info::value, simd_immediate_info::step)
+ (simd_immediate_info::modifier, simd_immediate_info::shift): Replace
+ with...
+ (simd_immediate_info::u): ...this new union.
+ (simd_immediate_info::simd_immediate_info): Update accordingly.
+ (aarch64_output_simd_mov_immediate): Likewise.
+ (aarch64_output_sve_mov_immediate): Likewise.
+
+2019-08-13 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config.gcc (msp430*-*-*): Add msp430-devices.o to extra_objs and
+ extra_gcc_objs.
+ * config/msp430/driver-msp430.c: Remove msp430_mcu_data.
+ (msp430_select_cpu): New spec function.
+ (msp430_select_hwmult_lib): Use msp430_extract_mcu_data to extract
+ MCU data.
+ * config/msp430/msp430-devices.c: New file.
+ * config/msp430/msp430-devices.h: New file.
+ * config/msp430/msp430.c: Remove msp430_mcu_data.
+ (msp430_option_override): Use msp430_extract_mcu_data to extract
+ MCU data.
+ (msp430_use_f5_series_hwmult): Likewise.
+ (use_32bit_hwmult): Likewise.
+ (msp430_no_hwmult): Likewise.
+ * config/msp430/msp430.h (ASM_SPEC): Don't pass -mmcu to the
+ assembler.
+ (DRIVER_SELF_SPECS): Call msp430_select_cpu if -mmcu is used without
+ and -mcpu option.
+ (EXTRA_SPEC_FUNCTIONS): Add msp430_select_cpu.
+ * config/msp430/t-msp430: Add rule to build msp430-devices.o.
+ Remove hard-coded MCU multilib data.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64.c (aarch64_classify_vector_mode): Switch
+ based on the mode instead of testing properties of it.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ * doc/md.texi: Document the x and y constraints for AArch64.
+ * config/aarch64/aarch64.h (FP_LO8_REGNUM_P): New macro.
+ (FP_LO8_REGS): New reg_class.
+ (REG_CLASS_NAMES, REG_CLASS_CONTENTS): Add an entry for FP_LO8_REGS.
+ * config/aarch64/aarch64.c (aarch64_hard_regno_nregs)
+ (aarch64_regno_regclass, aarch64_class_max_nregs): Handle FP_LO8_REGS.
+ * config/aarch64/predicates.md (aarch64_simd_register): Use
+ FP_REGNUM_P instead of checking the classes manually.
+ * config/aarch64/constraints.md (y): New constraint.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/iterators.md (perm_insn): Include the "1"/"2" suffix.
+ (perm_hilo): Remove UNSPEC_ZIP*, UNSEPC_TRN* and UNSPEC_UZP*.
+ * config/aarch64/aarch64-simd.md
+ (aarch64_<PERMUTE:perm_insn><PERMUTE:perm_hilo><mode>): Rename to..
+ (aarch64_<PERMUTE:perm_insn><mode>): ...this and remove perm_hilo
+ from the asm template.
+ * config/aarch64/aarch64-sve.md
+ (aarch64_<perm_insn><perm_hilo><PRED_ALL:mode>): Rename to..
+ (aarch64_<perm_insn><PRED_ALL:mode>): ...this and remove perm_hilo
+ from the asm template.
+ (aarch64_<perm_insn><perm_hilo><SVE_ALL:mode>): Rename to..
+ (aarch64_<perm_insn><SVE_ALL:mode>): ...this and remove perm_hilo
+ from the asm template.
+ * config/aarch64/aarch64-simd-builtins.def: Update comment.
+
+2019-08-13 Martin Liska <mliska@suse.cz>
+
+ * value-prof.c (gimple_ic_transform): Add new line.
+ Print details with MSG_NOTE.
+
+2019-08-13 Martin Liska <mliska@suse.cz>
+
+ * doc/invoke.texi: Document automatic detection of jobserver.
+ * lto-wrapper.c (run_gcc): Detect jobserver always.
+
+2019-08-13 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386-expand.c (ix86_expand_vector_set)
+ <case E_V2SImode>: Use vec_merge path for
+ TARGET_MMX_WITH_SSE && TARGET_SSE4_1.
+ <case E_V8QImode>: Ditto.
+ * config/i386/mmx.md (*mmx_pinsrd): New insn pattern.
+ (*mmx_pinsrb): Ditto.
+
+2019-08-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/83250
+ PR target/91340
+ * config/i386/avxintrin.h (_mm256_zextpd128_pd256,
+ _mm256_zextps128_ps256, _mm256_zextsi128_si256): New intrinsics.
+ * config/i386/avx512fintrin.h (_mm512_zextpd128_pd512,
+ _mm512_zextps128_ps512, _mm512_zextsi128_si512, _mm512_zextpd256_pd512,
+ _mm512_zextps256_ps512, _mm512_zextsi256_si512): Likewise.
+
+2019-08-12 Richard Biener <rguenther@suse.de>
+
+ PR lto/91375
+ * tree.c (free_lang_data_in_type): Do not free TYPE_BINFO dependent on
+ flag_devirtualize.
+
+2019-08-12 Richard Biener <rguenther@suse.de>
+
+ PR driver/91130
+ * lto-wrapper.c (get_options_from_collect_gcc_options): Remove
+ lang_mask option, always use CL_DRIVER.
+ (get_options_from_collect_gcc_options): Adjust.
+ (find_and_merge_options): Likewise.
+ (run_gcc): Likewise.
+
+2019-08-12 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * ipa-predicate.c (add_condition): Restore inverted test.
+
+2019-08-10 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-core.h (enum omp_clause_code): Add OMP_CLAUSE_DEVICE_TYPE.
+ (enum omp_clause_device_type_kind): New enum.
+ (struct tree_omp_clause): Add subcode.device_type_kind.
+ * tree.h (OMP_CLAUSE_DEVICE_TYPE_KIND): Define.
+ * tree.c (omp_clause_num_ops, omp_clause_code_name): Add entries
+ for device_type clause.
+ (walk_tree_1): Handle OMP_CLAUSE_DEVICE_TYPE.
+ * tree-pretty-print.c (dump_omp_clause): Likewise.
+
+ PR target/91408
+ * config/i386/mmx.md (usadv8qi): Use register_operand instead of
+ vector_operand.
+
+2019-09-09 Vladimir Makarov <vmakarov@redhat.com>
+
+ * reload1.c (finish_spills): Do not check ira_conflicts_p when
+ handling spilled pseudos.
+
+2019-09-09 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/91386
+ * config/aarch64/aarch64.c (aarch64_gen_adjusted_ldpstp): Use copy_rtx
+ to preserve the contents of the original insns.
+
+2019-08-09 Richard Earnshaw <rearnsha@arm.com>
+
+ * config/arm/arm.md (addsi3_compare_op1): Add 16-bit thumb-2 variants.
+ (addsi3_compare_op2): Likewise.
+
+2019-08-09 Martin Liska <mliska@suse.cz>
+
+ * alias.c (alias_ptr_types_compatible_p): Strengten
+ type comparison in LTO mode.
+
+2019-08-09 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR middle-end/90313
+ * tree-tailcall.c (find_tail_calls): Reject calls that might
+ read from an escaped RESULT_DECL.
+
+2019-08-09 Martin Liska <mliska@suse.cz>
+
+ * doc/invoke.texi: Document the option value.
+ * lto-wrapper.c (run_gcc): Set auto_parallel
+ only with -flto=auto.
+
+2019-08-09 Martin Liska <mliska@suse.cz>
+
+ * opts.c (common_handle_option): Error for an invalid argument
+ to -flto=.
+
+2019-08-09 Martin Liska <mliska@suse.cz>
+
+ * ipa-icf.c (sem_function::merge): Define AUTO_DUMP_SCOPE and
+ use dump_printf to report optimization.
+ (sem_variable::merge): Likwise.
+ (sem_item_optimizer::merge_classes): Use dump_printf to report
+ ICF hits.
+
+2019-08-09 Martin Liska <mliska@suse.cz>
+
+ * value-prof.c (gimple_divmod_fixed_value_transform):
+ Use dump_printf_loc.
+ (gimple_mod_pow2_value_transform): Likewise.
+ (gimple_mod_subtract_transform): Likewise.
+ (init_node_map): Likewise.
+ (gimple_ic_transform): Likewise.
+ (gimple_stringops_transform): Likewise.
+
+2019-08-08 Mihailo Stojanovic <mistojanovic@wavecomp.com>
+
+ * doc/extend.texi: Add const qualifier to ld intrinsics.
+
+2019-08-08 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/dfp.md (D64_D128): Rename to ...
+ (DDTD): ... this, throughout.
+ (dfp_suffix): Rename to ...
+ (q): ... this, throughout.
+
+2019-08-08 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/dfp.md (D64_D128): Move earlier in the file.
+ (dfp_suffix): Ditto.
+ (adddd3, addtd3): Merge to ...
+ (add<mode>3 for D64_D128): ... this.
+ (subdd3, subtd3): Merge to ...
+ (sub<mode>3 for D64_D128): ... this.
+ (muldd3, multd3): Merge to ...
+ (mul<mode>3 for D64_D128): ... this.
+ (divdd3, divtd3): Merge to ...
+ (div<mode>3 for D64_D128): ... this.
+ (*cmpdd_internal1, *cmptd_internal1): Merge to ...
+ (*cmp<mode>_internal1 for D64_D128): ... this.
+ (ftruncdd2, ftrunctd2): Merge to ...
+ (ftrunc<mode>2 for D64_D128): ... this.
+ (fixdddi2, fixtddi2): Merge to ...
+ (fix<mode>di2 for D64_D128): ... this.
+
+2019-08-08 Jim Wilson <jimw@sifive.com>
+
+ PR target/91229
+ * config/riscv/riscv.c (riscv_flatten_aggregate_field): New arg
+ ignore_zero_width_bit_field_p. Skip zero size bitfields when true.
+ Pass into recursive call.
+ (riscv_flatten_aggregate_argument): New arg. Pass to
+ riscv_flatten_aggregate_field.
+ (riscv_pass_aggregate_in_fpr_pair_p): New local warned. Call
+ riscv_flatten_aggregate_argument twice, with false and true as last
+ arg. Process result twice. Compare results and warn if different.
+ (riscv_pass_aggregate_in_fpr_and_gpr_p): Likewise.
+
+2019-08-08 Martin Liska <mliska@suse.cz>
+
+ PR bootstrap/91352
+ * gcc.c (driver::detect_jobserver): Use is_valid_fd.
+ * lto-wrapper.c (jobserver_active_p): Likewise.
+
+2019-08-08 Martin Liska <mliska@suse.cz>
+
+ * cgraphclones.c (set_new_clone_decl_and_node_flags): Drop
+ IS_OPERATOR_NEW and IS_OPERATOR_DELETE.
+ (create_version_clone_with_body): Likewise.
+
+2019-08-08 Jakub Jelinek <jakub@redhat.com>
+
+ * gimplify.c (omp_add_variable): Use GOVD_PRIVATE | GOVD_EXPLICIT
+ for VLA helper variables on target data even if not GOVD_FIRSTPRIVATE.
+ (gimplify_scan_omp_clauses): For OMP_CLAUSE_USE_DEVICE_* use just
+ GOVD_EXPLICIT flags.
+ (gimplify_omp_workshare): For OMP_TARGET_DATA move all
+ OMP_CLAUSE_USE_DEVICE_* clauses to the end of clauses chain.
+ * omp-low.c (scan_sharing_clauses): For OMP_CLAUSE_USE_DEVICE_*
+ call install_var_field with mask 11 instead of 3.
+ (lower_omp_target): For OMP_CLAUSE_USE_DEVICE_* use pass
+ (splay_tree_key) &DECL_UID (var) to build_sender_ref instead of var.
+
+2019-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/constraints.md (Z): Handle floating-point zeros too.
+ * config/aarch64/predicates.md (aarch64_reg_or_zero): Likewise.
+
+2019-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md (vec_shl_insert_<mode>): Add
+ MOVPRFX alternatives. Make the GPR alternatives more expensive
+ than the FPR ones.
+
+2019-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md (fold_extract_last_<mode>):
+ Disparage the GPR alternative relative to the FPR one.
+ Fix handling of 8-bit and 16-bit FPR values.
+
+2019-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/iterators.md (BITWISEV): Delete.
+ (SVE_INT_REDUCTION, SVE_FP_REDUCTION): New int iterators.
+ (optab): Handle UNSPEC_UMAXV, UNSPEC_UMINV, UNSPEC_SMAXV,
+ UNSPEC_SMINV, UNSPEC_FADDV, UNSPEC_FMAXNMV, UNSPEC_FMAXV,
+ UNSPEC_FMINNMV, UNSPEC_FMINV.
+ (bit_reduc_op): Delete.
+ (sve_int_op): New int attribute.
+ (sve_fp_op): Handle UNSPEC_FADDV, UNSPEC_FMAXNMV, UNSPEC_FMAXV,
+ UNSPEC_FMINNMV, UNSPEC_FMINV.
+ * config/aarch64/aarch64-sve.md
+ (reduc_<MAXMINV:maxmin_uns>_scal_<SVE_I:mode>)
+ (*reduc_<MAXMINV:maxmin_uns>_scal_<SVE_I:mode>)
+ (reduc_<BITWISEV:optab>_scal_<SVE_I:mode>)
+ (*reduc_<BITWISEV:optab>_scal_<SVE_I:mode>): Merge into...
+ (reduc_<SVE_INT_REDUCTION:optab>_scal_<SVE_I:mode>)
+ (*reduc_<SVE_INT_REDUCTION:optab>_scal_<SVE_I:mode>): ...these
+ new patterns.
+ (reduc_plus_scal_<SVE_F:mode>, *reduc_plus_scal_<SVE_I:mode>)
+ (reduc_<FMAXMINV:optab>_scal_<SVE_F:mode>)
+ (*reduc_<FMAXMINV:optab>_scal_<SVE_F:mode>): Merge into...
+ (reduc_<SVE_FP_REDUCTION:optab>_scal_<SVE_F:mode>)
+ (*reduc_<SVE_FP_REDUCTION:optab>_scal_<SVE_F:mode>): ...these
+ new patterns.
+
+2019-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md (fma<mode>4, *fma<mode>4)
+ (fnma<mode>4, *fnma<mode>4, fnms<mode>4, *fnms<mode>4)
+ (fms<mode>4, *fms<mode>4): Replace with...
+ (<SVE_COND_FP_TERNARY:optab><SVE_F:mode>4)
+ (*<SVE_COND_FP_TERNARY:optab><SVE_F:mode>4): ...these new patterns.
+ Use unspecs instead of rtx codes.
+ (cond_<optab><mode>, *cond_<optab><mode>_2, *cond_<optab><mode>_4)
+ (*cond_<optab><mode>_any): Add the predicate to SVE_COND_FP_TERNARY.
+
+2019-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/iterators.md (SVE_COND_FP_MAXMIN_PUBLIC): New
+ int iterator.
+ (maxmin_uns_op): Handle UNSPEC_COND_FMAXNM and UNSPEC_COND_FMINNM.
+ * config/aarch64/aarch64-sve.md
+ (<FMAXMIN:su><FMAXMIN:maxmin><SVE_F:mode>3): Rename to...
+ (<SVE_COND_FP_MAXMIN_PUBLIC:optab><SVE_F:mode>3): ...this and
+ use a single unspec for the rhs.
+ (*<su><maxmin><mode>3): Delete.
+ (<maxmin_uns><SVE_F:mode>3): Use a single unspec for the rhs.
+
+2019-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/iterators.md (UNSPEC_COND_FABS, UNSPEC_COND_FNEG)
+ (UNSPEC_COND_FRINTA, UNSPEC_COND_FRINTI, UNSPEC_COND_FRINTM)
+ (UNSPEC_COND_FRINTN, UNSPEC_COND_FRINTP, UNSPEC_COND_FRINTX)
+ (UNSPEC_COND_FRINTZ, UNSPEC_COND_FSQRT): New unspecs.
+ (optab, sve_fp_op): Handle them.
+ (SVE_FP_UNARY): Delete.
+ (optab): Remove sqrt entry.
+ (sve_fp_op): Remove neg, abs and sqrt entries.
+ (SVE_COND_FP_UNARY): New int iterator.
+ * config/aarch64/aarch64-sve.md (<frint_pattern><mode>2)
+ (*<frint_pattern><mode>2): Delete.
+ (<SVE_FP_UNARY:optab><SVE_F:mode>2): Replace with...
+ (<SVE_COND_FP_UNARY:optab><SVE_F:mode>2): ...this.
+ (*<SVE_FP_UNARY:optab><SVE_F:mode>2): Replace with...
+ (*<SVE_COND_FP_UNARY:optab><SVE_F:mode>2): ...this.
+
+2019-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md (*pred_fold_left_plus_<mode>): Delete.
+
+2019-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/iterators.md (UNSPEC_COND_ADD): Rename to...
+ (UNSPEC_COND_FADD): ...this.
+ (UNSPEC_COND_SUB): Rename to...
+ (UNSPEC_COND_FSUB): ...this.
+ (UNSPEC_COND_MUL): Rename to...
+ (UNSPEC_COND_FMUL): ...this.
+ (UNSPEC_COND_DIV): Rename to...
+ (UNSPEC_COND_FDIV): ...this.
+ (UNSPEC_COND_MAX): Rename to...
+ (UNSPEC_COND_FMAXNM): ...this.
+ (UNSPEC_COND_MIN): Rename to...
+ (UNSPEC_COND_FMINNM): ...this.
+ (UNSPEC_COND_LT): Rename to...
+ (UNSPEC_COND_FCMLT): ...this.
+ (UNSPEC_COND_LE): Rename to...
+ (UNSPEC_COND_FCMLE): ...this.
+ (UNSPEC_COND_EQ): Rename to...
+ (UNSPEC_COND_FCMEQ): ...this.
+ (UNSPEC_COND_NE): Rename to...
+ (UNSPEC_COND_FCMNE): ...this.
+ (UNSPEC_COND_GE): Rename to...
+ (UNSPEC_COND_FCMGE): ...this.
+ (UNSPEC_COND_GT): Rename to...
+ (UNSPEC_COND_FCMGT): ...this.
+ (SVE_COND_FP_BINARY, SVE_COND_FP_CMP, optab, cmp_op, sve_fp_op)
+ (sve_fp_op_rev): Update accordingly.
+ * config/aarch64/aarch64.c (aarch64_unspec_cond_code): Likewise.
+
+2019-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/aarch64-sve.md: Reorganize contents and add
+ banner comments.
+ * config/aarch64/check-sve-md.awk: New file.
+ * config/aarch64/t-aarch64 (s-check-sve-md): New rule.
+ (insn-conditions.md): Depend on it.
+
+2019-08-07 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/91385
+ * config/i386/sse.md (*negsi2_1_zext): Simplify insn pattern.
+ (*negsi2_cmpz_zext): Ditto.
+
+2019-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/aarch64/iterators.md (commutative): Remove.
+
+2019-08-07 Richard Earnshaw <rearnsha@arm.com>
+
+ PR driver/91130
+ * lto-wrapper.c (find_and_merge_options): Use CL_DRIVER when
+ processing COLLECT_GCC_OPTIONS.
+ (run_gcc): Likewise.
+
+2019-08-07 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR tree-optimization/91109
+ * lra-remat.c (update_scratch_ops): Remove assignment of the
+ hard register.
+
+2019-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * data-streamer.h (streamer_write_poly_uint64): Declare.
+ (streamer_read_poly_uint64): Likewise.
+ * data-streamer-in.c (streamer_read_poly_uint64): New function.
+ * data-streamer-out.c (streamer_write_poly_uint64): Likewise.
+ * ipa-predicate.h (condition::size): Turn into a poly_int64.
+ (add_condition): Take a poly_int64 size.
+ * ipa-predicate.c (add_condition): Likewise.
+ * ipa-prop.h (ipa_load_from_parm_agg): Take a poly_int64 size pointer.
+ * ipa-prop.c (ipa_load_from_parm_agg): Likewise.
+ (ipcp_modif_dom_walker::before_dom_children): Update accordingly.
+ * ipa-fnsummary.c (evaluate_conditions_for_known_args): Handle
+ condition::size as a poly_int64.
+ (unmodified_parm_1): Take a poly_int64 size pointer.
+ (unmodified_parm): Likewise.
+ (unmodified_parm_or_parm_agg_item): Likewise.
+ (set_cond_stmt_execution_predicate): Update accordingly.
+ (set_switch_stmt_execution_predicate): Likewise.
+ (will_be_nonconstant_expr_predicate): Likewise.
+ (will_be_nonconstant_predicate): Likewise.
+ (inline_read_section): Stream condition::size as a poly_int.
+ (ipa_fn_summary_write): Likewise.
+
+2019-08-07 Martin Liska <mliska@suse.cz>
+
+ * fold-const.c (twoval_comparison_p): Replace int
+ with bool as a return type.
+ (simple_operand_p): Likewise.
+ (operand_equal_p): Replace int with bool as a return type.
+ * fold-const.h (operand_equal_p): Likewise.
+
+2019-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-core.h (enum omp_clause_code): Adjust OMP_CLAUSE_USE_DEVICE_PTR
+ OpenMP description. Add OMP_CLAUSE_USE_DEVICE_ADDR clause.
+ * tree.c (omp_clause_num_ops, omp_clause_code_name): Add entries
+ for OMP_CLAUSE_USE_DEVICE_ADDR clause.
+ (walk_tree_1): Handle OMP_CLAUSE_USE_DEVICE_ADDR.
+ * tree-pretty-print.c (dump_omp_clause): Likewise.
+ * tree-nested.c (convert_nonlocal_omp_clauses,
+ convert_local_omp_clauses): Likewise.
+ * gimplify.c (gimplify_scan_omp_clauses, gimplify_adjust_omp_clauses):
+ Likewise.
+ * omp-low.c (scan_sharing_clauses, lower_omp_target): Likewise.
+ Treat OMP_CLAUSE_USE_DEVICE_ADDR like OMP_CLAUSE_USE_DEVICE_PTR
+ clause with array or reference to array types, no matter what type
+ except for reference it has.
+
+2019-08-07 Kewen Lin <linkw@gcc.gnu.org>
+
+ * config/rs6000/vector.md (vrotr<mode>3): New define_expand.
+
+2019-08-07 Kito Cheng <kito.cheng@sifive.com>
+
+ * config/riscv/multilib-generator: (canonical_order): Add 'g'.
+ (arch_canonicalize): Support rv32g and rv64g and fix error
+ handling.
+
+2019-08-06 Martin Liska <mliska@suse.cz>
+
+ * cgraph.c (cgraph_node::dump): Dump DECL_IS_OPERATOR_NEW_P
+ and DECL_IS_OPERATOR_DELETE_P.
+
+2019-08-06 Jakub Jelinek <jakub@redhat.com>
+
+ * tree.h (OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV): Rename to ...
+ (OMP_CLAUSE_LASTPRIVATE_LOOP_IV): ... this. Adjust comment.
+ * gimplify.c (gimple_add_tmp_var): In SIMD contexts, turn addressable
+ new vars into GOVD_PRIVATE rather than GOVD_LOCAL.
+ (gimplify_omp_for): Don't do C++ random access iterator clause
+ adjustments on combined constructs from OMP_LOOP. For OMP_LOOP,
+ don't predetermine the artificial iterator in case of C++ random
+ access iterators as lastprivate, but private. For OMP_LOOP, force
+ bind expr around simd body and force for_pre_body before the
+ construct. Use OMP_CLAUSE_LASTPRIVATE_LOOP_IV instead of
+ OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV.
+ (gimplify_omp_loop): Add firstprivate clauses on OMP_PARALLEL for
+ diff var of C++ random access iterators. Handle
+ OMP_CLAUSE_FIRSTPRIVATE. For OMP_CLAUSE_LASTPRIVATE_LOOP_IV, if
+ not outermost also add OMP_CLAUSE_FIRSTPRIVATE, and in both cases
+ clear OMP_CLAUSE_LASTPRIVATE_LOOP_IV on the lastprivate clause
+ on the OMP_FOR and OMP_DISTRIBUTE constructs if any.
+ * omp-low.c (lower_rec_input_clauses): For
+ OMP_CLAUSE_LASTPRIVATE_LOOP_IV on simd copy construct the private
+ variables instead of default constructing them.
+ (lower_lastprivate_clauses): Use OMP_CLAUSE_LASTPRIVATE_LOOP_IV
+ instead of OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV and move the
+ is_taskloop_ctx check from the assert to the guarding condition.
+
+2019-08-06 Kito Cheng <kito.cheng@sifive.com>
+
+ * config/riscv/multilib-generator: (canonical_order): New.
+ (arch_canonicalize): Dito.
+ Apply arch_canonicalize for alts.
+
+2019-08-05 Martin Sebor <msebor@redhat.com>
+
+ * doc/extend.texi (Common Variable Attributes): Document alias
+ attribute.
+
+2019-08-05 Marek Polacek <polacek@redhat.com>
+
+ PR c++/91338 - Implement P1161R3: Deprecate a[b,c].
+ * doc/invoke.texi: Document -Wcomma-subscript.
+
+2019-08-05 Richard Sandiford <richard.sandiford@arm.com>
+
+ * tree-core.h (tree_function_decl): Make function_code an
+ independent field. Group the remaining bitfields into bytes
+ and move decl_type so that it contines to be at a byte boundary.
+ Leave 12 bits for future expansion.
+
+2019-08-05 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gimple-fold.c (gimple_fold_mask_load_store_mem_ref)
+ (gimple_fold_mask_load, gimple_fold_mask_store): New functions.
+ (gimple_fold_call): Use them to fold IFN_MASK_LOAD and
+ IFN_MASK_STORE.
+
+2019-08-05 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gimple.h (gimple_move_vops): Declare.
+ * gimple.c (gimple_move_vops): New function
+ * gimple-fold.c (replace_call_with_call_and_fold)
+ (gimple_fold_builtin_memory_op, gimple_fold_builtin_memset)
+ (gimple_fold_builtin_stpcpy, fold_builtin_atomic_compare_exchange)
+ (gimple_fold_call): Use it.
+ * ipa-param-manipulation.c (ipa_modify_call_arguments): Likewise.
+ * tree-call-cdce.c (use_internal_fn): Likewise.
+ * tree-if-conv.c (predicate_load_or_store): Likewise.
+ * tree-ssa-ccp.c (optimize_atomic_bit_test_and): Likewise.
+ * tree-ssa-math-opts.c (pass_cse_reciprocals::execute): Likewise.
+ * tree-ssa-propagate.c (finish_update_gimple_call): Likewise.
+ (update_call_from_tree): Likewise.
+ * tree-vect-stmts.c (vectorizable_load): Likewise.
+ * tree-vectorizer.c (adjust_simduid_builtins): Likewise.
+
+2019-08-05 Martin Liska <mliska@suse.cz>
+
+ PR c++/91334
+ * tree-ssa-dce.c (propagate_necessity): Handle new operators
+ with not arguments.
+ (eliminate_unnecessary_stmts): Likewise.
+
+2019-08-05 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/91169
+ * fold-const.c (get_array_ctor_element_at_index): Create
+ offset_ints according to the sign of the index type and treat
+ that as signed if it is obviously so.
+
+2019-08-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/91341
+ * config/i386/avxintrin.h (_mm256_loadu2_m128, _mm256_storeu2_m128,
+ _mm256_loadu2_m128d, _mm256_storeu2_m128d, _mm256_loadu2_m128i,
+ _mm256_storeu2_m128i): New function.
+
+2019-08-05 Kito Cheng <kito.cheng@sifive.com>
+
+ * config/riscv/riscv.c (riscv_promote_function_mode): New.
+ (TARGET_PROMOTE_FUNCTION_MODE): Use riscv_promote_function_mode.
+
+2019-08-05 Alan Modra <amodra@gmail.com>
+
+ PR target/91349
+ * config/rs6000/freebsd64.h (CPLUSPLUS_CPP_SPEC),
+ (LINK_GCC_C_SEQUENCE_SPEC): Undef.
+
+2019-08-04 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/install.texi (Prerequisites): Remove reference to Tcl 8.6
+ bug that was fixed in Tcl 8.6.1.
+
+2019-08-02 Michael Meissner <meissner@linux.ibm.com>
+
+ * config/rs6000/future.md: New file.
+ * config/rs6000/rs6000.md: Include future.md.
+ * config/rs6000/t-rs6000 (MD_INCLUDES): Add future.md.
+
+2019-08-02 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * function.c (assign_parm_adjust_stack_rtl): Revise STRICT_ALIGNMENT
+ check to use targetm.slow_unaligned_access instead.
+
+ * function.c (assign_param_data_one): Remove unused data members.
+
+2019-08-02 Steve Ellcey <sellcey@marvell.com>
+
+ * omp-simd-clone.c (simd_clone_adjust_return_type): Remove call to
+ build_distinct_type_copy.
+ (simd_clone_adjust_argument_types): Ditto.
+ (simd_clone_adjust): Call build_distinct_type_copy here.
+ (expand_simd_clones): Ditto.
+
+2019-08-02 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/91201
+ * config/i386/sse.md (*vec_extractv16qi_zext): New insn pattern.
+
+2019-08-02 Alexander Monakov <amonakov@ispras.ru>
+
+ * tree-ssa-loop-im.c (sort_bbs_in_loop_postorder_cmp): Simplify casts
+ from 'const void *'.
+ (sort_locs_in_loop_postorder_cmp): Likewise.
+
+2019-08-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * doc/invoke.texi (hot-bb-count-fraction): Rework description.
+ (hot-bb-count-ws-permille): Likewise.
+ (hot-bb-frequency-fraction): Likewise.
+ (unlikely-bb-count-fraction): Likewise.
+ * params.def (hot-bb-count-fraction): Rework description.
+ (hot-bb-count-ws-permille): Likewise.
+ (hot-bb-frequency-fraction): Likewise.
+ (unlikely-bb-count-fraction): Likewise. Remove min and max values.
+ * predict.c (get_hot_bb_threshold): Deal with 0 HOT_BB_COUNT_FRACTION.
+
+2019-08-02 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/91323
+ * config/i386/i386-expand.c (ix86_unordered_fp_compare) <case LTGT>:
+ Return false.
+
+2019-08-02 Richard Biener <rguenther@suse.de>
+
+ * vec.h (vec::sort): Add gcc_qsort_r support.
+ (vec::bsearch): Add an overload with gcc_qsort_r style callbacks.
+ * tree-ssa-loop-im.c (sort_bbs_in_loop_postorder_cmp): Adjust
+ to gcc_qsort_r style callback.
+ (sort_locs_in_loop_postorder_cmp): Likewise.
+ (analyze_memory_references): Use gcc_sort_r interfaces.
+ (find_ref_loc_in_loop_cmp): Use new bsearch overload.
+
+2019-08-02 Martin Liska <mliska@suse.cz>
+
+ PR lto/91313
+ * gcc.c (driver::maybe_run_linker): Call detect_jobserver
+ to detect working job server.
+ (driver::detect_jobserver): Test whether jobserver
+ is active from GCC driver. That will prevent situation where
+ GCC is invoked from a LD plugin and the linker already uses
+ file descriptors suggested by make. That leads to a wrong
+ detection.
+ * gcc.h (driver): Add detect_jobserver.
+ * lto-wrapper.c (jobserver_active_p): Simplify sscanf by
+ not scanning for --jobserver-auth prefix.
+
+2019-08-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/91201
+ * config/i386/i386-expand.c (ix86_expand_vector_extract): For elt == 0
+ V16QImode extraction without sse4.1 try to use V4SImode lowpart
+ extraction.
+
+2019-08-01 Martin Sebor <msebor@redhat.com>
+
+ PR c++/90947
+ * tree.c (type_initializer_zero_p): Define.
+ * tree.h (type_initializer_zero_p): New function.
+
+2019-08-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * cfgrtl.c (relink_block_chain): Add line returns in dump file.
+
+2019-08-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * cgraph.h (cgraph_edge::maybe_hot_p): Tweak comment.
+ * cgraph.c (cgraph_edge::maybe_hot_p): Likewise. Remove useless test.
+ * predict.c (maybe_hot_count_p): Likewise.
+ (maybe_hot_bb_p): Tweak comment.
+ (maybe_hot_edge_p): Likewise.
+ (probably_never_executed): Likewise. Minor tweak.
+ (probably_never_executed_bb_p): Likewise.
+ (unlikely_executed_edge_p): Likewise.
+ (probably_never_executed_edge_p): Likewise.
+ (optimize_function_for_size_p): Likewise.
+ (optimize_function_for_speed_p): Likewise.
+ (function_optimization_type): Likewise.
+ (optimize_bb_for_size_p): Likewise.
+ (optimize_bb_for_speed_p): Likewise.
+ (bb_optimization_type): Likewise.
+ (optimize_edge_for_size_p): Likewise.
+ (optimize_edge_for_speed_p): Likewise.
+ (optimize_insn_for_size_p): Likewise.
+ (optimize_insn_for_speed_p): Likewise.
+ (optimize_loop_for_size_p): Likewise.
+ (optimize_loop_for_speed_p): Likewise.
+ (optimize_loop_nest_for_speed_p): Likewise.
+ (optimize_loop_nest_for_size_p): Likewise.
+ (predictable_edge_p): Likewise.
+ (handle_missing_profiles): Minor tweak.
+
+2019-08-01 Michael Meissner <meissner@linux.ibm.com>
+
+ * config/rs6000/predicates.md (pcrel_external_address): Update
+ comment.
+
+2019-08-01 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/85693
+ * config/i386/mmx.md (usadv8qi): New expander.
+
+2019-08-01 Matthew Beliveau <mbelivea@redhat.com>
+
+ PR c++/90590
+ * c-warn.c (c_do_switch_warnings): Suppress warning for enumerators
+ with reserved names that are in a system header.
+
+2019-08-01 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/mmx.md (vec_extractv2si_0): Add (r,x) alternative.
+ (*vec_extractv2si_0_zext_sse4): New insn pattern.
+ (*vec_extractv2si_0_zext): Ditto.
+ (*vec_extractv2si_1): Add (rm,x) alternative.
+ (*vec_extractv2si_1_zext): New insn pattern.
+ (*vec_extractv2si_zext_mem): Add "TARGET_MMX || TARGET_MMX_WITH_SSE"
+ insn constraint.
+
+2019-08-01 Richard Biener <rguenther@suse.de>
+
+ * domwalk.c (bb_postorder): Remove static variable.
+ (cmp_bb_postorder): Adjust.
+ (sort_bbs_postorder): Adjust and use gcc_sort_r.
+ (dom_walker::walk): Adjust.
+
+2019-08-01 Alexander Monakov <amonakov@ispras.ru>
+
+ * sort.cc (sort_r_ctx): New struct.
+ (reorder23): Make templated on context type.
+ (reorder45): Ditto.
+ (cmp1): Ditto. Adjust signature.
+ (netsort): Ditto.
+ (mergesort): Ditto.
+ [CHECKING_P] (cmp2to3): New static function. Use it...
+ (gcc_qsort) [CHECKING_P]: ...here.
+ (gcc_sort_r): New function.
+ * system.h (sort_r_cmp_fn): New function typedef.
+ (qsort_chk): Adjust signature.
+ (gcc_sort_r): Declare.
+ * vec.c (qsort_chk_error): Adjust.
+ (qsort_chk): Adjust.
+
+2019-08-01 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-pre.c (has_abnormal_preds): Remove global var.
+ (compute_antic): Localize it here.
+
+2019-07-31 Maxim Blinov <maxim.blinov@embecosm.com>
+
+ * common/config/riscv/riscv-common.c: Check -march string ends
+ with null.
+
+2019-07-31 Alexander Monakov <amonakov@ispras.ru>
+
+ * ipa-devirt.c (type_warning_cmp): Make static.
+ (decl_warning_cmp): Ditto.
+
+2019-07-31 Peter Bergner <bergner@linux.ibm.com>
+
+ PR target/91050
+ * config/rs6000/rs6000.opt (mdejagnu-cpu=): Delete option.
+ * config/rs6000/rs6000.c (rs6000_option_override_internal): Remove
+ use of deleted rs6000_dejagnu_cpu_index variable.
+ * config/rs6000/rs6000.h (DRIVER_SELF_SPECS): Define.
+ (SUBTARGET_DRIVER_SELF_SPECS): Likewise.
+ * config/darwin.h (DRIVER_SELF_SPECS): Rename from this ...
+ (SUBTARGET_DRIVER_SELF_SPECS): ...to this.
+ * config/i386/i386.h (DRIVER_SELF_SPECS): Define.
+ (SUBTARGET_DRIVER_SELF_SPECS): Likewise.
+
+2019-07-31 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91280
+ * tree-ssa-structalias.c (get_constraint_for_component_ref):
+ Decompose MEM_REF manually for offset handling.
+
+2019-07-31 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91293
+ * tree-vect-slp.c (vect_build_slp_tree_2): Do not swap operands
+ of reduction stmts.
+
+2019-07-31 Matt Thomas <matt@3am-software.com>
+ Nick Hudson <nick@nthcliff.demon.co.uk>
+ Matthew Green <mrg@eterna.com.au>
+ Maya Rashish <coypu@sdf.org>
+
+ * config.gcc (hppa*-*-netbsd*): New target.
+ * config/pa/pa-netbsd.h: New file.
+ * config/pa/pa32-netbsd.h: New file.
+
+2019-07-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/91201
+ * config/i386/mmx.md (reduc_plus_scal_v8qi): New expander.
+
+2019-07-31 Andrew Stubbs <ams@codesourcery.com>
+
+ * config/gcn/gcn-valu.md
+ (scatter<mode>_insn_1offset<exec_scatter>): Remove s_waitcnt.
+ (scatter<mode>_insn_1offset_ds<exec_scatter>): Likewise.
+ (scatter<mode>_insn_2offsets<exec_scatter>): Likewise.
+ * config/gcn/gcn.c (gcn_md_reorg): Add delayeduse and reads to
+ struct ilist. Add nops for delayeduse insns.
+ * config/gcn/gcn.md (delayeduse): New attribute.
+ (*movbi): Remove s_waitcnt from stores.
+ (*mov<mode>_insn): Likewise.
+ (*movti_insn): Likewise. Add delayeduse attribute.
+ (sync_compare_and_swap<mode>_insn): Add delayeduse attribute.
+ (atomic_store<mode>): Remove or adjust s_waitcnt.
+
+2019-07-31 Richard Biener <rguenther@suse.de>
+
+ * vr-values.h (vr_values::swap_vr_value): New.
+ (vr_values::free_value_range): likewise.
+ * vr-values.c (vr_values::swap_vr_value): Implement.
+ * gimple-ssa-evrp-analyze.h (evrp_range_analyzer::pop_value_range):
+ Do not return a range or take a var.
+ (evrp_range_analyzer::stack): Change back to recording a non-const
+ value_range *.
+ * gimple-ssa-evrp-analyze.c
+ (evrp_range_analyzer::record_ranges_from_stmt): Free unused
+ value-range.
+ (evrp_range_analyzer::pop_to_marker): Adjust.
+ (evrp_range_analyzer::push_value_range): Use new swap_vr_value.
+ (evrp_range_analyzer::pop_value_range): Likewise. Free the
+ no longer needed value-range.
+
+2019-07-31 Martin Liska <mliska@suse.cz>
+
+ * tree-ssa-dce.c (propagate_necessity): Delete operator can
+ have size and (or) alignment as 2nd and later arguments.
+ Mark all of them as necessary.
+
+2019-07-31 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91178
+ * tree-ssa-sccvn.c (vn_reference_maybe_forwprop_address):
+ Use tail-recursion.
+
+2019-07-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/91201
+ * config/i386/sse.md (reduc_plus_scal_v16qi): New expander.
+ (REDUC_PLUS_MODE): Add V32QImode for TARGET_AVX and V64QImode for
+ TARGET_AVX512F.
+ (reduc_plus_scal_<mode>): Improve formatting by introducing
+ a temporary.
+
+2019-07-31 Sudakshina Das <sudi.das@arm.com>
+
+ * config/aarch64/aarch64-builtins.c (enum aarch64_builtins): Add
+ AARCH64_TME_BUILTIN_TSTART, AARCH64_TME_BUILTIN_TCOMMIT,
+ AARCH64_TME_BUILTIN_TTEST and AARCH64_TME_BUILTIN_TCANCEL.
+ (aarch64_init_tme_builtins): New.
+ (aarch64_init_builtins): Call aarch64_init_tme_builtins.
+ (aarch64_expand_builtin_tme): New.
+ (aarch64_expand_builtin): Handle TME builtins.
+ * config/aarch64/aarch64-c.c (aarch64_update_cpp_builtins): Define
+ __ARM_FEATURE_TME when enabled.
+ * config/aarch64/aarch64-option-extensions.def: Add "tme".
+ * config/aarch64/aarch64.h (AARCH64_FL_TME, AARCH64_ISA_TME): New.
+ (TARGET_TME): New.
+ * config/aarch64/aarch64.md (define_c_enum "unspec"): Add UNSPEC_TTEST.
+ (define_c_enum "unspecv"): Add UNSPECV_TSTART, UNSPECV_TCOMMIT and
+ UNSPECV_TCANCEL.
+ (tstart, ttest, tcommit, tcancel): New instructions.
+ * config/aarch64/arm_acle.h (__tstart, __tcommit): New.
+ (__tcancel, __ttest): New.
+ (_TMFAILURE_REASON, _TMFAILURE_RTRY, _TMFAILURE_CNCL): New macro.
+ (_TMFAILURE_MEM, _TMFAILURE_IMP, _TMFAILURE_ERR): Likewise.
+ (_TMFAILURE_SIZE, _TMFAILURE_NEST, _TMFAILURE_DBG): Likewise.
+ (_TMFAILURE_INT, _TMFAILURE_TRIVIAL): Likewise.
+ * config/arm/types.md: Add new tme type attr.
+ * doc/invoke.texi: Document "tme".
+
+2019-07-31 Joel Hutton <Joel.Hutton@arm.com>
+
+ * config/arm/arm_cmse.h (cmse_nonsecure_caller): Add
+ warn_unused_result attribute.
+ (cmse_check_address_range): Add warn_unused_result attribute.
+
+2019-07-31 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91257
+ * tree-vrp.c (union_ranges): Unify equality and less tests
+ by using compare_values. Re-order cheap tests first.
+
+2019-07-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/91301
+ * gimplify.c (gimplify_omp_for): If for class iterator on
+ distribute parallel for there is no data sharing clause
+ on inner_for_stmt, look for private clause on combined
+ parallel too and if found, move it to inner_for_stmt.
+
+2019-07-31 Richard Sandiford <richard.sandiford@arm.com>
+
+ * lra-int.h (lra_operand_data): Remove early_clobber field.
+ (lra_insn_reg): Likewise.
+ * lra.c (debug_operand_data): Update accordingly.
+ (setup_operand_alternative): Likewise.
+ (new_insn_reg): Likewise. Remove early_clobber parameter.
+ (collect_non_operand_hard_regs): Update call accordingly.
+ Don't assign to lra_insn_reg::early_clobber.
+ (add_regs_to_insn_regno_info): Remove early_clobber parameter
+ and update calls to new_insn_reg.
+ (lra_update_insn_regno_info): Update calls accordingly.
+ * lra-constraints.c (update_and_check_small_class_inputs): Take the
+ alternative number as a parameter and test whether the operand
+ is earlyclobbered in that particular alternative.
+ (process_alt_operands): Update call accordingly. Use per-alternative
+ checks for earyclobber here too.
+ * lra-lives.c (reg_early_clobber_p): Check early_clobber_alts
+ against zero for IRA_UNKNOWN_ALT.
+
+2019-07-30 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.c (alpha_option_override): Quote a C type.
+
+2019-07-30 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * config/arm/thumb2.md (thumb2_movsi_insn): Adjust literal offset.
+ * config/arm/vfp.md (thumb2_movsi_vfp): Likewise.
+
+2019-07-30 Martin Liska <mliska@suse.cz>
+
+ PR ipa/89330
+ * cgraph.c (cgraph_edge::make_direct): Use
+ edge->indirect_unknown_callee as edge->resolve_speculation can
+ deallocate edge which is this pointer.
+
+2019-07-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91257
+ * bitmap.c (bitmap_ior_and_compl_into): Open-code.
+
+2019-07-30 Martin Liska <mliska@suse.cz>
+
+ * doc/invoke.texi: Document new behavior.
+ * lto-wrapper.c (cpuset_popcount): New function
+ is a copy of libgomp/config/linux/proc.c.
+ (init_num_threads): Likewise.
+ (run_gcc): Automatically detect core count for -flto.
+ (jobserver_active_p): New function.
+
+2019-07-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91257
+ * bitmap.h (bitmap_ior_into_and_free): Declare.
+ * bitmap.c (bitmap_list_unlink_element): Add defaulted param
+ whether to add the unliked element to the freelist.
+ (bitmap_list_insert_element_after): Add defaulted param for
+ an already allocated element.
+ (bitmap_ior_into_and_free): New function.
+ * tree-ssa-structalias.c (condense_visit): Reduce the
+ ponts-to and edge bitmaps of the SCC members in a
+ logarithmic fashion rather than all to one.
+
+2019-07-30 Richard Sandiford <richard.sandiford@arm.com>
+
+ * tree-ssa-math-opts.c (convert_mult_to_fma): Add a mul_cond
+ parameter. When nonnull, make sure that the addition or subtraction
+ has the same condition.
+ (math_opts_dom_walker::after_dom_children): Try convert_mult_to_fma
+ for CFN_COND_MUL too.
+
+2019-07-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91291
+ * tree-ssa-sccvn.c (rpo_elim::eliminate_push_avail): Ignore
+ constant values.
+
+2019-07-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/91216
+ * omp-low.c (global_nonaddressable_vars): New variable.
+ (use_pointer_for_field): For global decls, if they are non-addressable,
+ remember it in the global_nonaddressable_vars bitmap, if they are
+ addressable and in the global_nonaddressable_vars bitmap, ignore their
+ TREE_ADDRESSABLE bit.
+ (omp_copy_decl_2): Clear TREE_ADDRESSABLE also on private copies of
+ vars in global_nonaddressable_vars bitmap.
+ (execute_lower_omp): Free global_nonaddressable_vars bitmap.
+
+ PR target/91150
+ * config/i386/i386-expand.c (expand_vec_perm_blend): Change mask type
+ from unsigned to unsigned HOST_WIDE_INT. For E_V64QImode cast
+ comparison to unsigned HOST_WIDE_INT before shifting it left.
+
+2019-07-30 Uroš Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (movstrict<mode>): Use register_operand
+ predicate for operand 0. Add expander condition. Assert that
+ operand 0 is a SUBREG RTX.
+ (*movstrict<mode>_1): Use register_operand predicate for operand 0.
+ Update operand constraints and insn condition.
+ (zero_extend<mode>si2_and): Do not call gen_movstrict<mode>.
+ (zero_extendqihi2_and): Do not call gen_movstrictqi.
+ (*setcc_qi_slp): Use register_operand predicate for operand 0.
+ Update operand 0 constraints.
+ (setcc_qi_slp splitters): Use register_operand predicate for operand 0.
+
+2019-07-29 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config/msp430/msp430.h (DRIVER_SELF_SPECS): Define and emit errors
+ when -m{code,data}-region are used without -mlarge.
+ * config/msp430/msp430.c (msp430_option_override): Error when a
+ non-default code or data region is used without -mlarge.
+ (msp430_section_attr): Emit a warning and do not add upper/lower/either
+ attributes when they are used without -mlarge.
+
+2019-07-29 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ PR target/70320
+ * config/msp430/msp430.h: Define ADDITIONAL_REGISTER_NAMES.
+
+2019-07-29 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR middle-end/91242
+ * wide-int.h (generic_wide_int::sext_elt): New function.
+ * inchash.h (hash::add_wide_int): Use it instead of elt.
+
+2019-07-29 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm-builtins.c (acle_builtin_data): Expand VAR1 to
+ CODE_FOR_arm_##.
+ * config/arm/arm.md (<crc_variant>): Rename to...
+ (arm_<crc_variant>): ... This.
+ (<cdp>): Rename to...
+ (arm_<cdp>): ... This.
+ (<ldc>): Rename to...
+ (arm_<ldc>): ... This.
+ (<stc>): Rename to...
+ (arm_<stc>): ... This.
+ (<mcr>): Rename to...
+ (arm_<mcr>): ... This.
+ (<mrc>): Rename to...
+ (arm_<mrc>): ... This.
+ (<mcrr>): Rename to...
+ (arm_<mcrr>): ... This.
+ (<mrrc>): Rename to...
+ (arm_<mrrc>): ... This.
+
+2019-07-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91257
+ * tree-ssa-sccvn.h (struct vn_avail): New.
+ (struct vn_ssa_aux): Add avail member.
+ * tree-ssa-sccvn.c (class rpo_elim): Remove m_rpo_avail
+ member, add m_avail_freelist one.
+ (rpo_elim::~rpo_elim): Remove.
+ (rpo_elim::eliminate_avail): Adjust to new avail tracking
+ data structure.
+ (rpo_elim::eliminate_push_avail): Likewise.
+ (do_unwind): Likewise.
+ (do_rpo_vn): Likewise.
+
+2019-07-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91257
+ * tree-vrp.c (operand_less_p): Avoid dispatching to fold for
+ most cases, instead call compare_values which handles the
+ symbolic ranges we handle specially.
+ (compare_values_warnv): Do not call operand_less_p but open-code
+ the effective fold calls. Avoid converting so much.
+
+2019-07-29 Martin Liska <mliska@suse.cz>
+
+ * tree-ssa-dce.c (eliminate_unnecessary_stmts): Do not
+ remove LHS of operator new call. It's handled latter.
+
+2019-07-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91267
+ * vr-values.c (vr_values::update_value_range): Add early return
+ for effectively VARYING lattice entry.
+
+2019-07-29 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR debug/86638
+ * tree-ssa-dce.c (keep_all_vdefs_p): New function.
+ (mark_stmt_if_obviously_necessary): Mark all stmts with vdefs as
+ necessary if keep_all_vdefs_p is true.
+ (mark_aliased_reaching_defs_necessary): Add a gcc_checking_assert
+ that keep_all_vdefs_p is false.
+ (mark_all_reaching_defs_necessary): Likewise.
+ (propagate_necessity): Skip the vuse scan if keep_all_vdefs_p is true.
+
+2019-07-29 Richard Sandiford <richard.sandiford@arm.com>
+
+ * common.opt (Og): Change the initial value of flag_dse to 0.
+ * opts.c (default_options_table): Move OPT_ftree_dse from
+ OPT_LEVELS_1_PLUS to OPT_LEVELS_1_PLUS_NOT_DEBUG. Also add
+ OPT_fdse to OPT_LEVELS_1_PLUS_NOT_DEBUG. Put the OPT_ftree_pta
+ entry before the OPT_ftree_sra entry.
+ * doc/invoke.texi (Og): Add -fdse and -ftree-dse to the list
+ of flags disabled by Og.
+
+2019-07-29 Richard Sandiford <richard.sandiford@arm.com>
+
+ * tree-cfg.c (execute_fixup_cfg): Don't delete stores to write-only
+ variables for -Og.
+
+2019-07-29 Richard Sandiford <richard.sandiford@arm.com>
+
+ * doc/sourcebuild.texi (check-function-bodies): Document.
+
+2019-07-29 Richard Sandiford <richard.sandiford@arm.com>
+
+ * simplify-rtx.c (simplify_const_unary_operation): Fold a
+ VEC_DUPLICATE of a fixed-length vector even if the result
+ is variable-length. Likewise fold a duplicate of a
+ variable-length vector if the variable-length vector is
+ itself a duplicate of a fixed-length sequence.
+ (test_vector_ops_duplicate): Test more cases.
+
+2019-07-29 Richard Sandiford <richard.sandiford@arm.com>
+
+ * vector-builder.h (vector_builder): Add a shape template parameter.
+ (vector_builder::new_unary_operation): New function, generalizing
+ the old tree_vector_builder function.
+ (vector_builder::new_binary_operation): Likewise.
+ (vector_builder::binary_encoded_nelts): Likewise.
+ * int-vector-builder.h (int_vector_builder): Update template
+ parameters to vector_builder.
+ (int_vector_builder::shape_nelts): New function.
+ * rtx-vector-builder.h (rtx_vector_builder): Update template
+ parameters to vector_builder.
+ (rtx_vector_builder::shape_nelts): New function.
+ (rtx_vector_builder::nelts_of): Likewise.
+ (rtx_vector_builder::npatterns_of): Likewise.
+ (rtx_vector_builder::nelts_per_pattern_of): Likewise.
+ * tree-vector-builder.h (tree_vector_builder): Update template
+ parameters to vector_builder.
+ (tree_vector_builder::shape_nelts): New function.
+ (tree_vector_builder::nelts_of): Likewise.
+ (tree_vector_builder::npatterns_of): Likewise.
+ (tree_vector_builder::nelts_per_pattern_of): Likewise.
+ * tree-vector-builder.c (tree_vector_builder::new_unary_operation)
+ (tree_vector_builder::new_binary_operation): Delete.
+ (tree_vector_builder::binary_encoded_nelts): Likewise.
+ * simplify-rtx.c: Include rtx-vector-builder.h.
+ (distributes_over_addition_p): New function.
+ (simplify_const_unary_operation)
+ (simplify_const_binary_operation): Generalize handling of vector
+ constants to include variable-length vectors.
+ (test_vector_ops_series): Add more tests.
+
+2019-07-28 Jan Hubicka <hubicka@ucw.cz>
+
+ PR lto/91222
+ * ipa-devirt.c (warn_types_mismatch): Compare indentifiers
+ than INDENTIFIER_POINTER.
+
+2019-07-28 Martin Liska <mliska@suse.cz>
+
+ PR ipa/89330
+ * cgraph.c (symbol_table::create_edge): Always allocate
+ a cgraph_edge.
+ (symbol_table::free_edge): Store summary_id to
+ edge_released_summary_ids if != -1;
+ * cgraph.h (NEXT_FREE_NODE): Remove.
+ (SET_NEXT_FREE_NODE): Likewise.
+ (NEXT_FREE_EDGE): Likewise.
+ (symbol_table::release_symbol): Store summary_id to
+ cgraph_released_summary_ids if != -1;
+ (symbol_table::allocate_cgraph_symbol): Always allocate
+ a cgraph_node.
+
+2019-07-28 Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/rs6000-call.c (rs6000_output_mi_thunk): Use
+ gen_sibcall.
+
+2019-07-28 Alan Modra <amodra@gmail.com>
+
+ PR target/91135
+ * config/rs6000/linux.h (GNU_USER_TARGET_D_OS_VERSIONS): Don't
+ define.
+ * config/rs6000/linux64.h (TARGET_OS_CPP_BUILTINS): Invoke
+ GNU_USER_TARGET_OS_CPP_BUILTINS for aixdesc abi.
+ (GNU_USER_TARGET_D_OS_VERSIONS): Don't define.
+
+2019-07-28 Alan Modra <amodra@gmail.com>
+
+ PR target/91050
+ * config/rs6000/sysv4.h (ASM_DEFAULT_SPEC): Modify if -m64.
+ * config/rs6000/default64.h (ASM_DEFAULT_SPEC): Define.
+ * config/rs6000/freebsd64.h (ASM_DEFAULT_SPEC): Don't define.
+ * config/rs6000/linux64.h (ASM_DEFAULT_SPEC): Likewise.
+ * config/rs6000/rtems.h (ASM_DEFAULT_SPEC): Likewise.
+ * config/rs6000/rs6000.h (ASM_DEFAULT_EXTRA): Define and use
+ in asm_default spec.
+ * config/rs6000/eabialtivec.h (ASM_DEFAULT_EXTRA): Redefine.
+ * config/rs6000/linuxaltivec.h (ASM_DEFAULT_EXTRA): Redefine.
+
+2019-07-28 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/include/gpl_v3.texi (Copying): Use https for www.gnu.org.
+
+2019-07-26 Tamar Christina <tamar.christina@arm.com>
+
+ PR target/89517
+ * config.gcc: Relax parsing of AARCH64_OPT_EXTENSION.
+ * config/aarch64/aarch64-option-extensions.def: Add new comments
+ and restore easier to read options.
+
+2019-07-26 Tamar Christina <tamar.christina@arm.com>
+
+ * convert.c (convert_to_real_1): Move part of conversion code...
+ * match.pd: ...To here.
+
+2019-07-26 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/89330
+ * ipa-inline-transform.c (check_speculations_1): New function.
+ (push_all_edges_in_set_to_vec): Likewise.
+ (check_speculations): Use check_speculations_1, new parameter
+ new_edges.
+ (inline_call): Pass new_edges to check_speculations.
+ * ipa-inline.c (add_new_edges_to_heap): Assert edge_callee is not
+ NULL.
+ (speculation_useful_p): Early return true if edge is inlined, remove
+ later checks for inline_failed.
+
+2019-07-25 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/91223
+ * lra-constraints.c (process_alt_operands): Fail for unsuccessful
+ matching with INOUT operand.
+
+2019-07-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * stmt.c (expand_case): Try to narrow the index type if it's larger
+ than a word. Tidy up.
+
+2019-07-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * cif-code.def (NEVER_CALL): New code.
+ * ipa-inline.c (want_inline_small_function_p): Fix formatting issues.
+ Set the failure to CIF_NEVER_CALL if the IPA count is zero.
+
+2019-07-25 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * config/arm/thumb2.md (thumb2_movsi_insn): Fix load/store low reg.
+ * config/arm/vfp.md (thumb2_movsi_vfp): Likewise.
+
+2019-07-23 Jan Hubicka <hubicka@ucw.cz>
+
+ * ipa-devirt.c (add_type_duplicate): Fix return value.
+
+2019-07-25 Richard Biener <rguenther@suse.de>
+
+ * tree-vrp.c (extract_range_from_multiplicative_op): Add
+ type parameter and use it instead of guessing expression
+ type from the first operand.
+ (extract_range_from_binary_expr): Pass expr_type down.
+
+2019-07-25 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.md (SATrev): Change to code attribute.
+ (*satsi_<SAT:code>): Adjust for the above.
+ (*satsi_<SAT:code>_shift): Likewise.
+
+2019-07-25 Richard Biener <rguenther@suse.de>
+
+ * gimple-loop-versioning.cc (loop_versioning::prune_loop_conditions):
+ Make value_range * temporary const.
+ * gimple-ssa-evrp-analyze.c (evrp_range_analyzer::try_find_new_range):
+ Likewise.
+ (evrp_range_analyzer::record_ranges_from_): Likewise.
+ (evrp_range_analyzer::pop_value_range): Return a const value_range *,
+ deal with having recorded a const one.
+ * gimple-ssa-evrp-analyze.h (evrp_range_analyzer::get_value_range):
+ Return a const value_range *.
+ (evrp_range_analyzer::pop_value_range): Likewise.
+ (evrp_range_analyzer::stack): Record const value_range *s.
+ * gimple-ssa-evrp.c (evrp_dom_walker::before_dom_children):
+ Adjust.
+ * gimple-ssa-sprintf.c (get_int_range): Likewise.
+ (format_integer): Likewise.
+ (sprintf_dom_walker::handle_gimple_call): Likewise.
+ * tree-ssa-dom.c (simplify_stmt_for_jump_threading): Likewise.
+ * tree-vrp.c (vrp_prop::set_def_to_varying): Add.
+ (vrp_prop::get_value_range): Adjust.
+ (vrp_prop::vrp_initialize): Use set_def_to_varying instead of
+ modifying the lattice in-place.
+ (vrp_prop::visit_stmt): Likewise.
+ * vr-values.c (vr_values::get_lattice_entry): New private method.
+ (vr_values::get_value_range): Wrap it and return a const
+ value_range *.
+ (vr_values::set_def_to_varying): New.
+ (vr_values::set_defs_to_varying): Use it.
+ (vr_values::update_value_range): Likewise.
+ (vr_values::vrp_stmt_computes_nonzero): Adjust.
+ (values::op_with_constant_singleton_va): Likewise.
+ (vr_values::extract_range_for_var_from_co): Likewise.
+ (vr_values::extract_range_from_ssa_name): Likewise.
+ (vr_values::extract_range_from_cond_expr): Likewise.
+ (vr_values::extract_range_basic): Likewise.
+ (compare_ranges): Take const value_range *, adjust.
+ (compare_range_with_value): Likewise.
+ (vrp_valueize): Adjust.
+ (vrp_valueize_1): Likewise.
+ (vr_values::get_vr_for_comparison): Return a const value_range *.
+ (vr_values::compare_name_with_value): Adjust.
+ (vr_values::compare_names): Likewise.
+ (vr_values::vrp_evaluate_conditional_warnv_with_ops_using_ranges):
+ Likewise.
+ (vr_values::vrp_evaluate_conditional): Likewise.
+ (find_case_label_ranges): Take a const value_range *.
+ (vr_values::vrp_visit_switch_stmt): Adjust.
+ (vr_values::extract_range_from_phi_node): Likewise.
+ (vr_values::simplify_div_or_mod_using_ran): Likewise.
+ (vr_values::simplify_abs_using_ranges): Likewise.
+ (test_for_singularity): Take a const value_range *.
+ (range_fits_type_p): Likewise.
+ (vr_values::simplify_cond_using_ranges_1): Adjust.
+ (vr_values::simplify_cond_using_ranges_2): Likewise.
+ (vr_values::simplify_switch_using_ranges): Likewise.
+ (vr_values::simplify_float_conversion_usi): Likewise.
+ (vr_values::two_valued_val_range_p): Likewise.
+ * vr-values.h (vr_values::get_value_range): Return a const
+ value_range *.
+ (vr_values::set_def_to_varying): New.
+ (vr_values::get_lattice_entry): New private method.
+ (vr_values::get_vr_for_comparison): Return a const value_range *.
+
+2019-07-25 Martin Liska <mliska@suse.cz>
+ Dominik Infuhr <dominik.infuehr@theobroma-systems.com>
+
+ PR c++/23383
+ * common.opt: Add -fallocation-dce
+ * gimple.c (gimple_call_operator_delete_p): New.
+ * gimple.h (gimple_call_operator_delete_p): Likewise.
+ * tree-core.h (enum function_decl_type): Add OPERATOR_DELETE.
+ * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Handle
+ DECL_IS_OPERATOR_DELETE_P.
+ (mark_all_reaching_defs_necessary_1): Likewise.
+ (propagate_necessity): Likewise.
+ (eliminate_unnecessary_stmts): Handle
+ gimple_call_operator_delete_p.
+ * tree-streamer-in.c (unpack_ts_function_decl_value_fields):
+ Add packing of OPERATOR_DELETE.
+ * tree-streamer-out.c (pack_ts_function_decl_value_fields):
+ Similarly here.
+ * tree.h (DECL_IS_OPERATOR_DELETE_P): New.
+ (DECL_SET_IS_OPERATOR_DELETE): New.
+ (DECL_IS_REPLACEABLE_OPERATOR_NEW_P): Likewise.
+
+2019-07-25 Martin Liska <mliska@suse.cz>
+
+ * calls.c (maybe_warn_alloc_args_overflow): Use new macros
+ (e.g. DECL_SET_LAMBDA_FUNCTION and DECL_LAMBDA_FUNCTION_P).
+ * coverage.c (coverage_begin_function): Likewise.
+ * fold-const.c (tree_expr_nonzero_warnv_p): Likewise.
+ * gimple.c (gimple_call_nonnull_result_p): Likewise.
+ * ipa-icf.c (sem_item::compare_referenced_symbol_properties): Likewise.
+ (sem_item::hash_referenced_symbol_properties): Likewise.
+ * lto-streamer-out.c (hash_tree): Likewise.
+ * predict.c (expr_expected_value_1): Likewise.
+ * tree-inline.c (expand_call_inline): Likewise.
+ * tree-streamer-in.c (unpack_ts_function_decl_value_fields): Likewise.
+ * tree-streamer-out.c (pack_ts_function_decl_value_fields): Likewise.
+ * tree-core.h (enum function_decl_type): New enum.
+ (struct tree_function_decl): Remove operator_new_flag and lambda_function.
+ * tree.h (FUNCTION_DECL_DECL_TYPE): New.
+ (set_function_decl_type): Likewise.
+ (DECL_IS_OPERATOR_NEW_P): New.
+ (DECL_SET_IS_OPERATOR_NEW): Likewise.
+ (DECL_LAMBDA_FUNCTION): Likewise.
+ (DECL_LAMBDA_FUNCTION_P): Likewise.
+ (DECL_IS_OPERATOR_NEW): Remove.
+ (DECL_SET_LAMBDA_FUNCTION): Likewise.
+
+2019-07-25 Xiong Hu Luo <luoxhu@linux.ibm.com>
+
+ * ipa-profile.c (get_most_common_single_value): Use
+ get_nth_most_common_value.
+ * profile.c (sort_hist_value): New function.
+ (compute_value_histograms): Call sort_hist_value to sort the
+ values after loading from disk.
+ * value-prof.c (get_most_common_single_value): Rename to ...
+ get_nth_most_common_value. Add input params n, return
+ the n_th value and count.
+ (gimple_divmod_fixed_value_transform): Use
+ get_nth_most_common_value.
+ (gimple_ic_transform): Likewise.
+ (gimple_stringops_transform): Likewise.
+ * value-prof.h (get_most_common_single_value): Add input params
+ n, default to 0.
+
+2019-07-25 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91236
+ * tree-ssa-sccvn.c (vn_walk_cb_data::push_partial_def): Fix
+ size of CONSTRUCTOR write. Fix buffer size we pass to
+ native_encode_expr.
+
+2019-07-24 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config.gcc (msp430*-*-*): Fix non-GNU style in r273774.
+ * config/msp430/msp430.h (ENDFILE_SPEC): Fix non-GNU style in
+ r273773.
+
+2019-07-24 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config.gcc (msp430*-*-*): Enable initfini_array by default unless
+ explicitly disabled with --disable-initfini-array.
+
+2019-07-24 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * config/msp430/msp430.h (ENDFILE_SPEC): Wrap uses of crtn*.o in
+ if-exists.
+
+2019-07-24 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/91183
+ PR tree-optimization/86688
+ * builtins.c (compute_objsize): Handle MEM_REF.
+ * tree-ssa-strlen.c (class ssa_name_limit_t): New.
+ (get_min_string_length): Remove.
+ (count_nonzero_bytes): New function.
+ (handle_char_store): Rename...
+ (handle_store): to this. Handle multibyte stores via integer types.
+ (strlen_check_and_optimize_stmt): Adjust conditional and the called
+ function name.
+
+2019-07-24 Martin Sebor <msebor@redhat.com>
+
+ PR driver/80545
+ * diagnostic.c (diagnostic_classify_diagnostic): Use lang_mask.
+ (diagnostic_report_diagnostic): Same.
+ * diagnostic.h (diagnostic_context::option_enabled): Add an argument.
+ (diagnostic_context::lang_mask): New data member.
+ * ipa-pure-const.c (suggest_attribute): Use
+ lang_hooks.option_lang_mask ().
+ * opts-common.c (option_enabled): Handle new argument.
+ (get_option_state): Pass an additional argument.
+ * opts.c (print_filtered_help): Print supported languages for
+ unsupported options. Adjust printing of current state.
+ * opts.h (option_enabled): Add argument.
+ * toplev.c (print_switch_values): Use lang_mask.
+ (general_init): Set global_dc->lang_mask.
+
+2019-07-24 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR bootstrap/87030
+ * config/i386/darwin.h (REAL_LIBGCC_SPEC): Revert change from r273749.
+
+2019-07-24 Giuliano Belinassi <giuliano.belinassi@usp.br>
+
+ * cgraphunit.c (symbol_table::compile): Start and stop
+ TV_CGRAPH_IPA_PASSES and TV_CGRAPH_FUNC_EXPANSION timers.
+ * timevar.def (TV_CGRAPH_IPA_PASSES, TV_CGRAPH_FUNC_EXPANSION): New.
+
+2019-07-24 Oliver Browne <oliverbrowne62@gmail.com>
+
+ * gimplify.c (flag_instrument_functions_exclude_p): Include
+ namespace/class information in the printable name.
+ * opts.c (add_comma_separated_to_vector): Add NUL terminator
+ to tokens entered into the vector.
+
+2019-07-24 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-nested.c (build_simple_mem_ref_notrap): New function.
+ (get_static_chain): Call it instead of build_simple_mem_ref.
+ (get_frame_field): Likewise.
+ (get_nonlocal_debug_decl): Likewise.
+ (convert_nonlocal_reference_op): Likewise.
+
+2019-07-24 Claudiu Zissulescu <claziss@synopsys.com>
+
+ * config/arc/arc-protos.h (arc_output_function_epilogue): Delete
+ declaration.
+ (arc_compute_frame_size): Millicode is disabled when compiling
+ ISR.
+ (arc_return_address_register): Likewise.
+ (arc_compute_function_type): Likewise.
+ (arc_compute_frame_size): Likewise.
+ (secondary_reload_info): Likewise.
+ (arc_get_unalign): Likewise.
+ (arc_can_use_return_insn): Declare.
+ * config/arc/arc.c (AUX_LP_START): Define
+ (AUX_LP_END): Likewise.
+ (arc_frame_info): Update gmask member to 64-bit datum.
+ (GMASK_LEN): Update.
+ (arc_compute_function_type): Make it static, move it forward.
+ (arc_must_save_register): Update, consider the extra regs.
+ (arc_compute_millicode_save_restore_regs): Update to use the 64
+ bit gmask.
+ (arc_compute_frame_size): Likewise.
+ (arc_enter_leave_p): Likewise.
+ (arc_save_callee_saves): Likewise.
+ (arc_restore_callee_saves): Likewise.
+ (arc_save_callee_enter): Likewise.
+ (arc_restore_callee_leave): Likewise.
+ (arc_save_callee_milli): Likewise.
+ (arc_restore_callee_milli): Likewise.
+ (arc_expand_prologue): Add new interrupt handling.
+ (arc_return_address_register): Make it static, move it forward.
+ (arc_expand_epilogue): Add new interrupt handling.
+ (arc_get_unalign): Delete.
+ (arc_epilogue_uses): Make sure we do not remove the extra
+ saved/restored registers when interrupt.
+ (arc_can_use_return_insn): New function.
+ (push_reg): Likewise.
+ (pop_reg): Likewise.
+ (arc_save_callee_saves): Add ZOL and FPX aux registers saving
+ procedures.
+ (arc_restore_callee_saves): Likewise, but restoring.
+ * config/arc/arc.md (VUNSPEC_ARC_ARC600_RTIE): Define.
+ (R33_REG): Likewise.
+ (R34_REG): Likewise.
+ (R35_REG): Likewise.
+ (R36_REG): Likewise.
+ (R37_REG): Likewise.
+ (R38_REG): Likewise.
+ (R39_REG): Likewise.
+ (R45_REG): Likewise.
+ (R46_REG): Likewise.
+ (R47_REG): Likewise.
+ (R48_REG): Likewise.
+ (R49_REG): Likewise.
+ (R50_REG): Likewise.
+ (R51_REG): Likewise.
+ (R52_REG): Likewise.
+ (R53_REG): Likewise.
+ (R54_REG): Likewise.
+ (R55_REG): Likewise.
+ (R56_REG): Likewise.
+ (R58_REG): Likewise.
+ (type): Add rtie attribute.
+ (in_call_delay_slot): Use RETURN_ADDR_REGNUM.
+ (movsi_insn): Accept moves to lp_count.
+ (rtie): Update pattern.
+ (simple_return): Simplify it, don't use this pattern as a return
+ from an interrupt.
+ (arc600_rtie): New pattern.
+ (p_return_i): Clean up.
+ (return): Likewise.
+ * config/arc/builtins.def (rtie): Only available for non ARC6xx
+ family CPUs.
+ * config/arc/predicates.md (move_src_operand): Consider lp_count
+ as a register.
+
+2019-07-24 Andreas Krebbel <krebbel@linux.ibm.com>
+
+ * config/s390/predicates.md (addv_const_operand): New predicate.
+ * config/s390/s390-modes.def (CCO): New condition code mode.
+ * config/s390/s390.c (s390_match_ccmode_set): Handle E_CCOmode.
+ (s390_branch_condition_mask): Likewise.
+ * config/s390/s390.md ("addv<mode>4", "subv<mode>4")
+ ("mulv<mode>4"): New expanders.
+ ("*addv<mode>3_ccoverflow", "*addv<mode>3_ccoverflow_const")
+ ("*subv<mode>3_ccoverflow", "*mulv<mode>3_ccoverflow"): New
+ pattern definitions.
+
+2019-07-24 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ PR middle-end/91166
+ * match.pd (vec_perm_expr(v, v, mask) -> v): New pattern.
+ (define_predicates): Add entry for uniform_vector_p.
+ (vec_same_elem_p): New match pattern.
+
+2019-07-24 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR bootstrap/87030
+ * config/i386/darwin.h (REAL_LIBGCC_SPEC): Move from here...
+ * config/i386/darwin32-biarch.h .. to here.
+ * config/i386/darwin64-biarch.h: Adjust comments.
+ * config/rs6000/darwin32-biarch.h: Likewise.
+ * config/rs6000/darwin64-biarch.h: Likewise.
+ * config.gcc: Missed commit from r273746
+ (*-*-darwin*): Don't include CPU t-darwin here.
+ (i[34567]86-*-darwin*): Adjust to use biarch files. Produce
+ an error message if i686-darwin configuration is attempted for
+ Darwin >= 18.
+
+2019-07-23 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR bootstrap/87030
+ * config.gcc (*-*-darwin*): Don't include CPU t-darwin here.
+ (i[34567]86-*-darwin*): Adjust to use biarch files. Produce
+ an error message if i686-darwin configuration is attempted for
+ Darwin >= 18.
+ (x86_64-*-darwin*): Switch to single multilib for Darwin >= 18.
+ (powerpc-*-darwin*): Use biarch files where needed.
+ (powerpc64-*-darwin*): Likewise.
+ * config/i386/darwin.h (REAL_LIBGCC_SPEC): Move to new biarch file.
+ (DARWIN_ARCH_SPEC, DARWIN_SUBARCH_SPEC): Revise for default single
+ arch case.
+ * config/i386/darwin32-biarch.h: New.
+ * config/i386/darwin64.h: Rename.
+ * config/i386/darwin64-biarch.h: To this.
+ * config/i386/t-darwin: Rename.
+ * config/i386/t-darwin32-biarch: To this.
+ * config/i386/t-darwin64: Rename.
+ * config/i386/t-darwin64-biarch: To this.
+ * config/rs6000/darwin32-biarch.h: New.
+ * config/rs6000/darwin64.h: Rename.
+ * config/rs6000/darwin64-biarch.h: To this.
+ (DARWIN_ARCH_SPEC, DARWIN_SUBARCH_SPEC): Revise for default single
+ arch case.
+ * config/rs6000/t-darwin8: Rename.
+ * config/rs6000/t-darwin32-biarch: To this.
+ * config/rs6000/t-darwin64 Rename.
+ * config/rs6000/t-darwin64-biarch: To this.
+
2019-07-23 Martin Sebor <msebor@redhat.com>
* configure.ac (ACX_PROG_CXX_WARNING_OPTS): Revert r273311.
-2019-07-23 Vladislav Ivanishin <vlad@ispras.ru>
+2019-07-23 Vladislav Ivanishin <vlad@ispras.ru>
* gdbinit.in (reload-gdbhooks): New command with an attached doc string.
(rh): New alias for it.
-2019-07-23 Vladislav Ivanishin <vlad@ispras.ru>
+2019-07-23 Vladislav Ivanishin <vlad@ispras.ru>
* gdbhooks.py: Pass replace=True to
gdb.printing.register_pretty_printer.
@@ -194,7 +3155,7 @@
PR target/90363
* config/or1k/or1k.md (zero_extend<mode>si2): Update predicate.
(extend<mode>si2): Update predicate.
- * gcc/config/or1k/predicates.md (volatile_mem_operand): New.
+ * config/or1k/predicates.md (volatile_mem_operand): New.
(reg_or_mem_operand): New.
2019-07-21 Iain Sandoe <iain@sandoe.co.uk>
@@ -400,6 +3361,7 @@
2019-07-19 Jeff Law <law@redhat.com>
+ PR tree-optimization/86061
* tree-ssa-dse.c (initialize_ao_ref_for_dse): Handle
strncpy. Drop some trivial dead code.
(maybe_trim_memstar_call): Handle strncpy.
@@ -530,17 +3492,16 @@
2019-07-18 Sylvia Taylor <sylvia.taylor@arm.com>
- PR target/90317
- * config/arm/arm_neon.h
- (vsha1h_u32): Refactor.
- (vsha1cq_u32): Likewise.
- (vsha1pq_u32): Likewise.
- (vsha1mq_u32): Likewise.
- * config/arm/crypto.md:
- (crypto_sha1h): Remove zero extend, correct vec select.
- (crypto_sha1c): Correct vec select.
- (crypto_sha1m): Likewise.
- (crypto_sha1p): Likewise.
+ PR target/90317
+ * config/arm/arm_neon.h (vsha1h_u32): Refactor.
+ (vsha1cq_u32): Likewise.
+ (vsha1pq_u32): Likewise.
+ (vsha1mq_u32): Likewise.
+ * config/arm/crypto.md (crypto_sha1h): Remove zero extend, correct
+ vec select.
+ (crypto_sha1c): Correct vec select.
+ (crypto_sha1m): Likewise.
+ (crypto_sha1p): Likewise.
2019-07-18 Richard Earnshaw <rearnsha@arm.com>
@@ -562,7 +3523,7 @@
(rsbsi3_carryin_shift): Likewise.
(negsi2_carryin_compare): Likewise.
-2019-07-18 Bin Cheng <bin.linux@linux.alibaba.com>
+2019-07-18 Bin Cheng <bin.cheng@linux.alibaba.com>
PR tree-optimization/91137
* tree-ssa-loop-ivopts.c (struct ivopts_data): New field.
@@ -585,7 +3546,7 @@
* tree-ssa-sccvn.c (vn_walk_cb_data::push_partial_def): Refactor
branches to make code less indented.
-2019-07-17 Alexandre Oliva <oliva@adacore.com>
+2019-07-17 Alexandre Oliva <oliva@adacore.com>
PR middle-end/81824
* attribs.c (decls_mismatched_attributes): Simplify the logic
@@ -599,7 +3560,7 @@
(pa_reloc_rw_mask): Return 3 when generating PIC code and when
generating code for SOM targets earlier than HP-UX 11. Otherwise,
return 2 for SOM and 0 for other targets.
-
+
2019-07-17 Jeff Law <law@redhat.com>
* tree-ssa-dse.c (initialize_ao_ref_for_dse): Fix formatting.
@@ -841,7 +3802,7 @@
(*test<mode>_1): Use nonmemory_szext_operand mode attribute
instead of genera_operand mode attribute.
-2019-07-14 Vladislav Ivanishin <vlad@ispras.ru>
+2019-07-14 Vladislav Ivanishin <vlad@ispras.ru>
* gdbhooks.py (DumpFn.invoke): Add explicit casts of return values of
fopen and fclose to their respective types.
@@ -947,7 +3908,7 @@
* tree-vect-slp.c (vect_build_slp_tree_2): Fix reduction
chain check.
-2019-07-12 Alexandre Oliva <oliva@adacore.com>
+2019-07-12 Alexandre Oliva <oliva@adacore.com>
* tree-eh.c (honor_protect_cleanup_actions): Use outer_
rather than this_state as the lowering context for the ELSE
@@ -1017,7 +3978,7 @@
2019-07-12 Kewen Lin <linkw@gcc.gnu.org>
- * gcc/cfgrtl.c (print_rtl_with_bb): Emit a hint if the
+ * cfgrtl.c (print_rtl_with_bb): Emit a hint if the
fallthrough target of current basic block isn't the placed
right next.
@@ -2967,18 +5928,11 @@
* config/s390/subst.md: Remove addr_style_op and masked_op substs.
* config/s390/vector.md: Use new predicate.
-2019-07-08 Joern Rennecke <joern.rennecke@riscy-ip.com>
-
- Avoid clash with system header declaration.
- * testsuite/gcc.dg/vect/slp-reduc-sad.c (uint32_t):
- Remove unused declaration.
-
2019-07-08 Andrew Waterman <andrew@sifive.com>
Jim Wilson <jimw@sifive.com>
* config/riscv/riscv.md (lshrsi3_zero_extend_3+1): Use operands[1]
bitsize instead of BITS_PER_WORD.
- gcc/testsuite/
2019-07-08 Martin Liska <mliska@suse.cz>
@@ -3107,7 +6061,7 @@
* config/arm/sync.md
(@atomic_compare_and_swap<CCSI:arch><NARROW:mode>_1): Use
<NARROW:sync_predtab> instead of (implicitly) <CCSI:sync_predtab>.
- (@atomic_compare_and_swap<CCSI:arch><SIDI:mode>_1): Likewise
+ (@atomic_compare_and_swap<CCSI:arch><SIDI:mode>_1): Likewise use
<SIDI:sync_predtab>. Use <SIDI:cas_cmp_operand> and
<SIDI:cas_cmp_str>.
@@ -3238,7 +6192,7 @@
Support __builtin_expect_with_probability for analysis
of # of loop iterations.
-2019-07-04 Alexandre Oliva <oliva@adacore.com>
+2019-07-04 Alexandre Oliva <oliva@adacore.com>
* doc/generic.texi (Cleanups): Document EH_ELSE_EXPR.
* except.c: Likewise.
@@ -3406,7 +6360,6 @@
(output_addr_table): Add DWARF5 table header generation here after
checking there are actually any addresses from...
(dwarf2out_finish): ...here.
- * testsuite/g++.dg/pr90981.C: New test.
2019-07-03 Richard Biener <rguenther@suse.de>
@@ -3606,12 +6559,6 @@
conditional lastprivate clause(s), emit GOMP_loop_end_nowait call
at the end.
-2019-07-02 Joern Rennecke <joern.rennecke@riscy-ip.com>
-
- PR testsuite/91065
- * testsuite/gcc.dg/plugin/start_unit_plugin.c: Register a root tab
- to reference fake_var.
-
2019-07-02 qing zhao <qing.zhao@oracle.com>
PR preprocessor/90581
@@ -3685,7 +6632,7 @@
nonoverlapping_component_refs_since_match_p_may_alias,
nonoverlapping_component_refs_since_match_p_no_alias.
(dump_alias_stats): Update dumping.
- (aliasing_matching_component_refs_p): Break out from ...;
+ (aliasing_matching_component_refs_p): Break out from ...;
dispatch to nonoverlapping_component_refs_for_decl_p
and nonoverlapping_component_refs_since_match_p.
(aliasing_component_refs_p): ... here; call
@@ -3725,7 +6672,6 @@
PR middle-end/66726
* tree-ssa-phiopt.c (factor_out_conditional_conversion):
Tune heuristic from PR71016 to allow MIN / MAX.
- * testsuite/gcc.dg/tree-ssa/pr66726-4.c: New testcase.
2019-07-01 Segher Boessenkool <segher@kernel.crashing.org>
@@ -3885,7 +6831,7 @@
argument.
(free_page): Likewise.
-2019-07-01 Vladislav Ivanishin <vlad@ispras.ru>
+2019-07-01 Vladislav Ivanishin <vlad@ispras.ru>
* gdbhooks.py (GdbPrettyPrinters.add_printer_for_types): Reorder
parameter names to match usage (no functional change).
@@ -3959,7 +6905,7 @@
2019-06-28 Michael Meissner <meissner@linux.ibm.com>
- * config/rs6000/predicates.md (pcrel_address): Use
+ * config/rs6000/predicates.md (pcrel_address): Use
SYMBOL_REF_LOCAL_P to determine if a label is local.
(pcrel_external_address): New predicate.
(non_prefixed_mem_operand): Delete, predicate not used.
@@ -4052,7 +6998,7 @@
* config/rs6000/rs6000.c (darwin_rs6000_override_options): Do not
use longcall for 64b code.
-2019-06-27 Aaron Sawdey <acsawdey@linux.ibm.com>
+2019-06-27 Aaron Sawdey <acsawdey@linux.ibm.com>
* builtins.c (get_memory_rtx): Fix comment.
* optabs.def (movmem_optab): Change to cpymem_optab.
@@ -4257,7 +7203,7 @@
* tree-ssa-sccvn.c (vn_reference_lookup_3): Encode valueized RHS.
-2019-06-27 Jun Ma <JunMa@linux.alibaba.com>
+2019-06-27 Jun Ma <JunMa@linux.alibaba.com>
PR tree-optimization/89772
* gimple-fold.c (gimple_fold_builtin_memchr): consider trailing nuls in
@@ -4279,7 +7225,7 @@
2019-06-27 Kewen Lin <linkw@gcc.gnu.org>
PR target/62147
- * gcc/loop-iv.c (find_simple_exit): Call finite_loop_p to update
+ * loop-iv.c (find_simple_exit): Call finite_loop_p to update
finiteness.
2019-06-26 Jeff Law <law@redhat.com>
@@ -4576,28 +7522,15 @@
2019-06-25 Jozef Lawrynowicz <jozef.l@mittosystems.com>
- * gcc/c-family/c-common.c (c_common_nodes_and_builtins): Define
- alternate "__intN__" name for "__intN" types.
- * gcc/c/c-parser.c (c_parse_init): Create keyword for "__intN__" type.
- * gcc/cp/lex.c (init_reswords): Likewise.
- * gcc/config/msp430/msp430.h: Use __int20__ for SIZE_TYPE and
+ * config/msp430/msp430.h: Use __int20__ for SIZE_TYPE and
PTRDIFF_TYPE.
- * gcc/cp/cp-tree.h (cp_decl_specifier_seq): New bitfield "int_n_alt".
- * gcc/c/c-decl.c (declspecs_add_type): Don't pedwarn about "__intN" ISO
- C incompatibility if alternate "__intN__" form is used.
- * gcc/cp/decl.c (grokdeclarator): Likewise.
- * gcc/cp/parser.c (cp_parser_simple_type_specifier): Set
- decl_specs->int_n_alt if "__intN__" form is used.
- * gcc/gimple-ssa-sprintf.c (build_intmax_type_nodes): Accept "__intN__"
+ * gimple-ssa-sprintf.c (build_intmax_type_nodes): Accept "__intN__"
format of "__intN" types for UINTMAX_TYPE.
- * gcc/brig/brig-lang.c (brig_build_c_type_nodes): Accept "__intN__"
- format of "__intN" types for SIZE_TYPE.
- * gcc/lto/lto-lang.c (lto_build_c_type_nodes): Likewise.
- * gcc/stor-layout.c (initialize_sizetypes): Accept "__intN__"
+ * stor-layout.c (initialize_sizetypes): Accept "__intN__"
format of "__intN" types for SIZETYPE.
- * gcc/tree.c (build_common_tree_nodes): Accept "__intN__"
+ * tree.c (build_common_tree_nodes): Accept "__intN__"
format of "__intN" types for SIZE_TYPE and PTRDIFF_TYPE.
- * gcc/doc/invoke.texi: Document that __intN__ disables pedantic
+ * doc/invoke.texi: Document that __intN__ disables pedantic
warnings.
2019-06-25 Jan Hubicka <jh@suse.cz>
@@ -4808,7 +7741,7 @@
(vectorizable_scan_store): Adjust caller, use whole vector left shift
and additional VEC_COND_EXPR only for those iterations that need it.
-2019-06-20 Alexandre Oliva <oliva@adacore.com>
+2019-06-20 Alexandre Oliva <oliva@adacore.com>
* config.gcc: Fix ARM --with-fpu checking and error message.
@@ -5966,7 +8899,7 @@
(ATTR_MALLOC_WARN_UNUSED_RESULT_SIZE_1_NOTHROW_LEAF_LIST): New.
(ATTR_ALLOCA_SIZE_1_NOTHROW_LEAF_LIST): Remove.
(ATTR_ALLOCA_WARN_UNUSED_RESULT_SIZE_1_NOTHROW_LEAF_LIST): New.
- (ATTR_MALLOC_SIZE_1_2_NOTHROW_LEAF_LIST): Remove.
+ (ATTR_MALLOC_SIZE_1_2_NOTHROW_LEAF_LIST): Remove.
(ATTR_MALLOC_WARN_UNUSED_RESULT_SIZE_1_2_NOTHROW_LEAF_LIST):
New.
(ATTR_ALLOC_SIZE_2_NOTHROW_LEAF_LIST): Remove.
@@ -7215,7 +10148,7 @@
(ix86_adjust_stack_and_probe): Ditto.
(ix86_emit_probe_stack_range): Use gen_probe_stack_range instead
of ix86_gen_probe_stack_range.
- (ix86_expand_prologue): Use gen_pro_epilogue_adjust_stack_sub
+ (ix86_expand_prologue): Use gen_pro_epilogue_adjust_stack_sub
instead of gen_pro_epilogue_adjust_stack_{si,di}_sub.
* config/i386/x86-tune-sched.c (ix86_macro_fusion_pair_p):
Include insn-opinit.h. Use code_for_stack_protect_test_1 instead of
@@ -7584,12 +10517,6 @@
(rs6000_file_start): ..extracted from here, and modified to
test all ISA bits.
(rs6000_output_function_prologue): Emit .machine as necessary.
- * testsuite/gcc.target/powerpc/ppc32-abi-dfp-1.c: Don't use
- power mnemonics.
- * testsuite/gcc.dg/vect/O3-pr70130.c: Disable default options
- added by check_vect_support_and_set_flags.
- * testsuite/gcc.dg/vect/pr48765.c: Likewise.
- * testsuite/gfortran.dg/vect/pr45714-b.f: Likewise.
2019-05-22 Hans-Peter Nilsson <hp@axis.com>
@@ -7674,7 +10601,7 @@
* config/i386/i386.md (anddi_1 to andsi_1_zext splitter):
Avoid calling gen_lowpart with CONST operand.
-2019-05-21 Alexandre Oliva <aoliva@redhat.com>
+2019-05-21 Alexandre Oliva <aoliva@redhat.com>
* tree-ssa-threadupdate.c (struct ssa_local_info_t): Add
field template_last_to_copy.
@@ -7703,8 +10630,6 @@
PR target/90545
* config/rs6000/rs6000.c (rs6000_register_move_cost): Increase
power9 direct move cost.
- * testsuite/gcc.target/powerpc/fold-vec-splats-floatdouble.c:
- Correct comments and rename functions to suit parameters.
2019-05-21 Richard Biener <rguenther@suse.de>
@@ -7725,8 +10650,8 @@
edges if for_edge_insertion_p is false. Fix whitespace.
* tree-ssa-pre.c (pass_pre::execute): Call
split_edges_for_insertion instead of split_critical_edges.
- * gcc/tree-ssa-tail-merge.c (tail_merge_optimize): Ditto.
- * gcc/tree-ssa-sink.c (pass_sink_code::execute): Ditto.
+ * tree-ssa-tail-merge.c (tail_merge_optimize): Ditto.
+ * tree-ssa-sink.c (pass_sink_code::execute): Ditto.
(pass_data_sink_code): Update function name in the comment.
2019-05-21 Vladislav Ivanishin <vlad@ispras.ru>
@@ -8280,7 +11205,7 @@
* lto-streamer.h (LTO_major_version): Bump to 9.
-2019-05-16 Jun Ma <JunMa@linux.alibaba.com>
+2019-05-16 Jun Ma <JunMa@linux.alibaba.com>
PR tree-optimization/90106
* tree-call-cdce.c (shrink_wrap_one_built_in_call_with_conds): Add
@@ -10144,7 +13069,7 @@
PR target/84369
* config/rs6000/power9.md: Add store forwarding bypass.
-2019-04-16 Alexandre Oliva <aoliva@redhat.com>
+2019-04-16 Alexandre Oliva <aoliva@redhat.com>
PR debug/89528
* valtrack.c (dead_debug_insert_temp): Reset debug references
@@ -11172,7 +14097,6 @@
2019-03-27 Jeff Law <law@redhat.com>
-
PR rtl-optimization/87761
PR rtl-optimization/89826
* regcprop.c (copyprop_hardreg_forward_1): Move may_trap_p test
@@ -11289,7 +14213,7 @@
alignment in diagnostic. Avoid assuming argument fits in SHWI,
convert it to UHWI when it fits.
-2019-03-25 Johan Karlsson <johan.karlsson@enea.com>
+2019-03-25 Johan Karlsson <johan.karlsson@enea.com>
PR debug/86964
* dwarf2out.c (premark_used_variables): New function.
@@ -11762,7 +14686,7 @@
(altivec_expand_vec_ext_builtin): Use modular arithmetic to
compute index.
-2019-03-15 Alexandre Oliva <aoliva@redhat.com>
+2019-03-15 Alexandre Oliva <aoliva@redhat.com>
PR c++/88534
PR c++/88537
@@ -11956,7 +14880,7 @@
(s390_sched_reorder): Likewise.
(s390_sched_variable_issue): Rework and use new functions.
(s390_sched_init): Use new functions.
- * config/s390/s390.h (s390_tune_attr): Add z14.
+ * config/s390/s390.h (s390_tune_attr): Add z14.
* config/s390/s390.md: Add z14.
2019-03-12 Robin Dapp <rdapp@linux.ibm.com>
@@ -12814,8 +15738,6 @@
(__builtin_has_attribute): Add missing comma after @xref.
(__builtin_object_size): Ditto.
* doc/md.texi (cond_*{mode}): Use @samp instead of @var around op1[i].
- * fortran/invoke.texi (-ffpe-trap): Use @var for every item
- in the list.
2019-02-26 Jeff Law <law@redhat.com>
@@ -12873,7 +15795,7 @@
(_mm_cvttpd_epi32): Likewise.
PR target/89338
- * config/rs6000/xmmintrin.h (_mm_cvtss_f32): Fix type mismatch.
+ * config/rs6000/xmmintrin.h (_mm_cvtss_f32): Fix type mismatch.
(_mm_cvt_ss2si): Fix type mismatch and 32-bit.
PR target/89339
@@ -13236,7 +16158,7 @@
(diagnostic_show_locus): Use linenum_arith_t when iterating over
lines within each line_span.
-2019-02-20 Andre Vieira <andre.simoesdiasvieira@arm.com>
+2019-02-20 Andre Vieira <andre.simoesdiasvieira@arm.com>
PR target/86487
* lra-constraints.c(uses_hard_regs_p): Fix handling of
@@ -13245,7 +16167,7 @@
2019-02-20 Li Jia He <helijia@linux.ibm.com>
PR target/88100
- * gcc/config/rs6000/rs6000.c (rs6000_gimple_fold_builtin)
+ * config/rs6000/rs6000.c (rs6000_gimple_fold_builtin)
<case ALTIVEC_BUILTIN_VSPLTISB, ALTIVEC_BUILTIN_VSPLTISH,
ALTIVEC_BUILTIN_VSPLTISW>: Don't convert the operand before
range checking it.
@@ -13571,8 +16493,7 @@
* config/i386/i386.c (ix86_function_arg_advance): Remove
unrelated comment.
(struct builtin_isa): Remove leaf_p and nothrow_p fields.
- (def_builtin): Remove usage of dead
- fields.
+ (def_builtin): Remove usage of dead fields.
(ix86_add_new_builtins): Likewise.
* ipa-fnsummary.c (compute_fn_summary): Likewise.
* ipa-icf.c (sem_function::equals_wpa): Likewise.
@@ -14660,7 +17581,7 @@
* doc/invoke.texi: Add -menqcmd.
2019-01-23 Bin Cheng <bin.cheng@arm.com>
- Steve Ellcey <sellcey@marvell.com>
+ Steve Ellcey <sellcey@marvell.com>
PR target/85711
* recog.c (address_operand): Return false on wrong mode for address.
@@ -16226,7 +19147,7 @@
* config/aarch64/aarch64.c (aarch64_expand_prologue): Use new
epilogue/prologue scratch registers EP0_REGNUM and EP1_REGNUM.
(aarch64_expand_epilogue): Likewise.
- (aarch64_output_mi_thunk): Likewise
+ (aarch64_output_mi_thunk): Likewise.
* config/aarch64/aarch64.h (REG_CLASS_CONTENTS): Change
TAILCALL_ADDR_REGS to x16 and x17.
* config/aarch64/aarch64.md: Define EP0_REGNUM and EP1_REGNUM.
@@ -16516,7 +19437,7 @@
to propagate state.
(nvptx_shared_propagate): Initialize vector bcast partition and
synchronization state.
- (nvptx_single): Generalize to enable vectors to use shared-memory
+ (nvptx_single): Generalize to enable vectors to use shared-memory
to propagate state.
(nvptx_process_pars): Likewise.
(nvptx_set_current_function): Initialize oacc_broadcast_partition.
@@ -16822,11 +19743,11 @@
(format_string): Set unlikely range appropriately.
* gimple-fold.c (get_range_strlen): Update comments. Fix minor
formatting issues.
- (get_range_strlen): Accept c_strlen_data pointer for external
+ (get_range_strlen): Accept c_strlen_data pointer for external
call sites as well. Pass through to call to internal get_range_strlen.
Adjust minlen, maxlen and maxbound as needed.
(get_maxval_strlen): Update comments.
- (gimple_fold_builtin_strlen): Update call to get_range_strlen
+ (gimple_fold_builtin_strlen): Update call to get_range_strlen
to use c_strlen_data pointer. Change variable accesses to instead
use c_strlen_data data members.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 0d94c83..11222eb 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20190723
+20190819
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 64ac98b..e59b709 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,1027 @@
+2019-08-19 Bob Duff <duff@adacore.com>
+
+ * doc/gnat_rm/implementation_advice.rst: Fix documentation for
+ stream oriented attributes.
+ * gnat_rm.texi: Regenerate.
+
+2019-08-19 Gary Dismukes <dismukes@adacore.com>
+
+ * einfo.ads (E_Function, E_Procedure): Update comments to
+ reflect that Renamed_Entity is also used for nongeneric
+ subprograms.
+
+2019-08-19 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_prag.adb (Is_Before_First_Decl): Deal with rewritten
+ pragmas.
+
+2019-08-19 Bob Duff <duff@adacore.com>
+
+ * sem_warn.adb (Warn_On_Unreferenced_Entity): Suppress warning
+ on formal parameters of dispatching operations.
+
+2019-08-19 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_res.adb (Resolve_Call): A call to an expression function
+ freezes when expander is active, unless the call appears within
+ the body of another expression function,
+
+2019-08-19 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * libgnat/s-os_lib.ads, libgnat/s-os_lib.adb (To_Ada, To_C): New
+ routines.
+
+2019-08-19 Bob Duff <duff@adacore.com>
+
+ * exp_attr.adb (Attribute_Valid): Correct the handling of
+ private types where the full type is modular. System.Address is
+ an example. Otherwise, we convert uncheckedly to a signed type,
+ so we get an incorrect range 0 .. -1, for which all values will
+ fail. The 'Valid attribute is illegal for such types, but we
+ generate such illegal attribute_references for 'Valid_Scalars,
+ and we generate 'Valid_Scalars when the -gnateV switch is used.
+ Rename Btyp --> PBtyp to avoid hiding the outer Btyp, which was
+ confusing.
+ * libgnat/a-except.adb: Set the Exception_Raised component.
+ Otherwise, we have incorrect reads of invalid data.
+
+2019-08-19 Pierre-Marie de Rodat <derodat@adacore.com>
+
+ * libgnat/a-cgaaso.ads, libgnat/a-cgarso.ads,
+ libgnat/a-cogeso.ads, libgnat/a-contai.ads,
+ libgnat/a-locale.ads: Import documentation from the RM.
+
+2019-08-19 Jerome Guitton <guitton@adacore.com>
+
+ * Makefile.rtl (system.o): New target to add generation of
+ target properties.
+ * gcc-interface/Makefile.in (install-gnatlib): Install
+ ada_target_properties.
+
+2019-08-19 Eric Botcazou <ebotcazou@adacore.com>
+
+ * inline.adb (Add_Inlined_Body): Do not special-case instances
+ that are compilation units.
+ (Add_Pending_Instantiation): Likewise.
+ (Instantiate_Body): Skip instantiations that are compilation
+ units and have already been performed.
+ * sem_ch12.adb (Needs_Body_Instantiated): Do not special-case
+ instances that are compilation units.
+ (Load_Parent_Of_Generic): Be prepared for parent that is a
+ compilation unit but whose instantiation node has not been
+ replaced.
+
+2019-08-19 Eric Botcazou <ebotcazou@adacore.com>
+
+ * inline.adb (Initialize, Lock): Deal with
+ Called_Pending_Instantiations.
+
+2019-08-19 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch6.adb (Check_Synchronized_Overriding): Complete
+ predicate that applies legality check in 9.4 (11.9/2): if an
+ inherited subprogram is implemented by a protected procedure or
+ entry, its first paarameter must be out, in_out or
+ access_to_varible.
+
+2019-08-19 Javier Miranda <miranda@adacore.com>
+
+ PR ada/65696
+ * exp_atag.ads, exp_atag.adb (Build_Inherit_Predefined_Prims):
+ Adding formal to specify how many predefined primitives are
+ inherited from the parent type.
+ * exp_disp.adb (Number_Of_Predefined_Prims): New subprogram.
+ (Make_Secondary_DT): Compute the number of predefined primitives
+ of all tagged types (including tagged types not defined at
+ library level). Previously we unconditionally relied on the
+ Max_Predef_Prims constant value when building the dispatch
+ tables of tagged types not defined at library level (thus
+ consuming more memory for their dispatch tables than required).
+ (Make_DT): Compute the number of predefined primitives that must
+ be inherited from their parent type when building the dispatch
+ tables of tagged types not defined at library level. Previously
+ we unconditionally relied on the Max_Predef_Prims constant value
+ when building the dispatch tables of tagged types not defined at
+ library level (thus copying more data than required from the
+ parent type).
+
+2019-08-19 Bob Duff <duff@adacore.com>
+
+ * sem_ch13.adb (Record_Hole_Check): Procedure to check for holes
+ that incudes processing type extensions. A type extension is
+ processed by first calling Record_Hole_Check recursively on the
+ parent type to compute the bit number after the last component
+ of the parent.
+
+2019-08-19 Gary Dismukes <dismukes@adacore.com>
+
+ * checks.adb (Length_Mismatch_Info_Message): New function in
+ Selected_Length_Checks to return a message indicating the
+ element counts for the mismatched lengths for a failed
+ compile-time length check.
+ (Plural_Or_Singular_Ending): Support function in
+ Length_Mismatch_Info_Message to return either "" or "s", for
+ concatenating to the end of words.
+ (Selected_Length_Checks): Pass the result of
+ Length_Mismatch_Info_Message as an extra warning message to
+ Compile_Time_Constraint_Error to indicate the mismatched lengths
+ for a failed compile-time length check.
+ * sem_util.ads (Compile_Time_Constraint_Error): Add an optional
+ message formal (Extra_Msg), defaulted to the empty string.
+ * sem_util.adb (Compile_Time_Constraint_Error): Output an extra
+ message following the main warning message (when Extra_Msg is
+ not the empty string).
+
+2019-08-19 Patrick Bernardi <bernardi@adacore.com>
+
+ * socket.c: Removed the redefinition of getaddrinfo, getnameinfo
+ and freeaddrinfo to internal VxWorks kernel calls because they
+ are, well, internal kernel calls and cannot be called from RTPs.
+ VxWorks provides the necessary components to call these routines
+ directly.
+
+2019-08-19 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_dist.adb (Is_Generic_Actual_Subtype): New predicate.
+ (Build_From_Any_Call, Build_To_Any_Call, Build_TypeCode_Call):
+ Use it instead of Is_Generic_Actual_Type flag to detect subtypes
+ representing generic actual types.
+
+2019-08-19 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_warn.adb (Check_References, Generic_Body_Formal): When a
+ formal parameter of a generic subprogram is not referenced in
+ the body, place the corresponding warning on the corresponding
+ entity in the specification of the generic body, as is done for
+ non-generic subprograms.
+
+2019-08-19 Bob Duff <duff@adacore.com>
+
+ * errout.ads (Size_Too_Small_Message): New constant.
+ * errout.adb, freeze.adb, sem_ch13.adb: Use it.
+
+2019-08-19 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_dist.adb (Build_Package_Stubs): Do not specifically visit
+ the declarations of an N_Subprogram_Instantiation node.
+
+2019-08-19 Bob Duff <duff@adacore.com>
+
+ * doc/gnat_ugn/gnat_utility_programs.rst: Document missing
+ metrics switches.
+
+2019-08-19 Piotr Trojanek <trojanek@adacore.com>
+
+ * sem_ch12.adb (Get_Unit_Instantiation_Node): Simplify Nkind_In
+ membership test.
+ * sem.adb (Depends_On_Main): Whitespace cleanup; only assign a
+ local variable if needed.
+
+2019-08-19 Claire Dross <dross@adacore.com>
+
+ * sem_spark.ads, sem_spark.adb (Is_Pledge_Function): New
+ parameter of the generic. Function used to decide whether a
+ function is a pledge function.
+ (Check_Not_Borrowed): Disable check inside the second parameter
+ of a pledge function for the path borrowed by the first
+ parameter. Also disable checks for entities inside a Global
+ contract.
+
+2019-08-19 Joffrey Huguet <huguet@adacore.com>
+
+ * libgnat/a-cfdlli.ads, libgnat/a-cfhama.ads,
+ libgnat/a-cfinve.ads, libgnat/a-cforma.ads,
+ libgnat/a-cofove.ads, libgnat/a-cofuma.ads,
+ libgnat/a-cofuve.ads: Add formal function parameter "=" (L, R :
+ Element_Type) to the generic packages.
+
+2019-08-19 Eric Botcazou <ebotcazou@adacore.com>
+
+ * opt.ads: Clean up left-overs of earlier implementation in
+ comment:
+
+2019-08-19 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch3.adb (Derived_Enumeration_Type): Do no freeze anonymous
+ base type if the bounds in the derived type declaration are
+ literals of the type.
+
+2019-08-19 Yannick Moy <moy@adacore.com>
+
+ * sem_res.adb (Resolve_Call): Check non-aliasing rules before
+ GNATprove inlining.
+
+2019-08-19 Eric Botcazou <ebotcazou@adacore.com>
+
+ * inline.adb (Add_Inlined_Body): Do not add pending
+ instantiations.
+ * sem_ch12.adb (Needs_Body_Instantiated): New predicate.
+ (Analyze_Package_Instantiation): Use it to decide whether to add
+ a pending instantiation for the body of the package.
+
+2019-08-19 Olivier Hainque <hainque@adacore.com>
+
+ * gcc-interface/trans.c (Acc_Loop_to_gnu): Return the openacc
+ BIND_EXPR node we have constructed on purpose. Remove unused
+ variable.
+
+2019-08-19 Pierre-Marie de Rodat <derodat@adacore.com>
+
+ * gcc-interface/lang.opt (fdump-scos): Define.
+ * gcc-interface/misc.c (gnat_handle_option): Handle
+ OPT_fdump_scos.
+
+2019-08-14 Joffrey Huguet <huguet@adacore.com>
+
+ * libgnat/a-cofuba.ads: Add a Length attribute to type
+ Container. Add a type Array_Base which replaces the previous
+ Elements attribute of Container.
+ (Content_Init): New subprogram. It is used to initialize the
+ Base attribute of Container.
+ * libgnat/a-cofuba.adb (Resize): New subprogram. It is used to
+ resize the underlying array of a container if necessary.
+ (=, <=, Find, Get, Intersection, Length, Num_Overlaps, Set,
+ Union): Update to match changes in type declarations.
+ (Add): Modify body to damp the time and space cost in a specific
+ case.
+ (Content_Init): New subprogram. It is used to initialize the
+ Base attribute of Container.
+ (Remove): Modify body to damp the time and space cost in a
+ specific case.
+
+2019-08-14 Bob Duff <duff@adacore.com>
+
+ * sem_ch13.adb (Get_Alignment_Value): Return 1 for Alignment 0,
+ and do not give an error.
+ * doc/gnat_rm/representation_clauses_and_pragmas.rst: Update the
+ corresponding documentation.
+ * gnat_rm.texi: Regenerate.
+
+2019-08-14 Eric Botcazou <ebotcazou@adacore.com>
+
+ * inline.adb (Add_Pending_Instantiation): Fix off-by-one error
+ in the comparison against the maximum number of instantiations.
+
+2019-08-14 Eric Botcazou <ebotcazou@adacore.com>
+
+ * inline.adb (Add_Pending_Instantiation): Use greater-or-equal
+ in the comparison against the maximum number of instantiations.
+
+2019-08-14 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_aux.adb (Next_Rep_Item): If a node in the rep chain
+ involves a Ghost aspect it may have been replaced by a null
+ statement; use the original node to find next Rep_Item.
+ * repinfo.adb (List_Entities): Do not list an Ignored
+ Ghost_Entity, for which information may have been deleted.
+
+2019-08-14 Bob Duff <duff@adacore.com>
+
+ * sem_prag.ads, sem_prag.adb
+ (Process_Compile_Time_Warning_Or_Error): In parameterless
+ version, improve detection of whether we are in a generic unit
+ to cover the case of an instance within a generic unit.
+ (Process_Compile_Time_Warning_Or_Error): Rename the
+ two-parameter version to be
+ Validate_Compile_Time_Warning_Or_Error, and do not export it.
+ Issue a warning if the condition is not known at compile time.
+ The key point is that the warning must be given only for pragmas
+ deferred to the back end, because the back end discovers
+ additional values that are known at compile time. Previous
+ changes in this ticket have enabled this by deferring to the
+ back end without checking for special cases such as 'Size.
+ (Validate_Compile_Time_Warning_Or_Error): Rename to be
+ Defer_Compile_Time_Warning_Error_To_BE.
+ * warnsw.ads, warnsw.adb (Warn_On_Unknown_Compile_Time_Warning):
+ Add new switches -gnatw_c and -gnatw_C to control the above
+ warning.
+ * doc/gnat_ugn/building_executable_programs_with_gnat.rst:
+ Document new switches.
+ * gnat_ugn.texi: Regenerate.
+
+2019-08-14 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch12.adb (Might_Inline_Subp): Rework comment and restrict
+ the shortcut based on Is_Inlined to the back-end inlining case.
+
+2019-08-14 Bob Duff <duff@adacore.com>
+
+ * inline.adb (Check_And_Split_Unconstrained_Function): Ignore
+ protected functions to get rid of spurious error. The
+ transformation done by this procedure triggers legality errors
+ in the generated code in this case.
+
+2019-08-14 Bob Duff <duff@adacore.com>
+
+ * sem_prag.adb (Process_Compile_Time_Warning_Or_Error): Defer
+ processing to the back end in all cases where the pragma's
+ condition is not known at compile time during the front end
+ (except in generics), as opposed to detecting 'Size attributes
+ and the like. This ensures that we take advantage of whatever
+ can be compile-time known after running the back end, as opposed
+ to having the front end guess what the back end can do. Remove
+ a little duplicated code at the call site.
+ * gnat1drv.adb (Post_Compilation_Validation_Checks): Unlock the
+ Elists while in Validate_Compile_Time_Warning_Errors, because it
+ does analysis and name resolution, which sometimes involves
+ adding Elists.
+
+2019-08-14 Eric Botcazou <ebotcazou@adacore.com>
+
+ * einfo.ads (Is_Called): Document new usage on E_Package
+ entities.
+ * einfo.adb (Is_Called): Accept E_Package entities.
+ (Set_Is_Called): Likewise.
+ * exp_ch6.adb (Expand_Call_Helper): Move code dealing with
+ instances for back-end inlining to Add_Inlined_Body.
+ * inline.ads: Remove with clauses for Alloc and Table.
+ (Pending_Instantiations): Move to...
+ * inline.adb: Add with clauses for Alloc, Uintp, Table and
+ GNAT.HTable.
+ (Backend_Instances): New variable.
+ (Pending_Instantiations): ...here.
+ (Called_Pending_Instantiations): New table.
+ (Node_Table_Size): New constant.
+ (Node_Header_Num): New subtype.
+ (Node_Hash): New function.
+ (To_Pending_Instantiations): New hash table.
+ (Add_Inlined_Body): Bail out early for subprograms in the main
+ unit or subunit. Likewise if the Is_Called flag is set. If the
+ subprogram is an instance, invoke Add_Inlined_Instance. Call
+ Set_Is_Called earlier. If the subrogram is within an instance,
+ invoke Add_Inlined_Instance. Also deal with the case where the
+ call itself is within an instance.
+ (Add_Inlined_Instance): New procedure.
+ (Add_Inlined_Subprogram): Remove conditions always fulfilled.
+ (Add_Pending_Instantiation): Move the defence against ludicruous
+ number of instantiations to here. When back-end inlining is
+ enabled, associate an instantiation with its index in table and
+ mark a few selected kinds of instantiations as always needed.
+ (Initialize): Set Backend_Instances to No_Elist.
+ (Instantiate_Body): New procedure doing the work extracted
+ from...
+ (Instantiate_Bodies): ...here. When back-end inlining is
+ enabled, loop over Called_Pending_Instantiations instead of
+ Pending_Instantiations.
+ (Is_Nested): Minor tweak.
+ (List_Inlining_Info): Also list the contents of
+ Backend_Instances.
+ * sem_ch12.adb (Might_Inline_Subp): Return early if Is_Inlined
+ is set and otherwise set it before returning true.
+ (Analyze_Package_Instantiation): Remove the defence against
+ ludicruous number of instantiations. Invoke
+ Remove_Dead_Instance instead of doing the removal manually if
+ there is a guaranteed ABE.
+
+2019-08-14 Gary Dismukes <dismukes@adacore.com>
+
+ * exp_ch3.adb (Predef_Spec_Or_Body): For an equality operation
+ of an interface type, create an expression function (that
+ returns False) rather than declaring an abstract function.
+ * freeze.adb (Check_Inherited_Conditions): Set Needs_Wrapper to
+ False unconditionally at the start of the loop creating wrappers
+ for inherited operations.
+
+2019-08-14 Bob Duff <duff@adacore.com>
+
+ * table.adb: Assert that the table is not locked when increasing
+ Last, even if it doesn't cause reallocation. In other words,
+ assert that on operations that MIGHT cause reallocation.
+ * table.ads: Fix comment accordingly.
+
+2019-08-14 Arnaud Charlet <charlet@adacore.com>
+
+ * doc/gnat_ugn/gnat_and_program_execution.rst: Remove
+ documentation of gnatelim.
+
+2019-08-14 Bob Duff <duff@adacore.com>
+
+ * sem_prag.adb (Validate_Compile_Time_Warning_Error): Attach the
+ warning to the Sloc of the first pragma argument, rather than to
+ the pragma itself. This is to make pragmas processed after the
+ back end use the same Sloc as pragmas processed earlier, in the
+ front end. There's no reason for this discrepancy, and it
+ hinders further work on this ticket.
+
+2019-08-14 Bob Duff <duff@adacore.com>
+
+ * sem.ads (Inside_A_Generic): Remove the ??? comment.
+
+2019-08-14 Eric Botcazou <ebotcazou@adacore.com>
+
+ * inline.ads (Pending_Descriptor): Delete.
+ * inline.adb (Initialize): Do not initialize it.
+ * sem_ch12.adb (Delay_Descriptors): Delete.
+ (Analyze_Package_Instantiation): Call
+ Set_Delay_Subprogram_Descriptors instead of Delay_Descriptors
+ throughout.
+
+2019-08-14 Bob Duff <duff@adacore.com>
+
+ * exp_aggr.adb (Init_Hidden_Discriminants): Avoid processing the
+ wrong discriminant, which could be of the wrong type.
+
+2019-08-14 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch12.adb (Analyze_Instance_And_Renamings): Do not reset
+ the Is_Generic_Instance flag previously set on the package
+ generated for the instantiation of a generic subprogram.
+
+2019-08-14 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Quantified_Expression): Freeze
+ explicitly the type of the loop parameter.
+
+2019-08-14 Javier Miranda <miranda@adacore.com>
+
+ * sem_util.adb (New_Copy_Tree.Copy_Node_With_Replacement):
+ Update the Chars attribute of identifiers.
+
+2019-08-14 Yannick Moy <moy@adacore.com>
+
+ * sem_spark.adb, sem_spark.ads (Is_Legal): New function exposed
+ for use in GNATprove, to test legality rules not related to
+ permissions.
+ (Check_Declaration_Legality): Extract the part of
+ Check_Declaration that checks rules not related to permissions.
+ (Check_Declaration): Call the new Check_Declaration_Legality.
+ (Check_Type_Legality): Rename of Check_Type. Introduce
+ parameters to force or not checking, and update a flag detecting
+ illegalities.
+ (Check_Node): Ignore attribute references in statement position.
+
+2019-08-14 Yannick Moy <moy@adacore.com>
+
+ * sem_spark.adb (Check_Old_Loop_Entry): New procedure to check
+ correct use of Old and Loop_Entry.
+ (Check_Node): Check subprogram contracts.
+ (Check_Pragma): Check Loop_Variant.
+ (Check_Safe_Pointers): Apply checking to library-level
+ subprogram declarations as well, in order to check their
+ contract.
+
+2019-08-14 Yannick Moy <moy@adacore.com>
+
+ * sem_spark.adb (Is_Subpath_Expression): Take into account
+ conversion and qualification.
+
+2019-08-14 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch7.adb (Install_Private_Declarations)
+ <Swap_Private_Dependents>: Do not rely solely on the
+ Is_Child_Unit flag on the unit to recurse.
+ (Uninstall_Declarations) <Swap_Private_Dependents>: New
+ function. Use it to recurse on the private dependent entities
+ for child units.
+
+2019-08-14 Javier Miranda <miranda@adacore.com>
+
+ * exp_aggr.adb (Is_CCG_Supported_Aggregate): Return False for
+ arrays with bounds not known at compile time.
+
+2019-08-14 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_util.adb (New_Copy_Tree, Visit_Entity): A quantified
+ expression includes the implicit declaration of the loop
+ parameter. When a quantified expression is copied during
+ expansion, for example when building the precondition code from
+ the generated pragma, a new loop parameter must be created for
+ the new tree, to prevent duplicate declarations for the same
+ symbol.
+
+2019-08-14 Yannick Moy <moy@adacore.com>
+
+ * sem_disp.adb (Check_Dispatching_Operation): Update assertion
+ for the separate declarations created in GNATprove mode.
+ * sem_disp.ads (Is_Overriding_Subprogram): Update comment.
+ * sem_elab.adb (SPARK_Processor): Fix test for checking of
+ overriding primitives.
+
+2019-08-14 Eric Botcazou <ebotcazou@adacore.com>
+
+ * inline.adb (Add_Inlined_Body): Tweak comments.
+ (List_Inlining_Info): Also list information about non-main
+ units.
+
+2019-08-14 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_ch4.adb (Analyze_Selected_Component): In the case where
+ the prefix is of a concurrent type, and the selected entity
+ matching the selector is the first private declaration of the
+ type (such as the first local variable in a task's body), set
+ Is_Private_Op.
+
+2019-08-14 Piotr Trojanek <trojanek@adacore.com>
+
+ * einfo.adb (Is_Generic_Actual_Subprogram): Replace repeated
+ calls to Ekind with Ekind_In.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR middle-end/91421
+ * gcc-interface/trans.c (gigi): Call set_decl_buillt_in_function.
+ (Call_to_gnu): Use DECL_FE_FUNCTION_CODE instead of DECL_FUNCTION_CODE.
+
+2019-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * ali.ads (Linker_Option_Record): Remove Original_Pos component.
+ * ali.adb (Scan_ALI): Do not set it.
+
+2019-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch3.adb (Build_Derived_Concurrent_Type): Add a couple of
+ local variables and use them. When the derived type fully
+ constrains the parent type, rewrite it as a subtype of an
+ implicit (unconstrained) derived type instead of the other way
+ around.
+ (Copy_And_Build): Deal with concurrent types and use predicates.
+ (Build_Derived_Private_Type): Build the full derivation if
+ needed for concurrent types too.
+ (Build_Derived_Record_Type): Add marker comment.
+ (Complete_Private_Subtype): Use predicates.
+
+2019-08-13 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch3.adb (Check_Generic_Ancestor): New subprogram,
+ aubsidiary to Build_Derived_Record_Type. to enforce the rule
+ that a type extension declared in a generic body cznnot have an
+ ancestor that is a generic formal (RM 3.9.1 (4/2)). The rule
+ applies to all ancestors of the type, including interface
+ progenitors.
+
+2019-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch3.adb (Build_Underlying_Full_View): Delete.
+ (Complete_Private_Subtype): Do not set the full view on the
+ private subtype here. If the full base is itself derived from
+ private, do not re-derive the parent type but instead constrain
+ an existing underlying full view.
+ (Prepare_Private_Subtype_Completion): Do not get to the
+ underlying full view, if any. Set the full view on the private
+ subtype here.
+ (Process_Full_View): Likewise.
+ * sem_ch12.adb (Check_Generic_Actuals): Also set
+ Is_Generic_Actual_Type on the full view if the type of the
+ actual is private.
+ (Restore_Private_Views): Also reset Is_Generic_Actual_Type on
+ the full view if the type of the actual is private.
+ * sem_eval.adb (Subtypes_Statically_Match): Remove bypass for
+ generic actual types.
+
+2019-08-13 Javier Miranda <miranda@adacore.com>
+
+ * sem_res.adb (Resolve_Selected_Component): When the type of the
+ component is an access to a class-wide type and the type of the
+ context is an access to a tagged type the relevant type is that
+ of the component (since in such case we may need to generate
+ implicit type conversions or dispatching calls).
+
+2019-08-13 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_aggr.adb (Aggr_Assignment_OK_For_Backend): Preanalyze
+ expression, rather do a full analysis, to prevent unwanted
+ removal of side effects which mask the intent of the expression.
+
+2019-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * impunit.adb (Non_Imp_File_Names_95): Add
+ GNAT.Branch_Prediction.
+
+2019-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch6.adb: Remove with and use clauses for Sem_Ch12.
+ (Expand_Call_Helper): Swap the back-end inlining case and the
+ special front-end expansion case. In back-end inlining mode, do
+ not invoke Add_Inlined_Body unless the call may be inlined.
+ * inline.ads (Add_Pending_Instantiation): New function moved
+ from...
+ * inline.adb (Add_Inlined_Body): Simplify comment. Turn test on
+ the enclosing unit into assertion.
+ (Add_Pending_Instantiation): New function moved from...
+ * sem_ch12.ads (Add_Pending_Instantiation): ...here.
+ * sem_ch12.adb (Add_Pending_Instantiation): ...here.
+
+2019-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem.adb (Do_Analyze): Recompute Style_Check_Max_Line_Length
+ after restoring Style_Max_Line_Length.
+
+2019-08-13 Arnaud Charlet <charlet@adacore.com>
+
+ * sem_ch13.adb (Check_Iterator_Functions): Protect against
+ cascaded errors.
+
+2019-08-13 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch8.adb (Analyze_Subprogram_Renaming): Do no suppress mode
+ conformance checks on child unit instance that is a compilation
+ unit.
+
+2019-08-13 Gary Dismukes <dismukes@adacore.com>
+
+ * exp_dbug.adb (Fully_Qualify_Name): Add full name qualification
+ for the E_Exception case.
+
+2019-08-13 Gary Dismukes <dismukes@adacore.com>
+
+ * exp_aggr.adb (Aggr_Size_OK): Compute the aggregate size using
+ universal arithmetic, to avoid situations where the size
+ computation overflows.
+
+2019-08-13 Justin Squirek <squirek@adacore.com>
+
+ * repinfo.adb (List_Scalar_Storage_Order): Modify conditionals
+ for displaying ordering to always be triggered when -gnatR4 is
+ in effect.
+
+2019-08-13 Justin Squirek <squirek@adacore.com>
+
+ * aspects.adb, aspects.ads: Register new aspect.
+ * par-prag.adb (Prag): Register new pragma
+ * sem_ch13.adb (Analyze_Aspect_Specifications): Add processing
+ for new aspect similar to Aspect_Max_Entry_Queue_Length.
+ * sem_prag.adb, sem_prag.ads (Analyze_Pragma): Register new
+ pragma and set it to use the same processing as
+ Pragma_Max_Queue_Length.
+ * snames.ads-tmpl: Move definition of
+ Name_Max_Entry_Queue_Length so that it can be processed as a
+ pragma in addition to a restriction and add an entry for the
+ pragma itself.
+
+2019-08-13 Yannick Moy <moy@adacore.com>
+
+ * sem_ch4.adb (Analyze_Allocator): Do not insert subtype
+ declaration for allocator inside a spec expression.
+
+2019-08-13 Yannick Moy <moy@adacore.com>
+
+ * sem_res.adb (Resolve_Call): Do not inline calls inside record
+ types.
+
+2019-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_ch4.adb (Analyze_One_Call): Remove bypass for type
+ mismatch in nested instantiations.
+ * sem_ch8.adb (Find_Nearer_Entity): New function.
+ (Find_Renamed_Entity): Use it to disambiguate the candidates for
+ the renaming generated for an instantiation when it is
+ ambiguous.
+
+2019-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat1drv.adb (Adjust_Global_Switches): Do not set
+ Back_End_Inlining in ASIS mode either.
+
+2019-08-13 Olivier Hainque <hainque@adacore.com>
+
+ * libgnat/s-win32.ads: Define size_t and fix the MapViewOfFile
+ binding to use it instead of DWORD for the dwNumberOfBytesToMap
+ argument.
+ * libgnat/g-sercom__mingw.adb (Read): State which definition of
+ size_t to fetch in call to Last_Index.
+
+2019-08-13 Arnaud Charlet <charlet@adacore.com>
+
+ * gcc-interface/Make-lang.in: Remove unused TRACE variable. Pass
+ LN_S to relevant gnatlib targets.
+ * gcc-interface/Makefile.in: Systematically pass LN_S to
+ relevant gnatlib targets.
+
+2019-08-13 Yannick Moy <moy@adacore.com>
+
+ * sem_dim.adb (Analyze_Dimension,
+ Analyze_Dimension_Array_Aggregate, Analyze_Dimension_Call,
+ Analyze_Dimension_Extension_Or_Record_Aggregate): Return
+ immediately when inside an inlined body.
+ * sem_res.adb (Resolve_Call): Remove special checking now done
+ inside Analyze_Dimension_Call.
+
+2019-08-13 Justin Squirek <squirek@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Allocator): Add condition to detect
+ library-level object declarations
+
+2019-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * doc/gnat_ugn/building_executable_programs_with_gnat.rst
+ (-gnateT): Document Double_Float_Alignment parameter and fix
+ description of Double_Scalar_Alignment parameter.
+ * gnat_ugn.texi: Regenerate.
+
+2019-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch6.adb (Expand_Call_Helper): If back-end inlining is
+ enabled, also instantiate the body of a generic unit containing
+ a subprogram subject to aspect/pragma Inline_Always at
+ optimization level zero.
+ * sem_ch12.adb (Might_Inline_Subp): Minor tweak.
+ (Analyze_Package_Instantiation): Do not instantiate the package
+ body because of inlining considerations if the instantiation is
+ done in a generic unit. Move around similar condition involving
+ the main unit. Add test on Back_End_Inlining to processing for
+ front-end inlining.
+
+2019-08-13 Javier Miranda <miranda@adacore.com>
+
+ * exp_disp.adb (Make_Secondary_DT): Handle record type
+ derivations that have interface components located at fixed
+ positions and interface components located at variable offset.
+ The offset of components located at fixed positions is computed
+ using the dummy object (similar to the case where all the
+ interface components are located at fixed positions).
+ (Make_DT): Build the dummy object for all tagged types that
+ implement interface types (that is, build it also for types with
+ variable size components), and use the dummy object to compute
+ the offset of all tag components located at fixed positions when
+ initializing the Interface_Table object.
+
+2019-08-13 Justin Squirek <squirek@adacore.com>
+
+ * gnatcmd.adb (GNATCmd): Add constant for new compiler switch
+ --help-ada, and include usage subprogram. Add line to usage help
+ explaining the new flag.
+ (GNATCmd_Usage): Rename from locally declared Usage so as not to
+ confuse with the newly imported version. Add new argument case
+ for --help-ada and add bug report email to implicit display of
+ help without the --help flag so as to unify output between the
+ two cases.
+
+2019-08-13 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * libgnat/g-comlin.adb (Getopt): Quote unrecognized switch in
+ Invalid_Switch exception message.
+
+2019-08-13 Yannick Moy <moy@adacore.com>
+
+ * sem_util.adb (Traverse_More_Func): Take into account
+ Loop_Actions inside N_Iterated_Component_Association nodes.
+ * sinfo.ads: Document correctly Loop_Actions as a field of nodes
+ of kind N_Iterated_Component_Association.
+
+2019-08-13 Claire Dross <dross@adacore.com>
+
+ * libgnat/a-cfinve.adb, libgnat/a-cofove.adb (Find_Index,
+ Reverse_Find_Index): Use bigger type to avoid range check
+ failure at the last loop iteration.
+
+2019-08-12 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * libgnat/g-socket.adb (Is_IPv6_Address): Check that no less
+ then 2 colons in IPv6 numeric address.
+
+2019-08-12 Dmitriy Anisimkov <anisimko@adacore.com>
+
+ * libgnat/g-comlin.ads, libgnat/g-comlin.adb (Getopt): Add
+ parameter Quiet. Need to do not output error messages to
+ console. Invalid_Switch exception generation surrounded by an
+ error message.
+
+2019-08-12 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch6.adb (Expand_Actuals. Add_Call_By_Copy_Code): Add code
+ to generate proper checks when an actual for an in-out or out
+ parameter has a non-null access type. No constraints are
+ applied to an inbound access parameter, but on exit a not-null
+ check must be performed if the type of the actual requires it.
+
+2019-08-12 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_util.adb (Is_Expaned_Priority_Attribute): Check whether
+ call comes from a rewritten attribute before comparing name with
+ Get_Ceiling run-time subprogram.
+
+2019-08-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_util.ads (Component_May_Be_Bit_Aligned): Small comment
+ tweaks.
+ (Possible_Bit_Aligned_Component): Likewise.
+ (Type_May_Have_Bit_Aligned_Components): Likewise.
+ * exp_util.adb (Component_May_Be_Bit_Aligned): Likewise.
+ (Possible_Bit_Aligned_Component): Likewise.
+ (Type_May_Have_Bit_Aligned_Components): Likewise.
+
+2019-08-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Op_Eq): Expand the array equality if
+ either operand is a possibly unaligned slice.
+ * exp_ch6.adb (Expand_Simple_Function_Return): Do not generate a
+ copy for a possibly unaligned object if it is represented as a
+ scalar.
+ * exp_util.adb (Is_Possibly_Unaligned_Slice): Do not always
+ return false if the target doesn't have strict alignment.
+
+2019-08-12 Bob Duff <duff@adacore.com>
+
+ * sem_ch12.adb (Instantiate_Package_Body): Remove suppression of
+ checks in instances of internal units.
+ * sem_ch6.adb (Analyze_Function_Return): Do not generate a
+ constraint check on an extended_return_statement if the subtype
+ of the return object in the statement is identical to the return
+ subtype of the function.
+
+2019-08-12 Bob Duff <duff@adacore.com>
+
+ * libgnat/a-cbmutr.adb (Is_Reachable): Declare Idx to be of the
+ base subtype. Clearly it makes no sense to loop "while Idx >=
+ 0", if Idx is of a nonnegative subtype.
+
+2019-08-12 Bob Duff <duff@adacore.com>
+
+ * libgnat/a-tifiio.adb (Put_Scaled): Prevent AA from being
+ negative, since Field is range 0 .. something.
+
+2019-08-12 Bob Duff <duff@adacore.com>
+
+ * doc/gnat_ugn/gnat_utility_programs.rst (gnatmetric, gnatpp,
+ gnatstub): Remove documentation for Ada language version
+ switches, and note that they are no longer needed.
+
+2019-08-12 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_ch5.adb (Prepare_Param_Spec_Loop): Set the parents of the
+ copied low and high bounds in the case where the loop range is
+ given by a discrete_subtype_indication, to prevent hanging (or
+ Assert_Failure) in Insert_Actions.
+
+2019-08-12 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch6.adb (heck_Untagged_Equality): Verify that user-defined
+ equality has the same profile as the predefined equality before
+ applying legality rule in RM 4.5.2 (9.8).
+
+2019-08-12 Bob Duff <duff@adacore.com>
+
+ * libgnat/a-except.ads: Update obsolete comment, still making
+ clear that this is a variant. Add explicit default for Id
+ component of Exception_Occurrence, because that value is used.
+ Define Null_Occurrence less redundantly.
+ * libgnat/a-einuoc.adb: Minor simplification of code.
+
+2019-08-12 Justin Squirek <squirek@adacore.com>
+
+ * libgnat/a-dhfina.adb, libgnat/a-dhfina.ads (Is_Simple_Name,
+ Is_Root_Directory, Is_Parent_Directory,
+ Is_Current_Directory_Name, Is_Relative_Name, Initial_Directory,
+ Relative_Name, Compose): Add implementation and documentation.
+ * libgnat/a-direct.adb (Containing_Directory): Modify routine to
+ use routines from Ada.Directories.Hierarchical_File_Names and
+ remove incorrect special case for parent directories.
+ (Fetch_Next_Entry): Add check for current directory and parent
+ directory and ignore them under certain circumstances.
+ (Simple_Nmae): Add check for null result from
+ Simple_Name_Internal and raise Name_Error.
+ (Simple_Name_Internal): Add explicit check for root directories,
+ sanitize trailing directory separators, and modify behavior so
+ that current and parent directories are considered valid
+ results.
+ * Makefile.rtl: Add entry to GNATRTL_NONTASKING_OBJS.
+
+2019-08-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * freeze.adb (Freeze_Entity): Give the same error for an
+ Object_Size clause on a variable-sized type as for a Size
+ clause.
+
+2019-08-12 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_prag.adb (Analyze_Pragma, Pragma_Suppress_Initialization):
+ For private types, set the Suppress_Initialization flag on the
+ Full_View of the entity rather than the entity's base type.
+
+2019-08-12 Yannick Moy <moy@adacore.com>
+
+ * aspects.adb, aspects.ads (Aspect_No_Caching): New aspect.
+ * contracts.adb, contracts.ads (Add_Contract_Item): Add handling
+ of No_Caching.
+ (Analyze_Object_Contract): Add handling of No_Caching.
+ * einfo.adb, einfo.ads
+ (Get_Pragma): Add handling of No_Caching.
+ * doc/gnat_rm/implementation_defined_aspects.rst,
+ doc/gnat_rm/implementation_defined_pragmas.rst: Document new
+ aspect/pragma.
+ * gnat_rm.texi: Regenerate.
+ * par-prag.adb (Prag): New pragma Pragma_No_Caching.
+ * sem_ch13.adb (Analyze_Aspect_Specifications,
+ Check_Aspect_At_Freeze_Point): Add handling of No_Caching.
+ * sem_prag.adb (Analyze_Pragma): Deal with pragma No_Caching.
+ * sem_prag.ads (Analyze_External_Property_In_Decl_Part): Now
+ applies to No_Caching.
+ * sem_util.adb, sem_util.ads (Is_Effectively_Volatile): Add
+ handling of No_Caching.
+ (No_Caching_Enabled): New query function.
+ * snames.ads-tmpl: New names for pragma.
+
+2019-08-12 Yannick Moy <moy@adacore.com>
+
+ * sem_util.adb, sem_util.ads (Traverse_More_Func,
+ Traverse_More_Proc): Add formal parameter for Itypes traversal.
+
+2019-08-12 Yannick Moy <moy@adacore.com>
+
+ * exp_attr.adb, exp_attr.ads (Expand_Size_Attribute): New
+ procedure to share part of the attribute expansion with
+ GNATprove mode.
+ (Expand_N_Attribute_Reference): Extract part of the
+ Size/Object_Size expansion in the new procedure
+ Expand_Size_Attribute.
+ * exp_spark.adb (Expand_SPARK_N_Attribute_Reference): Expand
+ Size/Object_Size attributes using the new procedure
+ Expand_Size_Attribute.
+
+2019-08-12 Yannick Moy <moy@adacore.com>
+
+ * exp_spark.adb (Expand_SPARK_N_Attribute_Reference): Only
+ expand Enum_Rep attribute when its parameter is a literal.
+
+2019-08-12 Justin Squirek <squirek@adacore.com>
+
+ * sem_eval.adb (Check_Non_Static_Context): Add a condition to
+ determine if a range violation constitues a warning or an error.
+ (Out_Of_Range): Add a condition to determine if a range
+ violation constitues a warning or an error.
+
+2019-08-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch4.adb (Real_Range_Check): Do not rewrite the conversion
+ node but its expression instead, after having fetched its
+ current value. Clear the Do_Range_Check flag on entry. Return
+ early for a rewritten float-to-float conversion. Remove
+ redundant local variable. Suppress all checks when inserting
+ the temporary and do not reanalyze the node.
+
+2019-08-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sprint.ads: Minor comment tweak.
+
+2019-08-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * checks.adb (Insert_Valid_Check): Do not retrieve the
+ Do_Range_Check flag from the Original_Node but from the
+ Validated_Object. Remove useless bypass for floating-point
+ types.
+
+2019-08-12 Yannick Moy <moy@adacore.com>
+
+ * sem_util.adb, sem_util.ads (Traverse_More_Func,
+ Traverse_More_Proc): New traversal subprograms.
+
+2019-08-12 Jerome Lambourg <lambourg@adacore.com>
+
+ * libgnarl/s-taprop__vxworks.adb (Abort_Handler): Only call
+ s-tpopsp.Self when actually needed.
+
+2019-08-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch4.adb (Discrete_Range_Check): Return if checks are
+ suppressed.
+
+2019-08-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * sem_res.adb: Add with & use clause for Sem_Mech and
+ alphabetize.
+ (Resolve_Actuals): Do not apply a scalar range check for the
+ source of a conversion whose result is passed by reference to a
+ valued procedure.
+
+2019-08-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * checks.adb (Insert_Valid_Check): Reset the Do_Range_Check flag
+ on the validated object.
+ * exp_ch6.adb (Add_Call_By_Copy_Code): Reset the Do_Range_Check
+ flag on the actual here, as well as on the Expression if the
+ actual is a N_Type_Conversion node.
+ (Add_Validation_Call_By_Copy_Code): Generate the incoming range
+ check if needed and reset the Do_Range_Check flag on the
+ Expression if the actual is a N_Type_Conversion node.
+ (Expand_Actuals): Do not reset the Do_Range_Check flag here.
+ Generate the incoming range check for In parameters here instead
+ of...
+ (Expand_Call_Helper): ...here. Remove redudant condition.
+ * sem_res.adb (Resolve_Actuals): Use local variable A_Typ and
+ remove obsolete comments.
+ (Resolve_Type_Conversion): Do not force the Do_Range_Check flag
+ on the operand if range checks are suppressed.
+
+2019-08-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * checks.adb (Activate_Range_Check): Remove redundant argument.
+ (Generate_Range_Check): Likewise.
+ (Apply_Float_Conversion_Check): Reset the Do_Range_Check flag on
+ entry and remove redundant condition.
+
+2019-08-02 Alexandre Oliva <oliva@adacore.com>
+
+ * libgnat/a-exexpr.adb (Begin_Handler_v1, End_Handler_v1): New.
+ (Claimed_Cleanup): New.
+ (Begin_Handler, End_Handler): Document.
+ * gcc-interface/trans.c (gigi): Switch to exception handler
+ ABI #1.
+ (Exception_Handler_to_gnu_gcc): Save the original cleanup
+ returned by begin handler, pass it to end handler, and use
+ EH_ELSE_EXPR to pass a propagating exception to end handler.
+ (gnat_to_gnu): Leave the exception pointer alone for reraise.
+ (add_cleanup): Handle EH_ELSE_EXPR, require it by itself.
+
2019-07-23 Ed Schonberg <schonberg@adacore.com>
* sem_ch13.adb (Check_Aspect_At_End_Of_Declarations,
@@ -268,7 +1292,7 @@
2019-07-22 Ed Schonberg <schonberg@adacore.com>
- * freeze.adb (Freeze_Fixed_Point_Type): When freezing a
+ * freeze.adb (Freeze_Fixed_Point_Type): When freezing a
fixed-point subtype, check whether the parent type declarastion
includes an aspect specification for the 'Small type attribute,
and inherit the specified value.
@@ -1932,7 +2956,7 @@
* libgnat/g-traceb.ads, libgnat/g-traceb.adb (Call_Chain): New
function.
-2019-07-04 James Clarke <jrtc27@debian.org>
+2019-07-04 James Clarke <jrtc27@debian.org>
* libgnarl/s-osinte__kfreebsd-gnu.ads (clockid_t): Make type
definition public.
@@ -2495,7 +3519,7 @@
2019-07-03 Ed Schonberg <schonberg@adacore.com>
- * inline.adb (Make_Loop_Labels_Unique): New procedure to modify
+ * inline.adb (Make_Loop_Labels_Unique): New procedure to modify
the source code of subprograms that are inlined by the
front-end, to prevent accidental duplication between loop labels
in the inlined code and the code surrounding the inlined call.
diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index 6528df8..c1a422f 100644
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -171,6 +171,7 @@ GNATRTL_NONTASKING_OBJS= \
a-cwila1$(objext) \
a-cwila9$(objext) \
a-decima$(objext) \
+ a-dhfina$(objext) \
a-diocst$(objext) \
a-direct$(objext) \
a-direio$(objext) \
@@ -2695,6 +2696,18 @@ setup-rts: force
# propagation of exceptions cannot itself be compiled with checks that
# may give rise to exceptions, e.g. stack overflow checks.
+# Generate target-dependent info into a file named ada_target_properties.
+# This information is used by tools for static analysis: they need to know
+# the size of standard types for a given run-time library. This metadata
+# is meant to be saved at the root of the run-time directory.
+
+ADA_TARGET_PROPERTIES = -gnatet=ada_target_properties
+
+system.o : system.ads
+ $(ADAC) -c $(ALL_ADAFLAGS) $(ADA_INCLUDES) $< \
+ $(ADA_TARGET_PROPERTIES) \
+ $(OUTPUT_OPTION)
+
# Force no sibling call optimization on s-traceb.o so the number of stack
# frames to be skipped when computing a call chain is not modified by
# optimization. We don't want inlining, either.
diff --git a/gcc/ada/ali.adb b/gcc/ada/ali.adb
index feea73f..ab98104 100644
--- a/gcc/ada/ali.adb
+++ b/gcc/ada/ali.adb
@@ -3204,9 +3204,6 @@ package body ALI is
Linker_Options.Table (Linker_Options.Last).Internal_File :=
Is_Internal_File_Name (F);
-
- Linker_Options.Table (Linker_Options.Last).Original_Pos :=
- Linker_Options.Last;
end if;
-- If there are notes present, scan them
diff --git a/gcc/ada/ali.ads b/gcc/ada/ali.ads
index fc6e592..22bf8a2 100644
--- a/gcc/ada/ali.ads
+++ b/gcc/ada/ali.ads
@@ -725,15 +725,11 @@ package ALI is
-- Set True if the linker options are from an internal file. This is
-- used to insert certain standard entries after all the user entries
-- but before the entries from the run-time.
-
- Original_Pos : Positive;
- -- Keep track of original position in the linker options table. This
- -- is used to implement a stable sort when we sort the linker options
- -- table.
end record;
- -- The indexes of active entries in this table range from 1 to the
- -- value of Linker_Options.Last. The zero'th element is for sort call.
+ -- The indexes of active entries in this table range from 1 to
+ -- the value of Linker_Options.Last. The zero'th element is for
+ -- convenience if the table needs to be sorted.
package Linker_Options is new Table.Table (
Table_Component_Type => Linker_Option_Record,
@@ -770,8 +766,8 @@ package ALI is
end record;
-- The indexes of active entries in this table range from 1 to the
- -- value of Linker_Options.Last. The zero'th element is for convenience
- -- if the table needs to be sorted.
+ -- value of Notes.Last. The zero'th element is for convenience if
+ -- the table needs to be sorted.
package Notes is new Table.Table (
Table_Component_Type => Notes_Record,
diff --git a/gcc/ada/aspects.adb b/gcc/ada/aspects.adb
index 54c0e56..d582abf 100644
--- a/gcc/ada/aspects.adb
+++ b/gcc/ada/aspects.adb
@@ -572,7 +572,9 @@ package body Aspects is
Aspect_Lock_Free => Aspect_Lock_Free,
Aspect_Machine_Radix => Aspect_Machine_Radix,
Aspect_Max_Entry_Queue_Depth => Aspect_Max_Entry_Queue_Depth,
+ Aspect_Max_Entry_Queue_Length => Aspect_Max_Entry_Queue_Length,
Aspect_Max_Queue_Length => Aspect_Max_Queue_Length,
+ Aspect_No_Caching => Aspect_No_Caching,
Aspect_No_Elaboration_Code_All => Aspect_No_Elaboration_Code_All,
Aspect_No_Inline => Aspect_No_Inline,
Aspect_No_Return => Aspect_No_Return,
diff --git a/gcc/ada/aspects.ads b/gcc/ada/aspects.ads
index 2a6acc2..64b0ff7 100644
--- a/gcc/ada/aspects.ads
+++ b/gcc/ada/aspects.ads
@@ -116,8 +116,10 @@ package Aspects is
Aspect_Link_Name,
Aspect_Linker_Section, -- GNAT
Aspect_Machine_Radix,
- Aspect_Max_Entry_Queue_Depth,
+ Aspect_Max_Entry_Queue_Depth, -- GNAT
+ Aspect_Max_Entry_Queue_Length,
Aspect_Max_Queue_Length, -- GNAT
+ Aspect_No_Caching, -- GNAT
Aspect_Object_Size, -- GNAT
Aspect_Obsolescent, -- GNAT
Aspect_Output,
@@ -252,6 +254,7 @@ package Aspects is
Aspect_Invariant => True,
Aspect_Lock_Free => True,
Aspect_Max_Entry_Queue_Depth => True,
+ Aspect_Max_Entry_Queue_Length => True,
Aspect_Max_Queue_Length => True,
Aspect_Object_Size => True,
Aspect_Persistent_BSS => True,
@@ -375,7 +378,9 @@ package Aspects is
Aspect_Linker_Section => Expression,
Aspect_Machine_Radix => Expression,
Aspect_Max_Entry_Queue_Depth => Expression,
+ Aspect_Max_Entry_Queue_Length => Expression,
Aspect_Max_Queue_Length => Expression,
+ Aspect_No_Caching => Optional_Expression,
Aspect_Object_Size => Expression,
Aspect_Obsolescent => Optional_Expression,
Aspect_Output => Name,
@@ -485,7 +490,9 @@ package Aspects is
Aspect_Lock_Free => Name_Lock_Free,
Aspect_Machine_Radix => Name_Machine_Radix,
Aspect_Max_Entry_Queue_Depth => Name_Max_Entry_Queue_Depth,
+ Aspect_Max_Entry_Queue_Length => Name_Max_Entry_Queue_Length,
Aspect_Max_Queue_Length => Name_Max_Queue_Length,
+ Aspect_No_Caching => Name_No_Caching,
Aspect_No_Elaboration_Code_All => Name_No_Elaboration_Code_All,
Aspect_No_Inline => Name_No_Inline,
Aspect_No_Return => Name_No_Return,
@@ -762,7 +769,9 @@ package Aspects is
Aspect_Initial_Condition => Never_Delay,
Aspect_Initializes => Never_Delay,
Aspect_Max_Entry_Queue_Depth => Never_Delay,
+ Aspect_Max_Entry_Queue_Length => Never_Delay,
Aspect_Max_Queue_Length => Never_Delay,
+ Aspect_No_Caching => Never_Delay,
Aspect_No_Elaboration_Code_All => Never_Delay,
Aspect_No_Tagged_Streams => Never_Delay,
Aspect_Obsolescent => Never_Delay,
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index 708bd9e..03cfcef 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -445,7 +445,7 @@ package body Checks is
procedure Activate_Range_Check (N : Node_Id) is
begin
- Set_Do_Range_Check (N, True);
+ Set_Do_Range_Check (N);
Possible_Local_Raise (N, Standard_Constraint_Error);
end Activate_Range_Check;
@@ -2031,6 +2031,12 @@ package body Checks is
return;
end if;
+ -- Here we will generate an explicit range check, so we don't want to
+ -- set the Do_Range check flag, since the range check is taken care of
+ -- by the code we will generate.
+
+ Set_Do_Range_Check (Ck_Node, False);
+
if not Compile_Time_Known_Value (LB)
or not Compile_Time_Known_Value (HB)
then
@@ -2079,7 +2085,6 @@ package body Checks is
if Nkind (Ck_Node) = N_Real_Literal
and then Etype (Ck_Node) = Universal_Real
and then Is_Integer_Type (Target_Typ)
- and then Nkind (Parent (Ck_Node)) = N_Type_Conversion
then
declare
Int_Val : constant Uint := UR_To_Uint (Realval (Ck_Node));
@@ -6936,7 +6941,7 @@ package body Checks is
-- flag set, we do not want to generate the explicit range check code.
if GNATprove_Mode or else not Expander_Active then
- Set_Do_Range_Check (N, True);
+ Set_Do_Range_Check (N);
return;
end if;
@@ -7583,16 +7588,19 @@ package body Checks is
Suppress => Validity_Check);
Set_Validated_Object (Var_Id, New_Copy_Tree (Exp));
+
Rewrite (Exp, New_Occurrence_Of (Var_Id, Loc));
- PV := New_Occurrence_Of (Var_Id, Loc);
- -- Copy the Do_Range_Check flag over to the new Exp, so it doesn't
- -- get lost. Floating point types are handled elsewhere.
+ -- Move the Do_Range_Check flag over to the new Exp so it doesn't
+ -- get lost and doesn't leak elsewhere.
- if not Is_Floating_Point_Type (Typ) then
- Set_Do_Range_Check (Exp, Do_Range_Check (Original_Node (Exp)));
+ if Do_Range_Check (Validated_Object (Var_Id)) then
+ Set_Do_Range_Check (Exp);
+ Set_Do_Range_Check (Validated_Object (Var_Id), False);
end if;
+ PV := New_Occurrence_Of (Var_Id, Loc);
+
-- Otherwise the expression does not denote a variable. Force its
-- evaluation by capturing its value in a constant. Generate:
@@ -9534,6 +9542,12 @@ package body Checks is
-- Returns expression to compute:
-- Typ'Length /= Expr'Length
+ function Length_Mismatch_Info_Message
+ (Left_Element_Count : Uint;
+ Right_Element_Count : Uint) return String;
+ -- Returns a message indicating how many elements were expected
+ -- (Left_Element_Count) and how many were found (Right_Element_Count).
+
---------------
-- Add_Check --
---------------
@@ -9721,6 +9735,36 @@ package body Checks is
Right_Opnd => Get_N_Length (Expr, Indx));
end Length_N_Cond;
+ ----------------------------------
+ -- Length_Mismatch_Info_Message --
+ ----------------------------------
+
+ function Length_Mismatch_Info_Message
+ (Left_Element_Count : Uint;
+ Right_Element_Count : Uint) return String
+ is
+
+ function Plural_Vs_Singular_Ending (Count : Uint) return String;
+ -- Returns an empty string if Count is 1; otherwise returns "s"
+
+ function Plural_Vs_Singular_Ending (Count : Uint) return String is
+ begin
+ if Count = 1 then
+ return "";
+ else
+ return "s";
+ end if;
+ end Plural_Vs_Singular_Ending;
+
+ begin
+ return "expected " & UI_Image (Left_Element_Count)
+ & " element"
+ & Plural_Vs_Singular_Ending (Left_Element_Count)
+ & "; found " & UI_Image (Right_Element_Count)
+ & " element"
+ & Plural_Vs_Singular_Ending (Right_Element_Count);
+ end Length_Mismatch_Info_Message;
+
-----------------
-- Same_Bounds --
-----------------
@@ -9915,12 +9959,16 @@ package body Checks is
if L_Length > R_Length then
Add_Check
(Compile_Time_Constraint_Error
- (Wnode, "too few elements for}??", T_Typ));
+ (Wnode, "too few elements for}??", T_Typ,
+ Extra_Msg => Length_Mismatch_Info_Message
+ (L_Length, R_Length)));
elsif L_Length < R_Length then
Add_Check
(Compile_Time_Constraint_Error
- (Wnode, "too many elements for}??", T_Typ));
+ (Wnode, "too many elements for}??", T_Typ,
+ Extra_Msg => Length_Mismatch_Info_Message
+ (L_Length, R_Length)));
end if;
-- The comparison for an individual index subtype
diff --git a/gcc/ada/contracts.adb b/gcc/ada/contracts.adb
index 4610b53..981bb91 100644
--- a/gcc/ada/contracts.adb
+++ b/gcc/ada/contracts.adb
@@ -317,6 +317,7 @@ package body Contracts is
-- Effective_Reads
-- Effective_Writes
-- Global
+ -- No_Caching
-- Part_Of
elsif Ekind (Id) = E_Variable then
@@ -327,6 +328,7 @@ package body Contracts is
Name_Effective_Reads,
Name_Effective_Writes,
Name_Global,
+ Name_No_Caching,
Name_Part_Of)
then
Add_Classification;
@@ -741,6 +743,7 @@ package body Contracts is
AW_Val : Boolean := False;
ER_Val : Boolean := False;
EW_Val : Boolean := False;
+ NC_Val : Boolean := False;
Items : Node_Id;
Prag : Node_Id;
Ref_Elmt : Elmt_Id;
@@ -847,6 +850,14 @@ package body Contracts is
Check_External_Properties (Obj_Id, AR_Val, AW_Val, ER_Val, EW_Val);
end if;
+ -- Analyze the non-external volatility property No_Caching
+
+ Prag := Get_Pragma (Obj_Id, Pragma_No_Caching);
+
+ if Present (Prag) then
+ Analyze_External_Property_In_Decl_Part (Prag, NC_Val);
+ end if;
+
-- The anonymous object created for a single concurrent type carries
-- pragmas Depends and Globat of the type.
diff --git a/gcc/ada/contracts.ads b/gcc/ada/contracts.ads
index 0dc5ff9..ca99c34 100644
--- a/gcc/ada/contracts.ads
+++ b/gcc/ada/contracts.ads
@@ -50,6 +50,7 @@ package Contracts is
-- Initial_Condition
-- Initializes
-- Interrupt_Handler
+ -- No_Caching
-- Part_Of
-- Postcondition
-- Precondition
diff --git a/gcc/ada/doc/gnat_rm/implementation_advice.rst b/gcc/ada/doc/gnat_rm/implementation_advice.rst
index b006f32..31376d9 100644
--- a/gcc/ada/doc/gnat_rm/implementation_advice.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_advice.rst
@@ -703,23 +703,23 @@ Followed.
.. index:: Stream oriented attributes
-RM 13.13.2(17): Stream Oriented Attributes
-==========================================
+RM 13.13.2(1.6): Stream Oriented Attributes
+===========================================
+
+ "If not specified, the value of Stream_Size for an elementary type
+ should be the number of bits that corresponds to the minimum number of
+ stream elements required by the first subtype of the type, rounded up
+ to the nearest factor or multiple of the word size that is also a
+ multiple of the stream element size."
- "If a stream element is the same size as a storage element, then the
- normal in-memory representation should be used by ``Read`` and
- ``Write`` for scalar objects. Otherwise, ``Read`` and ``Write``
- should use the smallest number of stream elements needed to represent
- all values in the base range of the scalar type."
+Followed, except that the number of stream elements is a power of 2.
+The Stream_Size may be used to override the default choice.
-Followed. By default, GNAT uses the interpretation suggested by AI-195,
-which specifies using the size of the first subtype.
However, such an implementation is based on direct binary
-representations and is therefore target- and endianness-dependent.
-To address this issue, GNAT also supplies an alternate implementation
-of the stream attributes ``Read`` and ``Write``,
-which uses the target-independent XDR standard representation
-for scalar types.
+representations and is therefore target- and endianness-dependent. To
+address this issue, GNAT also supplies an alternate implementation of
+the stream attributes ``Read`` and ``Write``, which uses the
+target-independent XDR standard representation for scalar types.
.. index:: XDR representation
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_aspects.rst b/gcc/ada/doc/gnat_rm/implementation_defined_aspects.rst
index 0fa4476..89f6718 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_aspects.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_aspects.rst
@@ -370,6 +370,12 @@ Aspect Max_Queue_Length
This aspect is equivalent to :ref:`pragma Max_Queue_Length<Pragma-Max_Queue_Length>`.
+Aspect No_Caching
+=================
+.. index:: No_Caching
+
+This boolean aspect is equivalent to :ref:`pragma No_Caching<Pragma-No_Caching>`.
+
Aspect No_Elaboration_Code_All
==============================
.. index:: No_Elaboration_Code_All
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
index 04b0def..a4ff222 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_pragmas.rst
@@ -3881,6 +3881,20 @@ such a way that a body needed before is no longer needed. The provision of a
dummy body with a No_Body pragma ensures that there is no interference from
earlier versions of the package body.
+.. _Pragma-No_Caching:
+
+Pragma No_Caching
+=================
+
+Syntax:
+
+.. code-block:: ada
+
+ pragma No_Caching [ (boolean_EXPRESSION) ];
+
+For the semantics of this pragma, see the entry for aspect ``No_Caching`` in
+the SPARK 2014 Reference Manual, section 7.1.2.
+
Pragma No_Component_Reordering
==============================
@@ -7355,6 +7369,7 @@ validity checks as shown in the following example:
pragma Validity_Checks (On); -- turn validity checks back on
A := C; -- C will be validity checked
+.. _Pragma-Volatile:
Pragma Volatile
===============
diff --git a/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst b/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst
index 82dc97c..efcdc80 100644
--- a/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst
+++ b/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst
@@ -30,9 +30,11 @@ Alignment Clauses
.. index:: Alignment Clause
-GNAT requires that all alignment clauses specify a power of 2, and all
-default alignments are always a power of 2. The default alignment
-values are as follows:
+GNAT requires that all alignment clauses specify 0 or a power of 2, and
+all default alignments are always a power of 2. Specifying 0 is the
+same as specifying 1.
+
+The default alignment values are as follows:
* *Elementary Types*.
@@ -610,23 +612,23 @@ alignment of the type (this is true for all types). In some cases the
end record;
-On a typical 32-bit architecture, the X component will occupy four bytes
-and the Y component will occupy one byte, for a total of 5 bytes. As a
-result ``R'Value_Size`` will be 40 (bits) since this is the minimum size
-required to store a value of this type. For example, it is permissible
-to have a component of type R in an array whose component size is
-specified to be 40 bits.
-
-However, ``R'Object_Size`` will be 64 (bits). The difference is due to
-the alignment requirement for objects of the record type. The X
-component will require four-byte alignment because that is what type
-Integer requires, whereas the Y component, a Character, will only
-require 1-byte alignment. Since the alignment required for X is the
-greatest of all the components' alignments, that is the alignment
-required for the enclosing record type, i.e., 4 bytes or 32 bits. As
-indicated above, the actual object size must be rounded up so that it is
-a multiple of the alignment value. Therefore, 40 bits rounded up to the
-next multiple of 32 yields 64 bits.
+On a typical 32-bit architecture, the X component will occupy four bytes
+and the Y component will occupy one byte, for a total of 5 bytes. As a
+result ``R'Value_Size`` will be 40 (bits) since this is the minimum size
+required to store a value of this type. For example, it is permissible
+to have a component of type R in an array whose component size is
+specified to be 40 bits.
+
+However, ``R'Object_Size`` will be 64 (bits). The difference is due to
+the alignment requirement for objects of the record type. The X
+component will require four-byte alignment because that is what type
+Integer requires, whereas the Y component, a Character, will only
+require 1-byte alignment. Since the alignment required for X is the
+greatest of all the components' alignments, that is the alignment
+required for the enclosing record type, i.e., 4 bytes or 32 bits. As
+indicated above, the actual object size must be rounded up so that it is
+a multiple of the alignment value. Therefore, 40 bits rounded up to the
+next multiple of 32 yields 64 bits.
For all other types, the ``Object_Size``
and ``Value_Size`` are the same (and equivalent to the RM attribute ``Size``).
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 2e867e2..913d6b9 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
@@ -1714,11 +1714,13 @@ Alphabetical List of All Switches
GCC macro ``BITS_PER_WORD`` documented as follows: `Number of bits in a word;
normally 32.`
- ``Double_Scalar_Alignment`` is the alignment for a scalar whose size is two
- machine words. It should be the same as the alignment for C ``long_long`` on
- most targets.
+ ``Double_Float_Alignment``, if not zero, is the maximum alignment that the
+ compiler can choose by default for a 64-bit floating-point type or object.
- ``Maximum_Alignment`` is the maximum alignment that the compiler might choose
+ ``Double_Scalar_Alignment``, if not zero, is the maximum alignment that the
+ compiler can choose by default for a 64-bit or larger scalar type or object.
+
+ ``Maximum_Alignment`` is the maximum alignment that the compiler can choose
by default for a type or object, which is also the maximum alignment that can
be specified in GNAT. It is computed for GCC backends as ``BIGGEST_ALIGNMENT
/ BITS_PER_UNIT`` where GCC macro ``BIGGEST_ALIGNMENT`` is documented as
@@ -2970,7 +2972,7 @@ of the pragma in the :title:`GNAT_Reference_manual`).
component for which no component clause is present.
-.. index:: -gnatwC (gcc)
+.. index:: -gnatw.C (gcc)
:switch:`-gnatw.C`
*Suppress warnings on missing component clauses.*
@@ -2979,6 +2981,30 @@ of the pragma in the :title:`GNAT_Reference_manual`).
missing a component clause in the situation described above.
+.. index:: -gnatw_c (gcc)
+
+:switch:`-gnatw_c`
+ *Activate warnings on unknown condition in Compile_Time_Warning.*
+
+ .. index:: Compile_Time_Warning
+ .. index:: Compile_Time_Error
+
+ This switch activates warnings on a pragma Compile_Time_Warning
+ or Compile_Time_Error whose condition has a value that is not
+ known at compile time.
+ The default is that such warnings are generated.
+
+
+.. index:: -gnatw_C (gcc)
+
+:switch:`-gnatw_C`
+ *Suppress warnings on missing component clauses.*
+
+ This switch supresses warnings on a pragma Compile_Time_Warning
+ or Compile_Time_Error whose condition has a value that is not
+ known at compile time.
+
+
.. index:: -gnatwd (gcc)
:switch:`-gnatwd`
diff --git a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
index de348e9..d2675c7 100644
--- a/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
+++ b/gcc/ada/doc/gnat_ugn/gnat_and_program_execution.rst
@@ -1406,18 +1406,8 @@ This section presents several topics related to program performance.
It first describes some of the tradeoffs that need to be considered
and some of the techniques for making your program run faster.
-.. only:: PRO or GPL
-
- It then documents the unused subprogram/data elimination feature
- and the ``gnatelim`` tool,
- which can reduce the size of program executables.
-
-
-.. only:: FSF
-
- It then documents the unused subprogram/data elimination feature,
- which can reduce the size of program executables.
-
+It then documents the unused subprogram/data elimination feature,
+which can reduce the size of program executables.
.. _Performance_Considerations:
@@ -2596,261 +2586,6 @@ It can be observed that the procedure ``Unused`` and the object
``Unused_Data`` are removed by the linker when using the
appropriate options.
-.. only:: PRO or GPL
-
- .. _Reducing_Size_of_Ada_Executables_with_gnatelim:
-
- Reducing Size of Ada Executables with ``gnatelim``
- --------------------------------------------------
-
- .. index:: gnatelim
-
- This section describes ``gnatelim``, a tool which detects unused
- subprograms and helps the compiler to create a smaller executable for your
- program.
-
- ``gnatelim`` is a project-aware tool.
- (See :ref:`Using_Project_Files_with_GNAT_Tools` for a description of
- the project-related switches but note that ``gnatelim`` does not support
- the :samp:`-U {main_unit}`, :samp:`--subdirs={dir}`, or
- :samp:`--no_objects_dir` switches.)
- The project file package that can specify
- ``gnatelim`` switches is named ``Eliminate``.
-
- .. _About_gnatelim:
-
- About ``gnatelim``
- ^^^^^^^^^^^^^^^^^^
-
- When a program shares a set of Ada
- packages with other programs, it may happen that this program uses
- only a fraction of the subprograms defined in these packages. The code
- created for these unused subprograms increases the size of the executable.
-
- ``gnatelim`` tracks unused subprograms in an Ada program and
- outputs a list of GNAT-specific pragmas ``Eliminate`` marking all the
- subprograms that are declared but never called. By placing the list of
- ``Eliminate`` pragmas in the GNAT configuration file :file:`gnat.adc` and
- recompiling your program, you may decrease the size of its executable,
- because the compiler will not generate the code for 'eliminated' subprograms.
- See ``Pragma_Eliminate`` in the :title:`GNAT_Reference_Manual` for more
- information about this pragma.
-
- ``gnatelim`` needs as its input data the name of the main subprogram.
-
- If a set of source files is specified as ``gnatelim`` arguments, it
- treats these files as a complete set of sources making up a program to
- analyse, and analyses only these sources.
-
- If ``gnatelim`` is called with a project file and :samp:`-U` option is
- used, then in process all the files from the argument project but
- not just the closure of the main subprogram.
-
- In all the other cases (that are typical cases of ``gnatelim`` usage, when
- the only ``gnatelim`` parameter is the name of the source file containing
- the main subprogram) gnatelim needs the full closure of the main subprogram.
- When called with a project file, gnatelim computes this closure itself.
- Otherwise it assumes that it can reuse the results of the previous
- build of the main subprogram.
-
- If the set of sources to be processed by ``gnatelim`` contains sources with
- preprocessing directives
- then the needed options should be provided to run preprocessor as a part of
- the ``gnatelim`` call, and the generated set of pragmas ``Eliminate``
- will correspond to preprocessed sources.
-
-
- .. _Running_gnatelim:
-
- Running ``gnatelim``
- ^^^^^^^^^^^^^^^^^^^^
-
- ``gnatelim`` has the following command-line interface:
-
-
- ::
-
- $ gnatelim [switches] -main=`main_unit_name {filename} [-cargs gcc_switches]
-
- ``main_unit_name`` should be a name of a source file that contains the main
- subprogram of a program (partition).
-
- Each ``filename`` is the name (including the extension) of a source
- file to process. 'Wildcards' are allowed, and
- the file name may contain path information.
-
- ``gcc_switches`` is a list of switches for
- ``gcc``. They will be passed on to all compiler invocations made by
- ``gnatelim`` to generate the ASIS trees. Here you can provide
- :switch:`-I` switches to form the source search path,
- use the :switch:`-gnatec` switch to set the configuration file,
- use the :switch:`-gnat05` switch if sources should be compiled in
- Ada 2005 mode etc.
-
- ``gnatelim`` has the following switches:
-
-
- .. index:: --version (gnatelim)
-
- :samp:`--version`
- Display Copyright and version, then exit disregarding all other options.
-
-
- .. index:: --help (gnatelim)
-
- :samp:`--help`
- Display usage, then exit disregarding all other options.
-
-
- .. index:: -P (gnatelim)
-
- :samp:`-P {file}`
- Indicates the name of the project file that describes the set of sources
- to be processed.
-
-
- .. index:: -X (gnatelim)
-
- :samp:`-X{name}={value}`
- Indicates that external variable ``name`` in the argument project
- has the value ``value``. Has no effect if no project is specified as
- tool argument.
-
-
- .. index:: --RTS (gnatelim)
-
- :samp:`--RTS={rts-path}`
- Specifies the default location of the runtime library. Same meaning as the
- equivalent ``gnatmake`` flag (:ref:`Switches_for_gnatmake`).
-
-
- .. index:: -U (gnatelim)
-
- :samp:`-U`
- Process all the sources from the argument project. If no project file
- is specified, this option has no effect. If this option is used with the
- project file, ``gnatelim`` does not require the preliminary build of the
- argument main subprogram.
-
-
- .. index:: -files (gnatelim)
-
- :samp:`-files={filename}`
- Take the argument source files from the specified file. This file should be an
- ordinary text file containing file names separated by spaces or
- line breaks. You can use this switch more than once in the same call to
- ``gnatelim``. You also can combine this switch with
- an explicit list of files.
-
-
- .. index:: -log (gnatelim)
-
- :samp:`-log`
- Duplicate all the output sent to :file:`stderr` into a log file. The log file
- is named :file:`gnatelim.log` and is located in the current directory.
-
- .. index:: --no-elim-dispatch (gnatelim)
-
- :samp:`--no-elim-dispatch`
- Do not generate pragmas for dispatching operations.
-
-
- .. index:: --ignore (gnatelim)
-
- :samp:`--ignore={filename}`
- Do not generate pragmas for subprograms declared in the sources
- listed in a specified file
-
- .. index:: -o (gnatelim)
-
-
- :samp:`-o={report_file}`
- Put ``gnatelim`` output into a specified file. If this file already exists,
- it is overridden. If this switch is not used, ``gnatelim`` outputs its results
- into :file:`stderr`
-
-
- .. index:: -j (gnatelim)
-
- :samp:`-j{n}`
- Use ``n`` processes to carry out the tree creations (internal representations
- of the argument sources). On a multiprocessor machine this speeds up processing
- of big sets of argument sources. If ``n`` is 0, then the maximum number of
- parallel tree creations is the number of core processors on the platform.
- This possibility is disabled if ``gnatelim`` has to compute the closure
- of the main unit.
-
-
- .. index:: -q (gnatelim)
-
- :samp:`-q`
- Quiet mode: by default ``gnatelim`` outputs to the standard error
- stream the number of program units left to be processed. This option turns
- this trace off.
-
- .. index:: -t (gnatelim)
-
-
- :samp:`-t`
- Print out execution time.
-
-
- .. index:: -v (gnatelim)
-
- :samp:`-v`
- Verbose mode: ``gnatelim`` version information is printed as Ada
- comments to the standard output stream. Also, in addition to the number of
- program units left ``gnatelim`` will output the name of the current unit
- being processed.
-
-
- .. index:: -wq (gnatelim)
-
- :samp:`-wq`
- Quiet warning mode - some warnings are suppressed. In particular warnings that
- indicate that the analysed set of sources is incomplete to make up a
- partition and that some subprogram bodies are missing are not generated.
-
-
-
- .. _Processing_Precompiled_Libraries:
-
- Processing Precompiled Libraries
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- If some program uses a precompiled Ada library, it can be processed by
- ``gnatelim`` in a usual way. ``gnatelim`` will newer generate an
- Eliminate pragma for a subprogram if the body of this subprogram has not
- been analysed, this is a typical case for subprograms from precompiled
- libraries. Switch :switch:`-wq` may be used to suppress
- warnings about missing source files and non-analyzed subprogram bodies
- that can be generated when processing precompiled Ada libraries.
-
-
- .. _Correcting_the_List_of_Eliminate_Pragmas:
-
- Correcting the List of Eliminate Pragmas
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
- In some rare cases ``gnatelim`` may try to eliminate
- subprograms that are actually called in the program. In this case, the
- compiler will generate an error message of the form:
-
- ::
-
- main.adb:4:08: cannot reference subprogram "P" eliminated at elim.out:5
-
- You will need to manually remove the wrong ``Eliminate`` pragmas from
- the configuration file indicated in the error message. You should recompile
- your program from scratch after that, because you need a consistent
- configuration file(s) during the entire compilation.
-
- If ``gnatelim`` is called with a project file and with ``-U`` option
- the generated set of pragmas may contain pragmas for subprograms that
- does not belong to the closure of the argument main subprogram. These
- pragmas has no effect when the set of pragmas is used to reduce the size
- of executable.
-
.. index:: Overflow checks
.. index:: Checks (overflow)
diff --git a/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst b/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst
index fc39214..56d4869 100644
--- a/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst
+++ b/gcc/ada/doc/gnat_ugn/gnat_utility_programs.rst
@@ -1797,9 +1797,6 @@ Alternatively, you may run the script using the following command line:
.. index:: ! gnatmetric
.. index:: Metric tool
- This documentation is for the new libadalang-based version
- of ``gnatmetric``, which replaces the ASIS-based version.
-
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
@@ -1822,14 +1819,16 @@ Alternatively, you may run the script using the following command line:
* ``switches`` specify the metrics to compute and define the destination for
the output
- * Each ``filename`` is the name (including the extension) 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.
+ * 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.
@@ -1928,6 +1927,16 @@ Alternatively, you may run the script using the following command line:
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
@@ -2098,6 +2107,14 @@ Alternatively, you may run the script using the following command line:
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
@@ -2284,6 +2301,53 @@ Alternatively, you may run the script using the following command line:
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-all`
+ Report the McCabe complexity of public subprograms
+
+
+ :switch:`--no-contract-all`
+ Do not report the McCabe complexity of public subprograms
+
+
.. _Complexity_Metrics_Control:
Complexity Metrics Control
@@ -2375,7 +2439,7 @@ Alternatively, you may run the script using the following command line:
:switch:`--no-complexity-all`
- Do not report any of complexity metrics
+ Do not report any of the complexity metrics
:switch:`--complexity-cyclomatic`
@@ -2811,6 +2875,11 @@ Alternatively, you may run the script using the following command line:
:switch:`-sfn`
:switch:`--short-file-names`
+ .. index:: -W (gnatsmetric)
+
+ :switch:`-W{e}`
+ :switch:`--wide-character-encoding={e}`
+
.. index:: -nolocal (gnatmetric)
:switch:`-nolocal`
@@ -2846,9 +2915,6 @@ Alternatively, you may run the script using the following command line:
.. index:: ! gnatpp
.. index:: pretty printer
- This documentation is for the new libadalang-based version
- of ``gnatpp``, which replaces the ASIS-based version.
-
The ``gnatpp`` tool is a utility for source reformatting / pretty
printing. It takes an Ada source file as input and generates a
reformatted version as output. You can specify various style
@@ -2880,6 +2946,10 @@ Alternatively, you may run the script using the following command line:
file name may contain path information; it does not have to follow
the GNAT file naming rules
+ Note that it is no longer necessary to specify the Ada language version;
+ ``gnatpp`` can process Ada source code written in any version from
+ Ada 83 onward without specifying any language version switch.
+
.. _Switches_for_gnatpp:
@@ -3633,30 +3703,6 @@ Alternatively, you may run the script using the following command line:
all the immediate units of the argument project.
- .. index:: --gnat83 (gnatpp)
-
- :switch:`--gnat83`
- Ada 83 mode
-
-
- .. index:: --gnat95 (gnatpp)
-
- :switch:`--gnat95`
- Ada 95 mode
-
-
- .. index:: --gnat2005 (gnatpp)
-
- :switch:`--gnat2005`
- Ada 2005 mode
-
-
- .. index:: --gnat2012 (gnatpp)
-
- :switch:`--gnat2012`
- Ada 2012 mode
-
-
.. _Formatting_Rules:
Formatting Rules
@@ -4243,6 +4289,10 @@ Alternatively, you may run the script using the following command line:
or creates the name file to generate using the standard GNAT
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
+ Ada 83 onward without specifying any language version switch.
+
* *switches*
is an optional sequence of switches as described in the next section
@@ -4402,30 +4452,6 @@ Alternatively, you may run the script using the following command line:
* *b* - Brackets encoding (default value)
- .. index:: --gnat83 (gnatstub)
-
- :switch:`--gnat83`
- Ada 83 mode
-
-
- .. index:: --gnat95 (gnatstub)
-
- :switch:`--gnat95`
- Ada 95 mode
-
-
- .. index:: --gnat2005 (gnatstub)
-
- :switch:`--gnat2005`
- Ada 2005 mode
-
-
- .. index:: --gnat2012 (gnatstub)
-
- :switch:`--gnat2012`
- Ada 2012 mode
-
-
.. index:: --quiet (gnatstub)
.. index:: -q (gnatstub)
diff --git a/gcc/ada/einfo.adb b/gcc/ada/einfo.adb
index 8ff9ec6..957bfe6 100644
--- a/gcc/ada/einfo.adb
+++ b/gcc/ada/einfo.adb
@@ -2140,7 +2140,7 @@ package body Einfo is
function Is_Called (Id : E) return B is
begin
- pragma Assert (Ekind_In (Id, E_Procedure, E_Function));
+ pragma Assert (Ekind_In (Id, E_Procedure, E_Function, E_Package));
return Flag102 (Id);
end Is_Called;
@@ -2314,7 +2314,7 @@ package body Einfo is
function Is_Generic_Actual_Subprogram (Id : E) return B is
begin
- pragma Assert (Ekind (Id) = E_Function or else Ekind (Id) = E_Procedure);
+ pragma Assert (Ekind_In (Id, E_Function, E_Procedure));
return Flag274 (Id);
end Is_Generic_Actual_Subprogram;
@@ -5344,7 +5344,7 @@ package body Einfo is
procedure Set_Is_Called (Id : E; V : B := True) is
begin
- pragma Assert (Ekind_In (Id, E_Procedure, E_Function));
+ pragma Assert (Ekind_In (Id, E_Procedure, E_Function, E_Package));
Set_Flag102 (Id, V);
end Set_Is_Called;
@@ -7589,6 +7589,7 @@ package body Einfo is
Id = Pragma_Initial_Condition or else
Id = Pragma_Initializes or else
Id = Pragma_Interrupt_Handler or else
+ Id = Pragma_No_Caching or else
Id = Pragma_Part_Of or else
Id = Pragma_Refined_Depends or else
Id = Pragma_Refined_Global or else
diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index 78208a1..089960a 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -2366,9 +2366,9 @@ package Einfo is
-- i.e. Standard.Boolean and all types ultimately derived from it.
-- Is_Called (Flag102)
--- Defined in subprograms. Returns true if the subprogram is called
--- in the unit being compiled or in a unit in the context. Used for
--- inlining.
+-- Defined in subprograms and packages. Set if a subprogram is called
+-- from the unit being compiled or a unit in the closure. Also set for
+-- a package that contains called subprograms. Used only for inlining.
-- Is_Character_Type (Flag63)
-- Defined in all entities. Set for character types and subtypes,
@@ -4674,7 +4674,7 @@ package Einfo is
-- They all overlap because they are supposed to apply to different entity
-- kinds. They are semantically related, and have the following intended uses:
--- a) Renamed_Entity appplies to entities in renaming declarations that rename
+-- a) Renamed_Entity applies to entities in renaming declarations that rename
-- an entity, so the value of the attribute IS an entity. This applies to
-- generic renamings, package renamings, exception renamings, and subprograms
-- renamings that rename a subprogram (rather than an attribute, an entry, a
@@ -6141,7 +6141,7 @@ package Einfo is
-- DTC_Entity (Node16)
-- First_Entity (Node17)
-- Alias (Node18) (non-generic case only)
- -- Renamed_Entity (Node18) (generic case only)
+ -- Renamed_Entity (Node18)
-- Extra_Accessibility_Of_Result (Node19) (non-generic case only)
-- Last_Entity (Node20)
-- Interface_Name (Node21)
@@ -6406,12 +6406,13 @@ package Einfo is
-- Has_Master_Entity (Flag21)
-- Has_RACW (Flag214) (non-generic case only)
-- Ignore_SPARK_Mode_Pragmas (Flag301)
- -- In_Package_Body (Flag48)
- -- In_Use (Flag8)
+ -- Is_Called (Flag102) (non-generic case only)
-- Is_Elaboration_Checks_OK_Id (Flag148)
-- Is_Elaboration_Warnings_OK_Id (Flag304)
-- Is_Instantiated (Flag126)
+ -- In_Package_Body (Flag48)
-- Is_Private_Descendant (Flag53)
+ -- In_Use (Flag8)
-- Is_Visible_Lib_Unit (Flag116)
-- Renamed_In_Spec (Flag231) (non-generic case only)
-- SPARK_Aux_Pragma_Inherited (Flag266)
@@ -6466,7 +6467,7 @@ package Einfo is
-- DTC_Entity (Node16)
-- First_Entity (Node17)
-- Alias (Node18) (non-generic case only)
- -- Renamed_Entity (Node18) (generic case only)
+ -- Renamed_Entity (Node18)
-- Receiving_Entry (Node19) (non-generic case only)
-- Last_Entity (Node20)
-- Interface_Name (Node21)
@@ -8429,6 +8430,7 @@ package Einfo is
-- Initial_Condition
-- Initializes
-- Interrupt_Handler
+ -- No_Caching
-- Part_Of
-- Precondition
-- Postcondition
diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
index ea524f3..f5a4925 100644
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -3259,7 +3259,7 @@ package body Errout is
-- Processing for "Size too small" messages
- elsif Msg = "size for& too small, minimum allowed is ^" then
+ elsif Msg = Size_Too_Small_Message then
-- Suppress "size too small" errors in CodePeer mode, since code may
-- be analyzed in a different configuration than the one used for
diff --git a/gcc/ada/errout.ads b/gcc/ada/errout.ads
index 10a43b1..9a54c7c 100644
--- a/gcc/ada/errout.ads
+++ b/gcc/ada/errout.ads
@@ -948,4 +948,10 @@ package Errout is
-- This name is the identifier name as passed, cased according to the
-- default identifier casing for the given file.
+ Size_Too_Small_Message : constant String :=
+ "size for& too small, minimum allowed is ^";
+ -- This message is explicitly tested in Special_Msg_Delete in the package
+ -- body, which is somewhat questionable, but at least by using a constant
+ -- we are obeying the DRY principle.
+
end Errout;
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index c944db6..6a756fd 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -344,7 +344,7 @@ package body Exp_Aggr is
Lo : Node_Id;
Hi : Node_Id;
Indx : Node_Id;
- Siz : Int;
+ Size : Uint;
Lov : Uint;
Hiv : Uint;
@@ -468,7 +468,7 @@ package body Exp_Aggr is
Max_Aggr_Size := 5000;
end if;
- Siz := Component_Count (Component_Type (Typ));
+ Size := UI_From_Int (Component_Count (Component_Type (Typ)));
Indx := First_Index (Typ);
while Present (Indx) loop
@@ -538,14 +538,17 @@ package body Exp_Aggr is
return False;
end if;
- Siz := Siz * UI_To_Int (Rng);
- end;
+ -- Compute the size using universal arithmetic to avoid the
+ -- possibility of overflow on very large aggregates.
- if Siz <= 0
- or else Siz > Max_Aggr_Size
- then
- return False;
- end if;
+ Size := Size * Rng;
+
+ if Size <= 0
+ or else Size > Max_Aggr_Size
+ then
+ return False;
+ end if;
+ end;
-- Bounds must be in integer range, for later array construction
@@ -2686,8 +2689,10 @@ package body Exp_Aggr is
Discr_Constr :=
First_Elmt (Stored_Constraint (Full_View (Base_Typ)));
+ -- Otherwise, no discriminant to process
+
else
- Discr_Constr := First_Elmt (Stored_Constraint (Typ));
+ Discr_Constr := No_Elmt;
end if;
while Present (Discr) and then Present (Discr_Constr) loop
@@ -5318,6 +5323,16 @@ package body Exp_Aggr is
return False;
end if;
+ -- If the expression has side effects (e.g. contains calls with
+ -- potential side effects) reject as well. We only preanalyze the
+ -- expression to prevent the removal of intended side effects.
+
+ Preanalyze_And_Resolve (Expr, Ctyp);
+
+ if not Side_Effect_Free (Expr) then
+ return False;
+ end if;
+
-- The expression needs to be analyzed if True is returned
Analyze_And_Resolve (Expr, Ctyp);
@@ -7694,15 +7709,36 @@ package body Exp_Aggr is
P := Parent (P);
end loop;
- -- Cases where aggregates are supported by the CCG backend
+ -- Check cases where aggregates are supported by the CCG backend
if Nkind (P) = N_Object_Declaration then
- return True;
+ declare
+ P_Typ : constant Entity_Id := Etype (Defining_Identifier (P));
- elsif Nkind (P) = N_Qualified_Expression
- and then Nkind_In (Parent (P), N_Allocator, N_Object_Declaration)
- then
- return True;
+ begin
+ if Is_Record_Type (P_Typ) then
+ return True;
+ else
+ return Compile_Time_Known_Bounds (P_Typ);
+ end if;
+ end;
+
+ elsif Nkind (P) = N_Qualified_Expression then
+ if Nkind (Parent (P)) = N_Object_Declaration then
+ declare
+ P_Typ : constant Entity_Id :=
+ Etype (Defining_Identifier (Parent (P)));
+ begin
+ if Is_Record_Type (P_Typ) then
+ return True;
+ else
+ return Compile_Time_Known_Bounds (P_Typ);
+ end if;
+ end;
+
+ elsif Nkind (Parent (P)) = N_Allocator then
+ return True;
+ end if;
end if;
return False;
diff --git a/gcc/ada/exp_atag.adb b/gcc/ada/exp_atag.adb
index 567bb29..db1833c 100644
--- a/gcc/ada/exp_atag.adb
+++ b/gcc/ada/exp_atag.adb
@@ -742,9 +742,10 @@ package body Exp_Atag is
------------------------------------
function Build_Inherit_Predefined_Prims
- (Loc : Source_Ptr;
- Old_Tag_Node : Node_Id;
- New_Tag_Node : Node_Id) return Node_Id
+ (Loc : Source_Ptr;
+ Old_Tag_Node : Node_Id;
+ New_Tag_Node : Node_Id;
+ Num_Predef_Prims : Int) return Node_Id
is
begin
return
@@ -759,7 +760,7 @@ package body Exp_Atag is
New_Tag_Node)))),
Discrete_Range => Make_Range (Loc,
Make_Integer_Literal (Loc, Uint_1),
- New_Occurrence_Of (RTE (RE_Max_Predef_Prims), Loc))),
+ Make_Integer_Literal (Loc, Num_Predef_Prims))),
Expression =>
Make_Slice (Loc,
@@ -772,7 +773,7 @@ package body Exp_Atag is
Discrete_Range =>
Make_Range (Loc,
Make_Integer_Literal (Loc, 1),
- New_Occurrence_Of (RTE (RE_Max_Predef_Prims), Loc))));
+ Make_Integer_Literal (Loc, Num_Predef_Prims))));
end Build_Inherit_Predefined_Prims;
-------------------------
diff --git a/gcc/ada/exp_atag.ads b/gcc/ada/exp_atag.ads
index d6a4dbb..e8d5e62 100644
--- a/gcc/ada/exp_atag.ads
+++ b/gcc/ada/exp_atag.ads
@@ -109,9 +109,10 @@ package Exp_Atag is
-- generated code handles primary and secondary dispatch tables of Typ.
function Build_Inherit_Predefined_Prims
- (Loc : Source_Ptr;
- Old_Tag_Node : Node_Id;
- New_Tag_Node : Node_Id) return Node_Id;
+ (Loc : Source_Ptr;
+ Old_Tag_Node : Node_Id;
+ New_Tag_Node : Node_Id;
+ Num_Predef_Prims : Int) return Node_Id;
-- Build code that inherits the predefined primitives of the parent.
--
-- Generates: Predefined_DT (New_T).D (All_Predefined_Prims) :=
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index 9d6da33..306c1b5 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -3598,8 +3598,8 @@ package body Exp_Attr is
-- Result_Type (System.Fore (Universal_Real (Type'First)),
-- Universal_Real (Type'Last))
- -- Note that we know that the type is a non-static subtype, or Fore
- -- would have itself been computed dynamically in Eval_Attribute.
+ -- Note that we know that the type is a nonstatic subtype, or Fore would
+ -- have itself been computed dynamically in Eval_Attribute.
when Attribute_Fore =>
Rewrite (N,
@@ -5849,7 +5849,6 @@ package body Exp_Attr is
| Attribute_VADS_Size
=>
Size : declare
- Siz : Uint;
New_Node : Node_Id;
begin
@@ -5961,128 +5960,12 @@ package body Exp_Attr is
Rewrite (N, New_Node);
Analyze_And_Resolve (N, Typ);
return;
-
- -- Case of known RM_Size of a type
-
- elsif (Id = Attribute_Size or else Id = Attribute_Value_Size)
- and then Is_Entity_Name (Pref)
- and then Is_Type (Entity (Pref))
- and then Known_Static_RM_Size (Entity (Pref))
- then
- Siz := RM_Size (Entity (Pref));
-
- -- Case of known Esize of a type
-
- elsif Id = Attribute_Object_Size
- and then Is_Entity_Name (Pref)
- and then Is_Type (Entity (Pref))
- and then Known_Static_Esize (Entity (Pref))
- then
- Siz := Esize (Entity (Pref));
-
- -- Case of known size of object
-
- elsif Id = Attribute_Size
- and then Is_Entity_Name (Pref)
- and then Is_Object (Entity (Pref))
- and then Known_Esize (Entity (Pref))
- and then Known_Static_Esize (Entity (Pref))
- then
- Siz := Esize (Entity (Pref));
-
- -- For an array component, we can do Size in the front end if the
- -- component_size of the array is set.
-
- elsif Nkind (Pref) = N_Indexed_Component then
- Siz := Component_Size (Etype (Prefix (Pref)));
-
- -- For a record component, we can do Size in the front end if
- -- there is a component clause, or if the record is packed and the
- -- component's size is known at compile time.
-
- elsif Nkind (Pref) = N_Selected_Component then
- declare
- Rec : constant Entity_Id := Etype (Prefix (Pref));
- Comp : constant Entity_Id := Entity (Selector_Name (Pref));
-
- begin
- if Present (Component_Clause (Comp)) then
- Siz := Esize (Comp);
-
- elsif Is_Packed (Rec) then
- Siz := RM_Size (Ptyp);
-
- else
- Apply_Universal_Integer_Attribute_Checks (N);
- return;
- end if;
- end;
-
- -- All other cases are handled by the back end
-
- else
- Apply_Universal_Integer_Attribute_Checks (N);
-
- -- If Size is applied to a formal parameter that is of a packed
- -- array subtype, then apply Size to the actual subtype.
-
- if Is_Entity_Name (Pref)
- and then Is_Formal (Entity (Pref))
- and then Is_Array_Type (Ptyp)
- and then Is_Packed (Ptyp)
- then
- Rewrite (N,
- Make_Attribute_Reference (Loc,
- Prefix =>
- New_Occurrence_Of (Get_Actual_Subtype (Pref), Loc),
- Attribute_Name => Name_Size));
- Analyze_And_Resolve (N, Typ);
- end if;
-
- -- If Size applies to a dereference of an access to
- -- unconstrained packed array, the back end needs to see its
- -- unconstrained nominal type, but also a hint to the actual
- -- constrained type.
-
- if Nkind (Pref) = N_Explicit_Dereference
- and then Is_Array_Type (Ptyp)
- and then not Is_Constrained (Ptyp)
- and then Is_Packed (Ptyp)
- then
- Set_Actual_Designated_Subtype (Pref,
- Get_Actual_Subtype (Pref));
- end if;
-
- return;
end if;
- -- Common processing for record and array component case
-
- if Siz /= No_Uint and then Siz /= 0 then
- declare
- CS : constant Boolean := Comes_From_Source (N);
-
- begin
- Rewrite (N, Make_Integer_Literal (Loc, Siz));
+ -- Call Expand_Size_Attribute to do the final part of the
+ -- expansion which is shared with GNATprove expansion.
- -- This integer literal is not a static expression. We do
- -- not call Analyze_And_Resolve here, because this would
- -- activate the circuit for deciding that a static value
- -- was out of range, and we don't want that.
-
- -- So just manually set the type, mark the expression as
- -- non-static, and then ensure that the result is checked
- -- properly if the attribute comes from source (if it was
- -- internally generated, we never need a constraint check).
-
- Set_Etype (N, Typ);
- Set_Is_Static_Expression (N, False);
-
- if CS then
- Apply_Constraint_Check (N, Typ);
- end if;
- end;
- end if;
+ Expand_Size_Attribute (N);
end Size;
------------------
@@ -6662,7 +6545,7 @@ package body Exp_Attr is
-- See separate sections below for the generated code in each case.
when Attribute_Valid => Valid : declare
- Btyp : Entity_Id := Base_Type (Ptyp);
+ PBtyp : Entity_Id := Base_Type (Ptyp);
Save_Validity_Checks_On : constant Boolean := Validity_Checks_On;
-- Save the validity checking mode. We always turn off validity
@@ -6672,7 +6555,7 @@ package body Exp_Attr is
function Make_Range_Test return Node_Id;
-- Build the code for a range test of the form
- -- Btyp!(Pref) in Btyp!(Ptyp'First) .. Btyp!(Ptyp'Last)
+ -- PBtyp!(Pref) in PBtyp!(Ptyp'First) .. PBtyp!(Ptyp'Last)
---------------------
-- Make_Range_Test --
@@ -6711,16 +6594,16 @@ package body Exp_Attr is
return
Make_In (Loc,
- Left_Opnd => Unchecked_Convert_To (Btyp, Temp),
+ Left_Opnd => Unchecked_Convert_To (PBtyp, Temp),
Right_Opnd =>
Make_Range (Loc,
Low_Bound =>
- Unchecked_Convert_To (Btyp,
+ Unchecked_Convert_To (PBtyp,
Make_Attribute_Reference (Loc,
Prefix => New_Occurrence_Of (Ptyp, Loc),
Attribute_Name => Name_First)),
High_Bound =>
- Unchecked_Convert_To (Btyp,
+ Unchecked_Convert_To (PBtyp,
Make_Attribute_Reference (Loc,
Prefix => New_Occurrence_Of (Ptyp, Loc),
Attribute_Name => Name_Last))));
@@ -6748,8 +6631,8 @@ package body Exp_Attr is
-- Retrieve the base type. Handle the case where the base type is a
-- private enumeration type.
- if Is_Private_Type (Btyp) and then Present (Full_View (Btyp)) then
- Btyp := Full_View (Btyp);
+ if Is_Private_Type (PBtyp) and then Present (Full_View (PBtyp)) then
+ PBtyp := Full_View (PBtyp);
end if;
-- Floating-point case. This case is handled by the Valid attribute
@@ -6782,7 +6665,7 @@ package body Exp_Attr is
begin
-- The C and AAMP back-ends handle Valid for fpt types
- if Modify_Tree_For_C or else Float_Rep (Btyp) = AAMP then
+ if Modify_Tree_For_C or else Float_Rep (PBtyp) = AAMP then
Analyze_And_Resolve (Pref, Ptyp);
Set_Etype (N, Standard_Boolean);
Set_Analyzed (N);
@@ -6875,13 +6758,13 @@ package body Exp_Attr is
-- The way we do the range check is simply to create the
-- expression: Valid (N) and then Base_Type(Pref) in Typ.
- if not Subtypes_Statically_Match (Ptyp, Btyp) then
+ if not Subtypes_Statically_Match (Ptyp, PBtyp) then
Rewrite (N,
Make_And_Then (Loc,
Left_Opnd => Relocate_Node (N),
Right_Opnd =>
Make_In (Loc,
- Left_Opnd => Convert_To (Btyp, Pref),
+ Left_Opnd => Convert_To (PBtyp, Pref),
Right_Opnd => New_Occurrence_Of (Ptyp, Loc))));
end if;
end Float_Valid;
@@ -6910,24 +6793,24 @@ package body Exp_Attr is
-- (X >= type(X)'First and then type(X)'Last <= X)
elsif Is_Enumeration_Type (Ptyp)
- and then Present (Enum_Pos_To_Rep (Btyp))
+ and then Present (Enum_Pos_To_Rep (PBtyp))
then
Tst :=
Make_Op_Ge (Loc,
Left_Opnd =>
Make_Function_Call (Loc,
Name =>
- New_Occurrence_Of (TSS (Btyp, TSS_Rep_To_Pos), Loc),
+ New_Occurrence_Of (TSS (PBtyp, TSS_Rep_To_Pos), Loc),
Parameter_Associations => New_List (
Pref,
New_Occurrence_Of (Standard_False, Loc))),
Right_Opnd => Make_Integer_Literal (Loc, 0));
- if Ptyp /= Btyp
+ if Ptyp /= PBtyp
and then
- (Type_Low_Bound (Ptyp) /= Type_Low_Bound (Btyp)
+ (Type_Low_Bound (Ptyp) /= Type_Low_Bound (PBtyp)
or else
- Type_High_Bound (Ptyp) /= Type_High_Bound (Btyp))
+ Type_High_Bound (Ptyp) /= Type_High_Bound (PBtyp))
then
-- The call to Make_Range_Test will create declarations
-- that need a proper insertion point, but Pref is now
@@ -6960,16 +6843,16 @@ package body Exp_Attr is
-- test has to take this into account, and the proper form of the
-- test is:
- -- Btyp!(Pref) < Btyp!(Ptyp'Range_Length)
+ -- PBtyp!(Pref) < PBtyp!(Ptyp'Range_Length)
elsif Has_Biased_Representation (Ptyp) then
- Btyp := RTE (RE_Unsigned_32);
+ PBtyp := RTE (RE_Unsigned_32);
Rewrite (N,
Make_Op_Lt (Loc,
Left_Opnd =>
- Unchecked_Convert_To (Btyp, Duplicate_Subexpr (Pref)),
+ Unchecked_Convert_To (PBtyp, Duplicate_Subexpr (Pref)),
Right_Opnd =>
- Unchecked_Convert_To (Btyp,
+ Unchecked_Convert_To (PBtyp,
Make_Attribute_Reference (Loc,
Prefix => New_Occurrence_Of (Ptyp, Loc),
Attribute_Name => Name_Range_Length))));
@@ -6984,11 +6867,11 @@ package body Exp_Attr is
-- the Valid attribute is exactly that this test does not work).
-- What will work is:
- -- Btyp!(X) >= Btyp!(type(X)'First)
+ -- PBtyp!(X) >= PBtyp!(type(X)'First)
-- and then
- -- Btyp!(X) <= Btyp!(type(X)'Last)
+ -- PBtyp!(X) <= PBtyp!(type(X)'Last)
- -- where Btyp is an integer type large enough to cover the full
+ -- where PBtyp is an integer type large enough to cover the full
-- range of possible stored values (i.e. it is chosen on the basis
-- of the size of the type, not the range of the values). We write
-- this as two tests, rather than a range check, so that static
@@ -7012,11 +6895,13 @@ package body Exp_Attr is
-- correct, even though a value greater than 127 looks signed to a
-- signed comparison.
- elsif Is_Unsigned_Type (Ptyp) then
+ elsif Is_Unsigned_Type (Ptyp)
+ or else (Is_Private_Type (Ptyp) and then Is_Unsigned_Type (Btyp))
+ then
if Esize (Ptyp) <= 32 then
- Btyp := RTE (RE_Unsigned_32);
+ PBtyp := RTE (RE_Unsigned_32);
else
- Btyp := RTE (RE_Unsigned_64);
+ PBtyp := RTE (RE_Unsigned_64);
end if;
Rewrite (N, Make_Range_Test);
@@ -7025,9 +6910,9 @@ package body Exp_Attr is
else
if Esize (Ptyp) <= Esize (Standard_Integer) then
- Btyp := Standard_Integer;
+ PBtyp := Standard_Integer;
else
- Btyp := Universal_Integer;
+ PBtyp := Universal_Integer;
end if;
Rewrite (N, Make_Range_Test);
@@ -7608,6 +7493,140 @@ package body Exp_Attr is
end if;
end Expand_Pred_Succ_Attribute;
+ ---------------------------
+ -- Expand_Size_Attribute --
+ ---------------------------
+
+ procedure Expand_Size_Attribute (N : Node_Id) is
+ Loc : constant Source_Ptr := Sloc (N);
+ Typ : constant Entity_Id := Etype (N);
+ Pref : constant Node_Id := Prefix (N);
+ Ptyp : constant Entity_Id := Etype (Pref);
+ Id : constant Attribute_Id := Get_Attribute_Id (Attribute_Name (N));
+ Siz : Uint;
+
+ begin
+ -- Case of known RM_Size of a type
+
+ if (Id = Attribute_Size or else Id = Attribute_Value_Size)
+ and then Is_Entity_Name (Pref)
+ and then Is_Type (Entity (Pref))
+ and then Known_Static_RM_Size (Entity (Pref))
+ then
+ Siz := RM_Size (Entity (Pref));
+
+ -- Case of known Esize of a type
+
+ elsif Id = Attribute_Object_Size
+ and then Is_Entity_Name (Pref)
+ and then Is_Type (Entity (Pref))
+ and then Known_Static_Esize (Entity (Pref))
+ then
+ Siz := Esize (Entity (Pref));
+
+ -- Case of known size of object
+
+ elsif Id = Attribute_Size
+ and then Is_Entity_Name (Pref)
+ and then Is_Object (Entity (Pref))
+ and then Known_Esize (Entity (Pref))
+ and then Known_Static_Esize (Entity (Pref))
+ then
+ Siz := Esize (Entity (Pref));
+
+ -- For an array component, we can do Size in the front end if the
+ -- component_size of the array is set.
+
+ elsif Nkind (Pref) = N_Indexed_Component then
+ Siz := Component_Size (Etype (Prefix (Pref)));
+
+ -- For a record component, we can do Size in the front end if there is a
+ -- component clause, or if the record is packed and the component's size
+ -- is known at compile time.
+
+ elsif Nkind (Pref) = N_Selected_Component then
+ declare
+ Rec : constant Entity_Id := Etype (Prefix (Pref));
+ Comp : constant Entity_Id := Entity (Selector_Name (Pref));
+
+ begin
+ if Present (Component_Clause (Comp)) then
+ Siz := Esize (Comp);
+
+ elsif Is_Packed (Rec) then
+ Siz := RM_Size (Ptyp);
+
+ else
+ Apply_Universal_Integer_Attribute_Checks (N);
+ return;
+ end if;
+ end;
+
+ -- All other cases are handled by the back end
+
+ else
+ Apply_Universal_Integer_Attribute_Checks (N);
+
+ -- If Size is applied to a formal parameter that is of a packed
+ -- array subtype, then apply Size to the actual subtype.
+
+ if Is_Entity_Name (Pref)
+ and then Is_Formal (Entity (Pref))
+ and then Is_Array_Type (Ptyp)
+ and then Is_Packed (Ptyp)
+ then
+ Rewrite (N,
+ Make_Attribute_Reference (Loc,
+ Prefix =>
+ New_Occurrence_Of (Get_Actual_Subtype (Pref), Loc),
+ Attribute_Name => Name_Size));
+ Analyze_And_Resolve (N, Typ);
+ end if;
+
+ -- If Size applies to a dereference of an access to unconstrained
+ -- packed array, the back end needs to see its unconstrained nominal
+ -- type, but also a hint to the actual constrained type.
+
+ if Nkind (Pref) = N_Explicit_Dereference
+ and then Is_Array_Type (Ptyp)
+ and then not Is_Constrained (Ptyp)
+ and then Is_Packed (Ptyp)
+ then
+ Set_Actual_Designated_Subtype (Pref, Get_Actual_Subtype (Pref));
+ end if;
+
+ return;
+ end if;
+
+ -- Common processing for record and array component case
+
+ if Siz /= No_Uint and then Siz /= 0 then
+ declare
+ CS : constant Boolean := Comes_From_Source (N);
+
+ begin
+ Rewrite (N, Make_Integer_Literal (Loc, Siz));
+
+ -- This integer literal is not a static expression. We do not
+ -- call Analyze_And_Resolve here, because this would activate
+ -- the circuit for deciding that a static value was out of range,
+ -- and we don't want that.
+
+ -- So just manually set the type, mark the expression as
+ -- nonstatic, and then ensure that the result is checked
+ -- properly if the attribute comes from source (if it was
+ -- internally generated, we never need a constraint check).
+
+ Set_Etype (N, Typ);
+ Set_Is_Static_Expression (N, False);
+
+ if CS then
+ Apply_Constraint_Check (N, Typ);
+ end if;
+ end;
+ end if;
+ end Expand_Size_Attribute;
+
-----------------------------
-- Expand_Update_Attribute --
-----------------------------
diff --git a/gcc/ada/exp_attr.ads b/gcc/ada/exp_attr.ads
index 5a3fefc..8ca9b10 100644
--- a/gcc/ada/exp_attr.ads
+++ b/gcc/ada/exp_attr.ads
@@ -31,4 +31,9 @@ package Exp_Attr is
procedure Expand_N_Attribute_Reference (N : Node_Id);
+ procedure Expand_Size_Attribute (N : Node_Id);
+ -- Handles part of the expansion of attributes 'Object_Size, 'Size,
+ -- 'Value_Size, and 'VADS_Size, so that it can also be used in the special
+ -- expansion in GNATprove mode.
+
end Exp_Attr;
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 834aaa3..1901ea5 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -10313,8 +10313,24 @@ package body Exp_Ch3 is
Result_Definition => New_Occurrence_Of (Ret_Type, Loc));
end if;
+ -- Declare an abstract subprogram for primitive subprograms of an
+ -- interface type (except for "=").
+
if Is_Interface (Tag_Typ) then
- return Make_Abstract_Subprogram_Declaration (Loc, Spec);
+ if Name /= Name_Op_Eq then
+ return Make_Abstract_Subprogram_Declaration (Loc, Spec);
+
+ -- The equality function (if any) for an interface type is defined
+ -- to be nonabstract, so we create an expression function for it that
+ -- always returns False. Note that the function can never actually be
+ -- invoked because interface types are abstract, so there aren't any
+ -- objects of such types (and their equality operation will always
+ -- dispatch).
+
+ else
+ return Make_Expression_Function
+ (Loc, Spec, New_Occurrence_Of (Standard_False, Loc));
+ end if;
-- If body case, return empty subprogram body. Note that this is ill-
-- formed, because there is not even a null statement, and certainly not
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index e4dc06b5..00f9aae 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -4421,10 +4421,13 @@ package body Exp_Ch4 is
begin
-- Warn on the presence of an allocator of an anonymous access type when
- -- enabled.
+ -- enabled except when its an object declaration at library level.
if Warn_On_Anonymous_Allocators
and then Ekind (PtrT) = E_Anonymous_Access_Type
+ and then not (Is_Library_Level_Entity (PtrT)
+ and then Nkind (Associated_Node_For_Itype (PtrT)) =
+ N_Object_Declaration)
then
Error_Msg_N ("?use of an anonymous access type allocator", N);
end if;
@@ -8068,7 +8071,9 @@ package body Exp_Ch4 is
and then not Is_Floating_Point_Type (Component_Type (Typl))
and then not Is_Atomic_Or_VFA (Component_Type (Typl))
and then not Is_Possibly_Unaligned_Object (Lhs)
+ and then not Is_Possibly_Unaligned_Slice (Lhs)
and then not Is_Possibly_Unaligned_Object (Rhs)
+ and then not Is_Possibly_Unaligned_Slice (Rhs)
and then Support_Composite_Compare_On_Target
then
null;
@@ -10332,8 +10337,30 @@ package body Exp_Ch4 is
Flag : Entity_Id;
Scheme : Node_Id;
Stmts : List_Id;
+ Var : Entity_Id;
begin
+ -- Ensure that the bound variable is properly frozen. We must do
+ -- this before expansion because the expression is about to be
+ -- converted into a loop, and resulting freeze nodes may end up
+ -- in the wrong place in the tree.
+
+ if Present (Iter_Spec) then
+ Var := Defining_Identifier (Iter_Spec);
+ else
+ Var := Defining_Identifier (Loop_Spec);
+ end if;
+
+ declare
+ P : Node_Id := Parent (N);
+ begin
+ while Nkind (P) in N_Subexpr loop
+ P := Parent (P);
+ end loop;
+
+ Freeze_Before (P, Etype (Var));
+ end;
+
-- Create the declaration of the flag which tracks the status of the
-- quantified expression. Generate:
@@ -10969,7 +10996,9 @@ package body Exp_Ch4 is
-- Discrete_Range_Check --
--------------------------
- -- Case of conversions to a discrete type
+ -- Case of conversions to a discrete type. We let Generate_Range_Check
+ -- do the heavy lifting, after converting a fixed-point operand to an
+ -- appropriate integer type.
procedure Discrete_Range_Check is
Expr : Node_Id;
@@ -10984,6 +11013,21 @@ package body Exp_Ch4 is
Expr := Expression (N);
+ -- Nothing to do if range checks suppressed
+
+ if Range_Checks_Suppressed (Target_Type) then
+ return;
+ end if;
+
+ -- Nothing to do if expression is an entity on which checks have been
+ -- suppressed.
+
+ if Is_Entity_Name (Expr)
+ and then Range_Checks_Suppressed (Entity (Expr))
+ then
+ return;
+ end if;
+
-- Before we do a range check, we have to deal with treating
-- a fixed-point operand as an integer. The way we do this
-- is simply to do an unchecked conversion to an appropriate
@@ -11212,12 +11256,12 @@ package body Exp_Ch4 is
-- Tnn : typ'Base := typ'Base (x);
-- [constraint_error when Tnn < typ'First or else Tnn > typ'Last]
- -- Tnn
+ -- typ (Tnn)
-- This is necessary when there is a conversion of integer to float or
-- to fixed-point to ensure that the correct checks are made. It is not
- -- necessary for float to float where it is enough to simply set the
- -- Do_Range_Check flag.
+ -- necessary for the float-to-float case where it is enough to just set
+ -- the Do_Range_Check flag on the expression.
procedure Real_Range_Check is
Btyp : constant Entity_Id := Base_Type (Target_Type);
@@ -11229,6 +11273,7 @@ package body Exp_Ch4 is
Hi_Val : Node_Id;
Lo_Arg : Node_Id;
Lo_Val : Node_Id;
+ Expr : Entity_Id;
Tnn : Entity_Id;
begin
@@ -11238,6 +11283,12 @@ package body Exp_Ch4 is
return;
end if;
+ Expr := Expression (N);
+
+ -- Clear the flag once for all
+
+ Set_Do_Range_Check (Expr, False);
+
-- Nothing to do if range checks suppressed, or target has the same
-- range as the base type (or is the base type).
@@ -11246,22 +11297,24 @@ package body Exp_Ch4 is
and then
Hi = Type_High_Bound (Btyp))
then
- -- Unset the range check flag on the current value of
- -- Expression (N), since the captured Operand may have
- -- been rewritten (such as for the case of a conversion
- -- to a fixed-point type).
-
- Set_Do_Range_Check (Expression (N), False);
return;
end if;
-- Nothing to do if expression is an entity on which checks have been
-- suppressed.
- if Is_Entity_Name (Operand)
- and then Range_Checks_Suppressed (Entity (Operand))
+ if Is_Entity_Name (Expr)
+ and then Range_Checks_Suppressed (Entity (Expr))
+ then
+ return;
+ end if;
+
+ -- Nothing to do if expression was rewritten into a float-to-float
+ -- conversion, since this kind of conversions is handled elsewhere.
+
+ if Is_Floating_Point_Type (Etype (Expr))
+ and then Is_Floating_Point_Type (Target_Type)
then
- Set_Do_Range_Check (Expression (N), False);
return;
end if;
@@ -11271,12 +11324,12 @@ package body Exp_Ch4 is
-- not trust it to be in range (might be infinite)
declare
- S_Lo : constant Node_Id := Type_Low_Bound (Operand_Type);
- S_Hi : constant Node_Id := Type_High_Bound (Operand_Type);
+ S_Lo : constant Node_Id := Type_Low_Bound (Etype (Expr));
+ S_Hi : constant Node_Id := Type_High_Bound (Etype (Expr));
begin
- if (not Is_Floating_Point_Type (Operand_Type)
- or else Is_Constrained (Operand_Type))
+ if (not Is_Floating_Point_Type (Etype (Expr))
+ or else Is_Constrained (Etype (Expr)))
and then Compile_Time_Known_Value (S_Lo)
and then Compile_Time_Known_Value (S_Hi)
and then Compile_Time_Known_Value (Hi)
@@ -11289,7 +11342,7 @@ package body Exp_Ch4 is
S_Hiv : Ureal;
begin
- if Is_Real_Type (Operand_Type) then
+ if Is_Real_Type (Etype (Expr)) then
S_Lov := Expr_Value_R (S_Lo);
S_Hiv := Expr_Value_R (S_Hi);
else
@@ -11301,7 +11354,6 @@ package body Exp_Ch4 is
and then S_Lov >= D_Lov
and then S_Hiv <= D_Hiv
then
- Set_Do_Range_Check (Expression (N), False);
return;
end if;
end;
@@ -11310,18 +11362,21 @@ package body Exp_Ch4 is
-- Otherwise rewrite the conversion as described above
- Set_Do_Range_Check (Expression (N), False);
+ Conv := Convert_To (Btyp, Expr);
- Conv := Relocate_Node (N);
- Rewrite (Subtype_Mark (Conv), New_Occurrence_Of (Btyp, Loc));
- Set_Etype (Conv, Btyp);
+ -- If a conversion is necessary, then copy the specific flags from
+ -- the original one and also move the Do_Overflow_Check flag since
+ -- this new conversion is to the base type.
- -- Enable overflow except for case of integer to float conversions,
- -- where it is never required, since we can never have overflow in
- -- this case.
+ if Nkind (Conv) = N_Type_Conversion then
+ Set_Conversion_OK (Conv, Conversion_OK (N));
+ Set_Float_Truncate (Conv, Float_Truncate (N));
+ Set_Rounded_Result (Conv, Rounded_Result (N));
- if not Is_Integer_Type (Operand_Type) then
- Enable_Overflow_Check (Conv);
+ if Do_Overflow_Check (N) then
+ Set_Do_Overflow_Check (Conv);
+ Set_Do_Overflow_Check (N, False);
+ end if;
end if;
Tnn := Make_Temporary (Loc, 'T', Conv);
@@ -11344,26 +11399,23 @@ package body Exp_Ch4 is
-- in systems where Duration is larger than Long_Integer.
if Is_Ordinary_Fixed_Point_Type (Target_Type)
- and then Is_Floating_Point_Type (Operand_Type)
- and then RM_Size (Base_Type (Target_Type)) <=
- RM_Size (Standard_Long_Integer)
+ and then Is_Floating_Point_Type (Etype (Expr))
+ and then RM_Size (Btyp) <= RM_Size (Standard_Long_Integer)
and then Nkind (Lo) = N_Real_Literal
and then Nkind (Hi) = N_Real_Literal
then
- -- Find the integer type of the right size to perform an unchecked
- -- conversion to the target fixed-point type.
-
declare
- Bfx_Type : constant Entity_Id := Base_Type (Target_Type);
- Expr_Id : constant Entity_Id :=
- Make_Temporary (Loc, 'T', Conv);
+ Expr_Id : constant Entity_Id := Make_Temporary (Loc, 'T', Conv);
Int_Type : Entity_Id;
begin
- if RM_Size (Bfx_Type) > RM_Size (Standard_Integer) then
+ -- Find an integer type of the appropriate size to perform an
+ -- unchecked conversion to the target fixed-point type.
+
+ if RM_Size (Btyp) > RM_Size (Standard_Integer) then
Int_Type := Standard_Long_Integer;
- elsif RM_Size (Bfx_Type) > RM_Size (Standard_Short_Integer) then
+ elsif RM_Size (Btyp) > RM_Size (Standard_Short_Integer) then
Int_Type := Standard_Integer;
else
@@ -11371,9 +11423,9 @@ package body Exp_Ch4 is
end if;
-- Generate a temporary with the integer value. Required in the
- -- CCG compiler to ensure that runtime checks reference this
+ -- CCG compiler to ensure that run-time checks reference this
-- integer expression (instead of the resulting fixed-point
- -- value) because fixed-point values are handled by means of
+ -- value because fixed-point values are handled by means of
-- unsigned integer types).
Insert_Action (N,
@@ -11426,7 +11478,8 @@ package body Exp_Ch4 is
Attribute_Name => Name_Last);
end if;
- -- Build code for range checking
+ -- Build code for range checking. Note that checks are suppressed
+ -- here since we don't want a recursive range check popping up.
Insert_Actions (N, New_List (
Make_Object_Declaration (Loc,
@@ -11447,10 +11500,10 @@ package body Exp_Ch4 is
Make_Op_Gt (Loc,
Left_Opnd => Hi_Arg,
Right_Opnd => Hi_Val)),
- Reason => CE_Range_Check_Failed)));
+ Reason => CE_Range_Check_Failed)),
+ Suppress => All_Checks);
- Rewrite (N, New_Occurrence_Of (Tnn, Loc));
- Analyze_And_Resolve (N, Btyp);
+ Rewrite (Expr, New_Occurrence_Of (Tnn, Loc));
end Real_Range_Check;
-----------------------------
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index f38dd67..c182072 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -60,7 +60,6 @@ with Sem; use Sem;
with Sem_Aux; use Sem_Aux;
with Sem_Ch6; use Sem_Ch6;
with Sem_Ch8; use Sem_Ch8;
-with Sem_Ch12; use Sem_Ch12;
with Sem_Ch13; use Sem_Ch13;
with Sem_Dim; use Sem_Dim;
with Sem_Disp; use Sem_Disp;
@@ -203,8 +202,8 @@ package body Exp_Ch6 is
-- For all parameter modes, actuals that denote components and slices of
-- packed arrays are expanded into suitable temporaries.
--
- -- For non-scalar objects that are possibly unaligned, add call by copy
- -- code (copy in for IN and IN OUT, copy out for OUT and IN OUT).
+ -- For nonscalar objects that are possibly unaligned, add call by copy code
+ -- (copy in for IN and IN OUT, copy out for OUT and IN OUT).
--
-- For OUT and IN OUT parameters, add predicate checks after the call
-- based on the predicates of the actual type.
@@ -1295,7 +1294,14 @@ package body Exp_Ch6 is
Indic := New_Occurrence_Of (F_Typ, Loc);
end if;
+ -- The new code will be properly analyzed below and the setting of
+ -- the Do_Range_Check flag recomputed so remove the obsolete one.
+
+ Set_Do_Range_Check (Actual, False);
+
if Nkind (Actual) = N_Type_Conversion then
+ Set_Do_Range_Check (Expression (Actual), False);
+
V_Typ := Etype (Expression (Actual));
-- If the formal is an (in-)out parameter, capture the name
@@ -1399,6 +1405,16 @@ package body Exp_Ch6 is
Init := New_Occurrence_Of (Var, Loc);
end if;
+ -- Access types are passed in without checks, but if a copy-back is
+ -- required for a null-excluding check on an in-out or out parameter,
+ -- then the initial value is that of the actual.
+
+ elsif Is_Access_Type (E_Formal)
+ and then Can_Never_Be_Null (Etype (Actual))
+ and then not Can_Never_Be_Null (E_Formal)
+ then
+ Init := New_Occurrence_Of (Var, Loc);
+
else
Init := Empty;
end if;
@@ -1537,6 +1553,19 @@ package body Exp_Ch6 is
Type_Access_Level (E_Formal))));
else
+ if Is_Access_Type (E_Formal)
+ and then Can_Never_Be_Null (Etype (Actual))
+ and then not Can_Never_Be_Null (E_Formal)
+ then
+ Append_To (Post_Call,
+ Make_Raise_Constraint_Error (Loc,
+ Condition =>
+ Make_Op_Eq (Loc,
+ Left_Opnd => New_Occurrence_Of (Temp, Loc),
+ Right_Opnd => Make_Null (Loc)),
+ Reason => CE_Access_Check_Failed));
+ end if;
+
Append_To (Post_Call,
Make_Assignment_Statement (Loc,
Name => Lhs,
@@ -1689,6 +1718,20 @@ package body Exp_Ch6 is
Var_Id : Entity_Id;
begin
+ -- Generate range check if required
+
+ if Do_Range_Check (Actual) then
+ Generate_Range_Check (Actual, E_Formal, CE_Range_Check_Failed);
+ end if;
+
+ -- If there is a type conversion in the actual, it will be reinstated
+ -- below, the new instance will be properly analyzed and the setting
+ -- of the Do_Range_Check flag recomputed so remove the obsolete one.
+
+ if Nkind (Actual) = N_Type_Conversion then
+ Set_Do_Range_Check (Expression (Actual), False);
+ end if;
+
-- Copy the value of the validation variable back into the object
-- being validated.
@@ -1921,7 +1964,8 @@ package body Exp_Ch6 is
Apply_Constraint_Check (Actual, E_Formal);
-- Out parameter case. No constraint checks on access type
- -- RM 6.4.1 (13)
+ -- RM 6.4.1 (13), but on return a null-excluding check may be
+ -- required (see below).
elsif Is_Access_Type (E_Formal) then
null;
@@ -1998,7 +2042,7 @@ package body Exp_Ch6 is
elsif Is_Ref_To_Bit_Packed_Array (Actual) then
Add_Simple_Call_By_Copy_Code;
- -- If a non-scalar actual is possibly bit-aligned, we need a copy
+ -- If a nonscalar actual is possibly bit-aligned, we need a copy
-- because the back-end cannot cope with such objects. In other
-- cases where alignment forces a copy, the back-end generates
-- it properly. It should not be generated unconditionally in the
@@ -2028,11 +2072,14 @@ package body Exp_Ch6 is
-- formal subtype are not the same, requiring a check.
-- It is necessary to exclude tagged types because of "downward
- -- conversion" errors.
+ -- conversion" errors, but null-excluding checks on return may be
+ -- required.
elsif Is_Access_Type (E_Formal)
- and then not Same_Type (E_Formal, E_Actual)
and then not Is_Tagged_Type (Designated_Type (E_Formal))
+ and then (not Same_Type (E_Formal, E_Actual)
+ or else (Can_Never_Be_Null (E_Actual)
+ and then not Can_Never_Be_Null (E_Formal)))
then
Add_Call_By_Copy_Code;
@@ -2073,14 +2120,6 @@ package body Exp_Ch6 is
(Ekind (Formal) = E_In_Out_Parameter
and then not In_Subrange_Of (E_Actual, E_Formal)))
then
- -- Perhaps the setting back to False should be done within
- -- Add_Call_By_Copy_Code, since it could get set on other
- -- cases occurring above???
-
- if Do_Range_Check (Actual) then
- Set_Do_Range_Check (Actual, False);
- end if;
-
Add_Call_By_Copy_Code;
end if;
@@ -2194,6 +2233,12 @@ package body Exp_Ch6 is
-- Processing for IN parameters
else
+ -- Generate range check if required
+
+ if Do_Range_Check (Actual) then
+ Generate_Range_Check (Actual, E_Formal, CE_Range_Check_Failed);
+ end if;
+
-- For IN parameters in the bit-packed array case, we expand an
-- indexed component (the circuit in Exp_Ch4 deliberately left
-- indexed components appearing as actuals untouched, so that
@@ -2216,7 +2261,7 @@ package body Exp_Ch6 is
elsif Is_Ref_To_Bit_Packed_Array (Actual) then
Add_Simple_Call_By_Copy_Code;
- -- If a non-scalar actual is possibly unaligned, we need a copy
+ -- If a nonscalar actual is possibly unaligned, we need a copy
elsif Is_Possibly_Unaligned_Object (Actual)
and then not Represented_As_Scalar (Etype (Formal))
@@ -3054,16 +3099,6 @@ package body Exp_Ch6 is
Actual := First_Actual (Call_Node);
Param_Count := 1;
while Present (Formal) loop
-
- -- Generate range check if required
-
- if Do_Range_Check (Actual)
- and then Ekind (Formal) = E_In_Parameter
- then
- Generate_Range_Check
- (Actual, Etype (Formal), CE_Range_Check_Failed);
- end if;
-
-- Prepare to examine current entry
Prev := Actual;
@@ -3582,9 +3617,7 @@ package body Exp_Ch6 is
-- or IN OUT parameter. We do reset the Is_Known_Valid flag
-- since the subprogram could have returned in invalid value.
- if Ekind_In (Formal, E_Out_Parameter, E_In_Out_Parameter)
- and then Is_Assignable (Ent)
- then
+ if Is_Assignable (Ent) then
Sav := Last_Assignment (Ent);
Kill_Current_Values (Ent);
Set_Last_Assignment (Ent, Sav);
@@ -4282,15 +4315,15 @@ package body Exp_Ch6 is
if not Is_Inlined (Subp) then
null;
- -- Frontend inlining of expression functions (performed also when
- -- backend inlining is enabled).
+ -- Front-end inlining of expression functions (performed also when
+ -- back-end inlining is enabled).
elsif Is_Inlinable_Expression_Function (Subp) then
Rewrite (N, New_Copy (Expression_Of_Expression_Function (Subp)));
Analyze (N);
return;
- -- Handle frontend inlining
+ -- Handle front-end inlining
elsif not Back_End_Inlining then
Inlined_Subprogram : declare
@@ -4386,86 +4419,30 @@ package body Exp_Ch6 is
end if;
end Inlined_Subprogram;
- -- Back end inlining: let the back end handle it
-
- elsif No (Unit_Declaration_Node (Subp))
- or else Nkind (Unit_Declaration_Node (Subp)) /=
- N_Subprogram_Declaration
- or else No (Body_To_Inline (Unit_Declaration_Node (Subp)))
- or else Nkind (Body_To_Inline (Unit_Declaration_Node (Subp))) in
- N_Entity
- then
- Add_Inlined_Body (Subp, Call_Node);
-
- -- If the inlined call appears within an instantiation and some
- -- level of optimization is required, ensure that the enclosing
- -- instance body is available so that the back-end can actually
- -- perform the inlining.
-
- if In_Instance
- and then Comes_From_Source (Subp)
- and then Optimization_Level > 0
- then
- declare
- Decl : Node_Id;
- Inst : Entity_Id;
- Inst_Node : Node_Id;
-
- begin
- Inst := Scope (Subp);
-
- -- Find enclosing instance
-
- while Present (Inst) and then Inst /= Standard_Standard loop
- exit when Is_Generic_Instance (Inst);
- Inst := Scope (Inst);
- end loop;
-
- if Present (Inst)
- and then Is_Generic_Instance (Inst)
- and then not Is_Inlined (Inst)
- then
- Set_Is_Inlined (Inst);
- Decl := Unit_Declaration_Node (Inst);
-
- -- Do not add a pending instantiation if the body exits
- -- already, or if the instance is a compilation unit, or
- -- the instance node is missing.
-
- if Present (Corresponding_Body (Decl))
- or else Nkind (Parent (Decl)) = N_Compilation_Unit
- or else No (Next (Decl))
- then
- null;
-
- else
- -- The instantiation node usually follows the package
- -- declaration for the instance. If the generic unit
- -- has aspect specifications, they are transformed
- -- into pragmas in the instance, and the instance node
- -- appears after them.
-
- Inst_Node := Next (Decl);
-
- while Nkind (Inst_Node) /= N_Package_Instantiation loop
- Inst_Node := Next (Inst_Node);
- end loop;
-
- Add_Pending_Instantiation (Inst_Node, Decl);
- end if;
- end if;
- end;
- end if;
-
- -- Front end expansion of simple functions returning unconstrained
+ -- Front-end expansion of simple functions returning unconstrained
-- types (see Check_And_Split_Unconstrained_Function). Note that the
- -- case of a simple renaming (Body_To_Inline in N_Entity above, see
+ -- case of a simple renaming (Body_To_Inline in N_Entity below, see
-- also Build_Renamed_Body) cannot be expanded here because this may
-- give rise to order-of-elaboration issues for the types of the
-- parameters of the subprogram, if any.
- else
+ elsif Present (Unit_Declaration_Node (Subp))
+ and then Nkind (Unit_Declaration_Node (Subp)) =
+ N_Subprogram_Declaration
+ and then Present (Body_To_Inline (Unit_Declaration_Node (Subp)))
+ and then
+ Nkind (Body_To_Inline (Unit_Declaration_Node (Subp))) not in
+ N_Entity
+ then
Expand_Inlined_Call (Call_Node, Subp, Orig_Subp);
+
+ -- Back-end inlining either if optimization is enabled or the call is
+ -- required to be inlined.
+
+ elsif Optimization_Level > 0
+ or else Has_Pragma_Inline_Always (Subp)
+ then
+ Add_Inlined_Body (Subp, Call_Node);
end if;
end if;
@@ -7406,12 +7383,13 @@ package body Exp_Ch6 is
end;
end if;
- -- If we are returning an object that may not be bit-aligned, then copy
- -- the value into a temporary first. This copy may need to expand to a
- -- loop of component operations.
+ -- If we are returning a nonscalar object that is possibly unaligned,
+ -- then copy the value into a temporary first. This copy may need to
+ -- expand to a loop of component operations.
if Is_Possibly_Unaligned_Slice (Exp)
- or else Is_Possibly_Unaligned_Object (Exp)
+ or else (Is_Possibly_Unaligned_Object (Exp)
+ and then not Represented_As_Scalar (Etype (Exp)))
then
declare
ExpR : constant Node_Id := Relocate_Node (Exp);
diff --git a/gcc/ada/exp_dbug.adb b/gcc/ada/exp_dbug.adb
index f0df5e2..3dbe9ad 100644
--- a/gcc/ada/exp_dbug.adb
+++ b/gcc/ada/exp_dbug.adb
@@ -1539,6 +1539,7 @@ package body Exp_Dbug is
elsif Is_Subprogram (Ent)
or else Ekind (Ent) = E_Subprogram_Body
or else Is_Type (Ent)
+ or else Ekind (Ent) = E_Exception
then
Fully_Qualify_Name (Ent);
Name_Len := Full_Qualify_Len;
diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb
index 4fae37c..35fc484 100644
--- a/gcc/ada/exp_disp.adb
+++ b/gcc/ada/exp_disp.adb
@@ -3764,7 +3764,7 @@ package body Exp_Disp is
Dummy_Object : Entity_Id := Empty;
-- Extra nonexistent object of type Typ internally used to compute the
-- offset to the components that reference secondary dispatch tables.
- -- Used to statically allocate secondary dispatch tables.
+ -- Used to compute the offset of components located at fixed position.
procedure Check_Premature_Freezing
(Subp : Entity_Id;
@@ -3817,6 +3817,9 @@ package body Exp_Disp is
-- this secondary dispatch table by Make_Tags when its unique external
-- name was generated.
+ function Number_Of_Predefined_Prims (Typ : Entity_Id) return Nat;
+ -- Returns the number of predefined primitives of Typ
+
------------------------------
-- Check_Premature_Freezing --
------------------------------
@@ -3970,12 +3973,10 @@ package body Exp_Disp is
DT_Constr_List : List_Id;
DT_Aggr_List : List_Id;
Empty_DT : Boolean := False;
- Nb_Predef_Prims : Nat := 0;
Nb_Prim : Nat;
New_Node : Node_Id;
OSD : Entity_Id;
OSD_Aggr_List : List_Id;
- Pos : Nat;
Prim : Entity_Id;
Prim_Elmt : Elmt_Id;
Prim_Ops_Aggr_List : List_Id;
@@ -4022,38 +4023,12 @@ package body Exp_Disp is
-- predef-prim-op-thunk-n'address);
-- for Predef_Prims'Alignment use Address'Alignment
- -- Stage 1: Calculate the number of predefined primitives
-
- if not Building_Static_DT (Typ) then
- Nb_Predef_Prims := Max_Predef_Prims;
- else
- Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
- while Present (Prim_Elmt) loop
- Prim := Node (Prim_Elmt);
-
- if Is_Predefined_Dispatching_Operation (Prim)
- and then not Is_Abstract_Subprogram (Prim)
- then
- Pos := UI_To_Int (DT_Position (Prim));
-
- if Pos > Nb_Predef_Prims then
- Nb_Predef_Prims := Pos;
- end if;
- end if;
-
- Next_Elmt (Prim_Elmt);
- end loop;
- end if;
-
- if Generate_SCIL then
- Nb_Predef_Prims := 0;
- end if;
-
- -- Stage 2: Create the thunks associated with the predefined
- -- primitives and save their entity to fill the aggregate.
+ -- Create the thunks associated with the predefined primitives and
+ -- save their entity to fill the aggregate.
declare
- Prim_Table : array (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
+ Nb_P_Prims : constant Nat := Number_Of_Predefined_Prims (Typ);
+ Prim_Table : array (Nat range 1 .. Nb_P_Prims) of Entity_Id;
Decl : Node_Id;
Thunk_Id : Entity_Id;
Thunk_Code : Node_Id;
@@ -4191,14 +4166,16 @@ package body Exp_Disp is
Prefix => New_Occurrence_Of (Predef_Prims, Loc),
Attribute_Name => Name_Address));
- -- If the location of the component that references this secondary
- -- dispatch table is variable then we have not declared the internal
- -- dummy object; the value of Offset_To_Top will be set by the init
- -- subprogram.
+ -- Interface component located at variable offset; the value of
+ -- Offset_To_Top will be set by the init subprogram.
- if No (Dummy_Object) then
+ if No (Dummy_Object)
+ or else Is_Variable_Size_Record (Etype (Scope (Iface_Comp)))
+ then
Append_To (DT_Aggr_List, Make_Integer_Literal (Loc, 0));
+ -- Interface component located at fixed offset
+
else
Append_To (DT_Aggr_List,
Make_Op_Minus (Loc,
@@ -4444,7 +4421,7 @@ package body Exp_Disp is
Make_Object_Declaration (Loc,
Defining_Identifier => Iface_DT,
Aliased_Present => True,
- Constant_Present => Present (Dummy_Object),
+ Constant_Present => Building_Static_Secondary_DT (Typ),
Object_Definition =>
Make_Subtype_Indication (Loc,
@@ -4523,6 +4500,44 @@ package body Exp_Disp is
Append_Elmt (Iface_DT, DT_Decl);
end Make_Secondary_DT;
+ --------------------------------
+ -- Number_Of_Predefined_Prims --
+ --------------------------------
+
+ function Number_Of_Predefined_Prims (Typ : Entity_Id) return Nat is
+ Nb_Predef_Prims : Nat := 0;
+
+ begin
+ if not Generate_SCIL then
+ declare
+ Prim : Entity_Id;
+ Prim_Elmt : Elmt_Id;
+ Pos : Nat;
+
+ begin
+ Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
+ while Present (Prim_Elmt) loop
+ Prim := Node (Prim_Elmt);
+
+ if Is_Predefined_Dispatching_Operation (Prim)
+ and then not Is_Abstract_Subprogram (Prim)
+ then
+ Pos := UI_To_Int (DT_Position (Prim));
+
+ if Pos > Nb_Predef_Prims then
+ Nb_Predef_Prims := Pos;
+ end if;
+ end if;
+
+ Next_Elmt (Prim_Elmt);
+ end loop;
+ end;
+ end if;
+
+ pragma Assert (Nb_Predef_Prims <= Max_Predef_Prims);
+ return Nb_Predef_Prims;
+ end Number_Of_Predefined_Prims;
+
-- Local variables
Elab_Code : constant List_Id := New_List;
@@ -4582,7 +4597,6 @@ package body Exp_Disp is
I_Depth : Nat := 0;
Iface_Table_Node : Node_Id;
Name_ITable : Name_Id;
- Nb_Predef_Prims : Nat := 0;
Nb_Prim : Nat := 0;
New_Node : Node_Id;
Num_Ifaces : Nat := 0;
@@ -4723,9 +4737,10 @@ package body Exp_Disp is
end;
end if;
- if Building_Static_Secondary_DT (Typ) then
+ if not Is_Interface (Typ) and then Has_Interfaces (Typ) then
declare
Cannot_Have_Null_Disc : Boolean := False;
+ Dummy_Object_Typ : constant Entity_Id := Typ;
Name_Dummy_Object : constant Name_Id :=
New_External_Name (Tname,
'P', Suffix_Index => -1);
@@ -4754,19 +4769,20 @@ package body Exp_Disp is
Set_Is_Internal (Dummy_Object);
- if not Has_Discriminants (Typ) then
+ if not Has_Discriminants (Dummy_Object_Typ) then
Append_To (Result,
Make_Object_Declaration (Loc,
Defining_Identifier => Dummy_Object,
Constant_Present => True,
- Object_Definition => New_Occurrence_Of (Typ, Loc)));
+ Object_Definition => New_Occurrence_Of
+ (Dummy_Object_Typ, Loc)));
else
declare
Constr_List : constant List_Id := New_List;
Discrim : Node_Id;
begin
- Discrim := First_Discriminant (Typ);
+ Discrim := First_Discriminant (Dummy_Object_Typ);
while Present (Discrim) loop
if Is_Discrete_Type (Etype (Discrim)) then
Append_To (Constr_List,
@@ -4792,7 +4808,8 @@ package body Exp_Disp is
Constant_Present => True,
Object_Definition =>
Make_Subtype_Indication (Loc,
- Subtype_Mark => New_Occurrence_Of (Typ, Loc),
+ Subtype_Mark =>
+ New_Occurrence_Of (Dummy_Object_Typ, Loc),
Constraint =>
Make_Index_Or_Discriminant_Constraint (Loc,
Constraints => Constr_List))));
@@ -5500,19 +5517,23 @@ package body Exp_Disp is
declare
TSD_Ifaces_List : constant List_Id := New_List;
Elmt : Elmt_Id;
- Ifaces_List : Elist_Id := No_Elist;
- Ifaces_Comp_List : Elist_Id := No_Elist;
- Ifaces_Tag_List : Elist_Id;
Offset_To_Top : Node_Id;
Sec_DT_Tag : Node_Id;
+ Dummy_Object_Ifaces_List : Elist_Id := No_Elist;
+ Dummy_Object_Ifaces_Comp_List : Elist_Id := No_Elist;
+ Dummy_Object_Ifaces_Tag_List : Elist_Id := No_Elist;
+ -- Interfaces information of the dummy object
+
begin
-- Collect interfaces information if we need to compute the
-- offset to the top using the dummy object.
if Present (Dummy_Object) then
Collect_Interfaces_Info (Typ,
- Ifaces_List, Ifaces_Comp_List, Ifaces_Tag_List);
+ Ifaces_List => Dummy_Object_Ifaces_List,
+ Components_List => Dummy_Object_Ifaces_Comp_List,
+ Tags_List => Dummy_Object_Ifaces_Tag_List);
end if;
AI := First_Elmt (Typ_Ifaces);
@@ -5550,8 +5571,8 @@ package body Exp_Disp is
(Node (Next_Elmt (Next_Elmt (Elmt))), Loc);
end if;
- -- For static dispatch tables compute Offset_To_Top using
- -- the dummy object.
+ -- Use the dummy object to compute Offset_To_Top of
+ -- components located at fixed position.
if Present (Dummy_Object) then
declare
@@ -5561,8 +5582,10 @@ package body Exp_Disp is
Iface_Elmt : Elmt_Id;
begin
- Iface_Elmt := First_Elmt (Ifaces_List);
- Iface_Comp_Elmt := First_Elmt (Ifaces_Comp_List);
+ Iface_Elmt :=
+ First_Elmt (Dummy_Object_Ifaces_List);
+ Iface_Comp_Elmt :=
+ First_Elmt (Dummy_Object_Ifaces_Comp_List);
while Present (Iface_Elmt) loop
if Node (Iface_Elmt) = Iface then
@@ -5576,16 +5599,22 @@ package body Exp_Disp is
pragma Assert (Present (Iface_Comp));
- Offset_To_Top :=
- Make_Op_Minus (Loc,
- Make_Attribute_Reference (Loc,
- Prefix =>
- Make_Selected_Component (Loc,
- Prefix =>
- New_Occurrence_Of (Dummy_Object, Loc),
- Selector_Name =>
- New_Occurrence_Of (Iface_Comp, Loc)),
- Attribute_Name => Name_Position));
+ if not
+ Is_Variable_Size_Record (Etype (Scope (Iface_Comp)))
+ then
+ Offset_To_Top :=
+ Make_Op_Minus (Loc,
+ Make_Attribute_Reference (Loc,
+ Prefix =>
+ Make_Selected_Component (Loc,
+ Prefix =>
+ New_Occurrence_Of (Dummy_Object, Loc),
+ Selector_Name =>
+ New_Occurrence_Of (Iface_Comp, Loc)),
+ Attribute_Name => Name_Position));
+ else
+ Offset_To_Top := Make_Integer_Literal (Loc, 0);
+ end if;
end;
else
Offset_To_Top := Make_Integer_Literal (Loc, 0);
@@ -5634,7 +5663,7 @@ package body Exp_Disp is
Make_Object_Declaration (Loc,
Defining_Identifier => ITable,
Aliased_Present => True,
- Constant_Present => Present (Dummy_Object),
+ Constant_Present => Building_Static_Secondary_DT (Typ),
Object_Definition =>
Make_Subtype_Indication (Loc,
Subtype_Mark =>
@@ -5907,112 +5936,85 @@ package body Exp_Disp is
else
declare
- Pos : Nat;
+ Nb_P_Prims : constant Nat := Number_Of_Predefined_Prims (Typ);
+ Prim_Table : array (Nat range 1 .. Nb_P_Prims) of Entity_Id;
+ Decl : Node_Id;
+ E : Entity_Id;
begin
- if not Building_Static_DT (Typ) then
- Nb_Predef_Prims := Max_Predef_Prims;
+ Prim_Ops_Aggr_List := New_List;
+ Prim_Table := (others => Empty);
- else
- Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
+ if Building_Static_DT (Typ) then
+ Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
while Present (Prim_Elmt) loop
Prim := Node (Prim_Elmt);
if Is_Predefined_Dispatching_Operation (Prim)
and then not Is_Abstract_Subprogram (Prim)
+ and then not Is_Eliminated (Prim)
+ and then not Generate_SCIL
+ and then not Present (Prim_Table
+ (UI_To_Int (DT_Position (Prim))))
then
- Pos := UI_To_Int (DT_Position (Prim));
-
- if Pos > Nb_Predef_Prims then
- Nb_Predef_Prims := Pos;
- end if;
+ E := Ultimate_Alias (Prim);
+ pragma Assert (not Is_Abstract_Subprogram (E));
+ Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
end if;
Next_Elmt (Prim_Elmt);
end loop;
end if;
- declare
- Prim_Table : array
- (Nat range 1 .. Nb_Predef_Prims) of Entity_Id;
- Decl : Node_Id;
- E : Entity_Id;
-
- begin
- Prim_Ops_Aggr_List := New_List;
-
- Prim_Table := (others => Empty);
-
- if Building_Static_DT (Typ) then
- Prim_Elmt := First_Elmt (Primitive_Operations (Typ));
- while Present (Prim_Elmt) loop
- Prim := Node (Prim_Elmt);
-
- if Is_Predefined_Dispatching_Operation (Prim)
- and then not Is_Abstract_Subprogram (Prim)
- and then not Is_Eliminated (Prim)
- and then not Present (Prim_Table
- (UI_To_Int (DT_Position (Prim))))
- then
- E := Ultimate_Alias (Prim);
- pragma Assert (not Is_Abstract_Subprogram (E));
- Prim_Table (UI_To_Int (DT_Position (Prim))) := E;
- end if;
-
- Next_Elmt (Prim_Elmt);
- end loop;
+ for J in Prim_Table'Range loop
+ if Present (Prim_Table (J)) then
+ New_Node :=
+ Unchecked_Convert_To (RTE (RE_Prim_Ptr),
+ Make_Attribute_Reference (Loc,
+ Prefix =>
+ New_Occurrence_Of (Prim_Table (J), Loc),
+ Attribute_Name => Name_Unrestricted_Access));
+ else
+ New_Node := Make_Null (Loc);
end if;
- for J in Prim_Table'Range loop
- if Present (Prim_Table (J)) then
- New_Node :=
- Unchecked_Convert_To (RTE (RE_Prim_Ptr),
- Make_Attribute_Reference (Loc,
- Prefix =>
- New_Occurrence_Of (Prim_Table (J), Loc),
- Attribute_Name => Name_Unrestricted_Access));
- else
- New_Node := Make_Null (Loc);
- end if;
-
- Append_To (Prim_Ops_Aggr_List, New_Node);
- end loop;
+ Append_To (Prim_Ops_Aggr_List, New_Node);
+ end loop;
- New_Node :=
- Make_Aggregate (Loc,
- Expressions => Prim_Ops_Aggr_List);
+ New_Node :=
+ Make_Aggregate (Loc,
+ Expressions => Prim_Ops_Aggr_List);
- Decl :=
- Make_Subtype_Declaration (Loc,
- Defining_Identifier => Make_Temporary (Loc, 'S'),
- Subtype_Indication =>
- New_Occurrence_Of (RTE (RE_Address_Array), Loc));
+ Decl :=
+ Make_Subtype_Declaration (Loc,
+ Defining_Identifier => Make_Temporary (Loc, 'S'),
+ Subtype_Indication =>
+ New_Occurrence_Of (RTE (RE_Address_Array), Loc));
- Append_To (Result, Decl);
+ Append_To (Result, Decl);
- Append_To (Result,
- Make_Object_Declaration (Loc,
- Defining_Identifier => Predef_Prims,
- Aliased_Present => True,
- Constant_Present => Building_Static_DT (Typ),
- Object_Definition =>
- New_Occurrence_Of (Defining_Identifier (Decl), Loc),
- Expression => New_Node));
+ Append_To (Result,
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Predef_Prims,
+ Aliased_Present => True,
+ Constant_Present => Building_Static_DT (Typ),
+ Object_Definition =>
+ New_Occurrence_Of (Defining_Identifier (Decl), Loc),
+ Expression => New_Node));
- -- Remember aggregates initializing dispatch tables
+ -- Remember aggregates initializing dispatch tables
- Append_Elmt (New_Node, DT_Aggr);
+ Append_Elmt (New_Node, DT_Aggr);
- Append_To (Result,
- Make_Attribute_Definition_Clause (Loc,
- Name => New_Occurrence_Of (Predef_Prims, Loc),
- Chars => Name_Alignment,
- Expression =>
- Make_Attribute_Reference (Loc,
- Prefix =>
- New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
- Attribute_Name => Name_Alignment)));
- end;
+ Append_To (Result,
+ Make_Attribute_Definition_Clause (Loc,
+ Name => New_Occurrence_Of (Predef_Prims, Loc),
+ Chars => Name_Alignment,
+ Expression =>
+ Make_Attribute_Reference (Loc,
+ Prefix =>
+ New_Occurrence_Of (RTE (RE_Integer_Address), Loc),
+ Attribute_Name => Name_Alignment)));
end;
-- Stage 1: Initialize the discriminant and the record components
@@ -6284,7 +6286,9 @@ package body Exp_Disp is
(Node
(Next_Elmt
(First_Elmt
- (Access_Disp_Table (Typ)))), Loc)));
+ (Access_Disp_Table (Typ)))), Loc),
+ Num_Predef_Prims =>
+ Number_Of_Predefined_Prims (Parent_Typ)));
if Nb_Prims /= 0 then
Append_To (Elab_Code,
@@ -6373,7 +6377,10 @@ package body Exp_Disp is
Unchecked_Convert_To (RTE (RE_Tag),
New_Occurrence_Of
(Node (Next_Elmt (Sec_DT_Typ)),
- Loc))));
+ Loc)),
+ Num_Predef_Prims =>
+ Number_Of_Predefined_Prims
+ (Parent_Typ)));
if Num_Prims /= 0 then
Append_To (Elab_Code,
@@ -6419,7 +6426,10 @@ package body Exp_Disp is
Unchecked_Convert_To (RTE (RE_Tag),
New_Occurrence_Of
(Node (Next_Elmt (Sec_DT_Typ)),
- Loc))));
+ Loc)),
+ Num_Predef_Prims =>
+ Number_Of_Predefined_Prims
+ (Parent_Typ)));
if Num_Prims /= 0 then
Append_To (Elab_Code,
diff --git a/gcc/ada/exp_dist.adb b/gcc/ada/exp_dist.adb
index 13d45ff..89218c4 100644
--- a/gcc/ada/exp_dist.adb
+++ b/gcc/ada/exp_dist.adb
@@ -963,10 +963,8 @@ package body Exp_Dist is
when N_Package_Declaration =>
-- Case of a nested package or package instantiation coming
- -- from source. Note that the anonymous wrapper package for
- -- subprogram instances is not flagged Is_Generic_Instance at
- -- this point, so there is a distinct circuit to handle them
- -- (see case N_Subprogram_Instantiation below).
+ -- from source, including the wrapper package for an instance
+ -- of a generic subprogram.
declare
Pkg_Ent : constant Entity_Id :=
@@ -982,16 +980,6 @@ package body Exp_Dist is
end if;
end;
- when N_Subprogram_Instantiation =>
-
- -- The subprogram declaration for an instance of a generic
- -- subprogram is wrapped in a package that does not come from
- -- source, so we need to explicitly traverse it here.
-
- if Comes_From_Source (Decl) then
- Visit_Nested_Pkg (Instance_Spec (Decl));
- end if;
-
when others =>
null;
end case;
@@ -8213,6 +8201,12 @@ package body Exp_Dist is
-- type from Interfaces, or the smallest floating point type from
-- Standard whose range encompasses that of Typ.
+ function Is_Generic_Actual_Subtype (Typ : Entity_Id) return Boolean;
+ -- Return true if Typ is a subtype representing a generic formal type
+ -- as a subtype of the actual type in an instance. This is needed to
+ -- recognize these subtypes because the Is_Generic_Actual_Type flag
+ -- can only be relied upon within the instance.
+
function Make_Helper_Function_Name
(Loc : Source_Ptr;
Typ : Entity_Id;
@@ -8465,7 +8459,7 @@ package body Exp_Dist is
-- For the subtype representing a generic actual type, go to the
-- actual type.
- if Is_Generic_Actual_Type (U_Type) then
+ if Is_Generic_Actual_Subtype (U_Type) then
U_Type := Underlying_Type (Base_Type (U_Type));
end if;
@@ -9274,7 +9268,7 @@ package body Exp_Dist is
-- For the subtype representing a generic actual type, go to the
-- actual type.
- if Is_Generic_Actual_Type (U_Type) then
+ if Is_Generic_Actual_Subtype (U_Type) then
U_Type := Underlying_Type (Base_Type (U_Type));
end if;
@@ -10128,7 +10122,7 @@ package body Exp_Dist is
-- For the subtype representing a generic actual type, go to the
-- actual type.
- if Is_Generic_Actual_Type (U_Type) then
+ if Is_Generic_Actual_Subtype (U_Type) then
U_Type := Underlying_Type (Base_Type (U_Type));
end if;
@@ -10913,6 +10907,30 @@ package body Exp_Dist is
end Find_Numeric_Representation;
+ ---------------------------------
+ -- Is_Generic_Actual_Subtype --
+ ---------------------------------
+
+ function Is_Generic_Actual_Subtype (Typ : Entity_Id) return Boolean is
+ begin
+ if Is_Itype (Typ)
+ and then Present (Associated_Node_For_Itype (Typ))
+ then
+ declare
+ N : constant Node_Id := Associated_Node_For_Itype (Typ);
+ begin
+ if Nkind (N) = N_Subtype_Declaration
+ and then Nkind (Parent (N)) = N_Package_Specification
+ and then Is_Generic_Instance (Scope_Of_Spec (Parent (N)))
+ then
+ return True;
+ end if;
+ end;
+ end if;
+
+ return False;
+ end Is_Generic_Actual_Subtype;
+
---------------------------
-- Append_Array_Traversal --
---------------------------
diff --git a/gcc/ada/exp_spark.adb b/gcc/ada/exp_spark.adb
index 63f2dad..ea1381c 100644
--- a/gcc/ada/exp_spark.adb
+++ b/gcc/ada/exp_spark.adb
@@ -201,7 +201,38 @@ package body Exp_SPARK is
-- by the corresponding literal value.
elsif Attr_Id = Attribute_Enum_Rep then
- Exp_Attr.Expand_N_Attribute_Reference (N);
+ declare
+ Exprs : constant List_Id := Expressions (N);
+ begin
+ if Is_Non_Empty_List (Exprs) then
+ Expr := First (Exprs);
+ else
+ Expr := Prefix (N);
+ end if;
+
+ -- If the argument is a literal, expand it
+
+ if Nkind (Expr) in N_Has_Entity
+ and then
+ (Ekind (Entity (Expr)) = E_Enumeration_Literal
+ or else
+ (Nkind (Expr) in N_Has_Entity
+ and then Ekind (Entity (Expr)) = E_Constant
+ and then Present (Renamed_Object (Entity (Expr)))
+ and then Is_Entity_Name (Renamed_Object (Entity (Expr)))
+ and then Ekind (Entity (Renamed_Object (Entity (Expr)))) =
+ E_Enumeration_Literal))
+ then
+ Exp_Attr.Expand_N_Attribute_Reference (N);
+ end if;
+ end;
+
+ elsif Attr_Id = Attribute_Object_Size
+ or else Attr_Id = Attribute_Size
+ or else Attr_Id = Attribute_Value_Size
+ or else Attr_Id = Attribute_VADS_Size
+ then
+ Exp_Attr.Expand_Size_Attribute (N);
-- For attributes which return Universal_Integer, introduce a conversion
-- to the expected type with the appropriate check flags set.
@@ -217,10 +248,6 @@ package body Exp_SPARK is
or else Attr_Id = Attribute_Pos
or else Attr_Id = Attribute_Position
or else Attr_Id = Attribute_Range_Length
- or else Attr_Id = Attribute_Object_Size
- or else Attr_Id = Attribute_Size
- or else Attr_Id = Attribute_Value_Size
- or else Attr_Id = Attribute_VADS_Size
or else Attr_Id = Attribute_Aft
or else Attr_Id = Attribute_Max_Alignment_For_Allocation
then
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index b677a72..41708c3 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -4444,8 +4444,8 @@ package body Exp_Util is
begin
-- If no component clause, then everything is fine, since the back end
- -- never bit-misaligns by default, even if there is a pragma Packed for
- -- the record.
+ -- never misaligns from byte boundaries by default, even if there is a
+ -- pragma Pack for the record.
if No (Comp) or else No (Component_Clause (Comp)) then
return False;
@@ -8485,12 +8485,6 @@ package body Exp_Util is
return False;
end if;
- -- We only need to worry if the target has strict alignment
-
- if not Target_Strict_Alignment then
- return False;
- end if;
-
-- If it is a slice, then look at the array type being sliced
declare
@@ -10713,9 +10707,9 @@ package body Exp_Util is
Ptyp : constant Entity_Id := Etype (P);
begin
- -- If we know the component size and it is less than 64, then
- -- we are definitely OK. The back end always does assignment of
- -- misaligned small objects correctly.
+ -- If we know the component size and it is not larger than 64,
+ -- then we are definitely OK. The back end does the assignment
+ -- of misaligned small objects correctly.
if Known_Static_Component_Size (Ptyp)
and then Component_Size (Ptyp) <= 64
@@ -10738,13 +10732,15 @@ package body Exp_Util is
Comp : constant Entity_Id := Entity (Selector_Name (N));
begin
- -- If there is no component clause, then we are in the clear
- -- since the back end will never misalign a large component
- -- unless it is forced to do so. In the clear means we need
- -- only the recursive test on the prefix.
+ -- This is the crucial test: if the component itself causes
+ -- trouble, then we can stop and return True.
if Component_May_Be_Bit_Aligned (Comp) then
return True;
+
+ -- Otherwise, we need to test the prefix, to see if we are
+ -- selecting from a possibly unaligned component.
+
else
return Possible_Bit_Aligned_Component (P);
end if;
@@ -10757,7 +10753,7 @@ package body Exp_Util is
return Possible_Bit_Aligned_Component (Prefix (N));
-- For an unchecked conversion, check whether the expression may
- -- be bit-aligned.
+ -- be bit aligned.
when N_Unchecked_Type_Conversion =>
return Possible_Bit_Aligned_Component (Expression (N));
@@ -13511,9 +13507,17 @@ package body Exp_Util is
begin
E := First_Component_Or_Discriminant (Typ);
while Present (E) loop
- if Component_May_Be_Bit_Aligned (E)
- or else Type_May_Have_Bit_Aligned_Components (Etype (E))
- then
+ -- This is the crucial test: if the component itself causes
+ -- trouble, then we can stop and return True.
+
+ if Component_May_Be_Bit_Aligned (E) then
+ return True;
+ end if;
+
+ -- Otherwise, we need to test its type, to see if it may
+ -- itself contain a troublesome component.
+
+ if Type_May_Have_Bit_Aligned_Components (Etype (E)) then
return True;
end if;
diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads
index c0848c7..30a3c71 100644
--- a/gcc/ada/exp_util.ads
+++ b/gcc/ada/exp_util.ads
@@ -401,32 +401,27 @@ package Exp_Util is
-- case overflow.
function Component_May_Be_Bit_Aligned (Comp : Entity_Id) return Boolean;
- -- This function is in charge of detecting record components that may
- -- cause trouble in the back end if an attempt is made to assign the
- -- component. The back end can handle such assignments with no problem if
- -- the components involved are small (64-bits or less) records or scalar
- -- items (including bit-packed arrays represented with modular types) or
- -- are both aligned on a byte boundary (starting on a byte boundary, and
- -- occupying an integral number of bytes).
+ -- This function is in charge of detecting record components that may cause
+ -- trouble for the back end if an attempt is made to access the component
+ -- as a whole. The back end can handle such accesses with no problem if the
+ -- components involved are small (64 bits or less) records or scalar items
+ -- (including bit-packed arrays represented with a modular type), or else
+ -- if they are aligned on byte boundaries (i.e. starting on a byte boundary
+ -- and occupying an integral number of bytes).
--
-- However, problems arise for records larger than 64 bits, or for arrays
-- (other than bit-packed arrays represented with a modular type) if the
- -- component starts on a non-byte boundary, or does not occupy an integral
- -- number of bytes (i.e. there are some bits possibly shared with fields
- -- at the start or beginning of the component). The back end cannot handle
- -- loading and storing such components in a single operation.
+ -- component either does not start on a byte boundary or does not occupy an
+ -- integral number of bytes (i.e. there are some bits possibly shared with
+ -- other components at the start or the end of the component). The back end
+ -- cannot handle loading from or storing to such components as a whole.
--
- -- This function is used to detect the troublesome situation. it is
- -- conservative in the sense that it produces True unless it knows for
- -- sure that the component is safe (as outlined in the first paragraph
- -- above). The code generation for record and array assignment checks for
- -- trouble using this function, and if so the assignment is generated
+ -- This function is used to detect the troublesome situation. It is meant
+ -- to be conservative in the sense that it produces True unless it knows
+ -- for sure that the component is safe (as outlined in the first paragraph
+ -- above). The processing for record and array assignment indirectly checks
+ -- for trouble using this function and, if so, the assignment is expanded
-- component-wise, which the back end is required to handle correctly.
- --
- -- Note that in GNAT 3, the back end will reject such components anyway,
- -- so the hard work in checking for this case is wasted in GNAT 3, but
- -- it is harmless, so it is easier to do it in all cases, rather than
- -- conditionalize it in GNAT 5 or beyond.
function Containing_Package_With_Ext_Axioms
(E : Entity_Id) return Entity_Id;
@@ -962,12 +957,12 @@ package Exp_Util is
-- returned only if the replacement is safe.
function Possible_Bit_Aligned_Component (N : Node_Id) return Boolean;
- -- This function is used during processing the assignment of a record or
- -- indexed component. The argument N is either the left hand or right hand
- -- side of an assignment, and this function determines if there is a record
- -- component reference where the record may be bit aligned in a manner that
- -- causes trouble for the back end (see Component_May_Be_Bit_Aligned for
- -- further details).
+ -- This function is used during processing the assignment of a record or an
+ -- array, or the construction of an aggregate. The argument N is either the
+ -- left or the right hand side of an assignment and the function determines
+ -- whether there is a record component reference where the component may be
+ -- bit aligned in a manner that causes trouble for the back end (see also
+ -- Component_May_Be_Bit_Aligned for further details).
function Power_Of_Two (N : Node_Id) return Nat;
-- Determines if N is a known at compile time value which is of the form
@@ -1170,8 +1165,9 @@ package Exp_Util is
function Type_May_Have_Bit_Aligned_Components
(Typ : Entity_Id) return Boolean;
-- Determines if Typ is a composite type that has within it (looking down
- -- recursively at any subcomponents), a record type which has component
- -- that may be bit aligned (see Possible_Bit_Aligned_Component). The result
+ -- recursively at subcomponents) a record which contains a component that
+ -- may be bit aligned in a manner that causes trouble for the back end
+ -- (see also Component_May_Be_Bit_Aligned for further details). The result
-- is conservative, in that a result of False is decisive. A result of True
-- means that such a component may or may not be present.
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 00d20e9..70f4b9d 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -786,9 +786,7 @@ package body Freeze is
elsif Has_Size_Clause (T) then
if RM_Size (T) < S then
Error_Msg_Uint_1 := S;
- Error_Msg_NE
- ("size for& too small, minimum allowed is ^",
- Size_Clause (T), T);
+ Error_Msg_NE (Size_Too_Small_Message, Size_Clause (T), T);
end if;
-- Set size if not set already
@@ -1526,11 +1524,11 @@ package body Freeze is
-- so that LSP can be verified/enforced.
Op_Node := First_Elmt (Prim_Ops);
- Needs_Wrapper := False;
while Present (Op_Node) loop
- Decls := Empty_List;
- Prim := Node (Op_Node);
+ Decls := Empty_List;
+ Prim := Node (Op_Node);
+ Needs_Wrapper := False;
if not Comes_From_Source (Prim) and then Present (Alias (Prim)) then
Par_Prim := Alias (Prim);
@@ -1601,8 +1599,6 @@ package body Freeze is
(Par_R, New_List (New_Decl, New_Body));
end if;
end;
-
- Needs_Wrapper := False;
end if;
Next_Elmt (Op_Node);
@@ -6803,7 +6799,7 @@ package body Freeze is
-- Do not allow a size clause for a type which does not have a size
-- that is known at compile time
- if Has_Size_Clause (E)
+ if (Has_Size_Clause (E) or else Has_Object_Size_Clause (E))
and then not Size_Known_At_Compile_Time (E)
then
-- Suppress this message if errors posted on E, even if we are
diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in
index b6a337a1..df5f0b3 100644
--- a/gcc/ada/gcc-interface/Make-lang.in
+++ b/gcc/ada/gcc-interface/Make-lang.in
@@ -74,7 +74,6 @@ GNATLIBCFLAGS= -g -O2 $(TCFLAGS)
ADA_INCLUDE_DIR = $(libsubdir)/adainclude
ADA_RTL_OBJ_DIR = $(libsubdir)/adalib
THREAD_KIND=native
-TRACE=no
# We do not want the WARN_CFLAGS of the compiler in Ada as it is for C/C++.
COMMON_FLAGS_TO_PASS = $(filter-out $(WARN_CFLAGS), $(FLAGS_TO_PASS))
ADA_FLAGS_TO_PASS = \
@@ -701,7 +700,7 @@ gnatlib gnatlib-sjlj gnatlib-zcx gnatlib-shared: force
GNATLIBCFLAGS="$(GNATLIBCFLAGS)" \
TARGET_LIBGCC2_CFLAGS="$(TARGET_LIBGCC2_CFLAGS)" \
THREAD_KIND="$(THREAD_KIND)" \
- TRACE="$(TRACE)" \
+ LN_S="$(LN_S)" \
FORCE_DEBUG_ADAFLAGS="$(FORCE_DEBUG_ADAFLAGS)" \
$@
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index a0a5bb2..d4c9d15 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -516,6 +516,8 @@ install-gnatlib: ../stamp-gnatlib-$(RTSDIR) install-gcc-specs
for file in $(RTSDIR)/*.ali; do \
$(INSTALL_DATA_DATE) $$file $(DESTDIR)$(ADA_RTL_OBJ_DIR); \
done
+ $(INSTALL_DATA_DATE) $(RTSDIR)/ada_target_properties \
+ $(DESTDIR)$(ADA_RTL_OBJ_DIR)/../
-cd $(RTSDIR); for file in *$(arext);do \
$(INSTALL_DATA) $$file $(DESTDIR)$(ADA_RTL_OBJ_DIR); \
$(RANLIB_FOR_TARGET) $(DESTDIR)$(ADA_RTL_OBJ_DIR)/$$file; \
@@ -563,7 +565,7 @@ install-gnatlib: ../stamp-gnatlib-$(RTSDIR) install-gcc-specs
$(RM) ../stamp-gnatlib-$(RTSDIR)
../stamp-gnatlib1-$(RTSDIR): Makefile ../stamp-gnatlib2-$(RTSDIR)
- $(MAKE) MULTISUBDIR="$(MULTISUBDIR)" THREAD_KIND="$(THREAD_KIND)" setup-rts
+ $(MAKE) MULTISUBDIR="$(MULTISUBDIR)" THREAD_KIND="$(THREAD_KIND)" LN_S="$(LN_S)" setup-rts
# Copy tsystem.h
$(CP) $(srcdir)/tsystem.h $(RTSDIR)
$(RM) ../stamp-gnatlib-$(RTSDIR)
@@ -651,6 +653,7 @@ gnatlib-shared-default:
GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C) $(PICFLAG_FOR_TARGET)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
+ LN_S="$(LN_S)" \
gnatlib
$(RM) $(RTSDIR)/libgna*$(soext)
cd $(RTSDIR); `echo "$(GCC_FOR_TARGET)" \
@@ -681,7 +684,6 @@ gnatlib-shared-default:
$(addprefix $(RTSDIR)/,$(GNATRTL_TASKING_OBJS))
$(RANLIB_FOR_TARGET) $(RTSDIR)/libgnarl_pic$(arext)
-
gnatlib-shared-dual:
$(MAKE) $(FLAGS_TO_PASS) \
GNATLIBFLAGS="$(GNATLIBFLAGS)" \
@@ -690,6 +692,7 @@ gnatlib-shared-dual:
PICFLAG_FOR_TARGET="$(PICFLAG_FOR_TARGET)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
+ LN_S="$(LN_S)" \
gnatlib-shared-default
$(MV) $(RTSDIR)/libgna*$(soext) .
$(MV) $(RTSDIR)/libgnat_pic$(arext) .
@@ -701,7 +704,8 @@ gnatlib-shared-dual:
GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
- gnatlib
+ LN_S="$(LN_S)" \
+ gnatlib
$(MV) libgna*$(soext) $(RTSDIR)
$(MV) libgnat_pic$(arext) $(RTSDIR)
$(MV) libgnarl_pic$(arext) $(RTSDIR)
@@ -714,7 +718,8 @@ gnatlib-shared-dual-win32:
PICFLAG_FOR_TARGET="$(PICFLAG_FOR_TARGET)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
- gnatlib-shared-win32
+ LN_S="$(LN_S)" \
+ gnatlib-shared-win32
$(MV) $(RTSDIR)/libgna*$(soext) .
$(RM) ../stamp-gnatlib2-$(RTSDIR)
$(MAKE) $(FLAGS_TO_PASS) \
@@ -723,7 +728,8 @@ gnatlib-shared-dual-win32:
GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
- gnatlib
+ LN_S="$(LN_S)" \
+ gnatlib
$(MV) libgna*$(soext) $(RTSDIR)
# ??? we need to add the option to support auto-import of arrays/records to
@@ -737,7 +743,8 @@ gnatlib-shared-win32:
GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C) $(PICFLAG_FOR_TARGET)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
- gnatlib
+ LN_S="$(LN_S)" \
+ gnatlib
$(RM) $(RTSDIR)/libgna*$(soext)
$(CP) $(RTSDIR)/libgnat$(arext) $(RTSDIR)/libgnat_pic$(arext)
$(CP) $(RTSDIR)/libgnarl$(arext) $(RTSDIR)/libgnarl_pic$(arext)
@@ -762,6 +769,7 @@ gnatlib-shared-darwin:
GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C) $(PICFLAG_FOR_TARGET) -fno-common" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
+ LN_S="$(LN_S)" \
gnatlib
$(RM) $(RTSDIR)/libgnat$(soext) $(RTSDIR)/libgnarl$(soext)
$(CP) $(RTSDIR)/libgnat$(arext) $(RTSDIR)/libgnat_pic$(arext)
@@ -794,8 +802,9 @@ gnatlib-shared:
GNATLIBCFLAGS_FOR_C="$(GNATLIBCFLAGS_FOR_C)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
+ LN_S="$(LN_S)" \
PICFLAG_FOR_TARGET="$(PICFLAG_FOR_TARGET)" \
- $(GNATLIB_SHARED)
+ $(GNATLIB_SHARED)
# When building a SJLJ runtime for VxWorks, we need to ensure that the extra
# linker options needed for ZCX are not passed to prevent the inclusion of
@@ -808,6 +817,7 @@ gnatlib-sjlj:
EH_MECHANISM="" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
+ LN_S="$(LN_S)" \
../stamp-gnatlib1-$(RTSDIR)
sed \
-e 's/Frontend_Exceptions.*/Frontend_Exceptions : constant Boolean := True;/' \
@@ -822,6 +832,7 @@ gnatlib-sjlj:
FORCE_DEBUG_ADAFLAGS="$(FORCE_DEBUG_ADAFLAGS)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
+ LN_S="$(LN_S)" \
gnatlib
gnatlib-zcx:
@@ -829,6 +840,7 @@ gnatlib-zcx:
EH_MECHANISM="-gcc" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
+ LN_S="$(LN_S)" \
../stamp-gnatlib1-$(RTSDIR)
sed \
-e 's/Frontend_Exceptions.*/Frontend_Exceptions : constant Boolean := False;/' \
@@ -843,6 +855,7 @@ gnatlib-zcx:
FORCE_DEBUG_ADAFLAGS="$(FORCE_DEBUG_ADAFLAGS)" \
MULTISUBDIR="$(MULTISUBDIR)" \
THREAD_KIND="$(THREAD_KIND)" \
+ LN_S="$(LN_S)" \
gnatlib
# Compiling object files from source files.
diff --git a/gcc/ada/gcc-interface/lang.opt b/gcc/ada/gcc-interface/lang.opt
index cc9fa49..4295651 100644
--- a/gcc/ada/gcc-interface/lang.opt
+++ b/gcc/ada/gcc-interface/lang.opt
@@ -56,6 +56,10 @@ Wall
Ada AdaWhy AdaSCIL
Enable most warning messages.
+fdump-scos
+Ada RejectNegative Var(flag_dump_scos) Init(0)
+Dump Source Coverage Obligations
+
k8
Driver
Synonym of -gnatk8.
diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index 5737165..d53374e 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -161,6 +161,7 @@ gnat_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
case OPT_gnatO:
case OPT_fRTS_:
case OPT_I:
+ case OPT_fdump_scos:
case OPT_nostdinc:
case OPT_nostdlib:
/* These are handled by the front-end. */
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 6cd3759..6c696b9 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -493,8 +493,7 @@ gigi (Node_Id gnat_root,
build_function_type_list (integer_type_node, jmpbuf_ptr_type,
NULL_TREE),
NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
- DECL_BUILT_IN_CLASS (setjmp_decl) = BUILT_IN_NORMAL;
- DECL_FUNCTION_CODE (setjmp_decl) = BUILT_IN_SETJMP;
+ set_decl_built_in_function (setjmp_decl, BUILT_IN_NORMAL, BUILT_IN_SETJMP);
/* update_setjmp_buf updates a setjmp buffer from the current stack pointer
address. */
@@ -503,8 +502,8 @@ gigi (Node_Id gnat_root,
(get_identifier ("__builtin_update_setjmp_buf"), NULL_TREE,
build_function_type_list (void_type_node, jmpbuf_ptr_type, NULL_TREE),
NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
- DECL_BUILT_IN_CLASS (update_setjmp_buf_decl) = BUILT_IN_NORMAL;
- DECL_FUNCTION_CODE (update_setjmp_buf_decl) = BUILT_IN_UPDATE_SETJMP_BUF;
+ set_decl_built_in_function (update_setjmp_buf_decl, BUILT_IN_NORMAL,
+ BUILT_IN_UPDATE_SETJMP_BUF);
/* Indicate that it never returns. */
ftype = build_function_type_list (void_type_node,
@@ -524,22 +523,27 @@ gigi (Node_Id gnat_root,
NULL_TREE, is_default, true, true, true, false, false, NULL, Empty);
/* Hooks to call when entering/leaving an exception handler. */
- ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
-
+ ftype = build_function_type_list (ptr_type_node,
+ ptr_type_node, NULL_TREE);
begin_handler_decl
- = create_subprog_decl (get_identifier ("__gnat_begin_handler"), NULL_TREE,
- ftype, NULL_TREE,
+ = create_subprog_decl (get_identifier ("__gnat_begin_handler_v1"),
+ NULL_TREE, ftype, NULL_TREE,
is_default, true, true, true, false, false, NULL,
Empty);
- /* __gnat_begin_handler is a dummy procedure. */
+ /* __gnat_begin_handler_v1 is not a dummy procedure, but we arrange
+ for it not to throw. */
TREE_NOTHROW (begin_handler_decl) = 1;
+ ftype = build_function_type_list (ptr_type_node,
+ ptr_type_node, ptr_type_node,
+ ptr_type_node, NULL_TREE);
end_handler_decl
- = create_subprog_decl (get_identifier ("__gnat_end_handler"), NULL_TREE,
+ = create_subprog_decl (get_identifier ("__gnat_end_handler_v1"), NULL_TREE,
ftype, NULL_TREE,
is_default, true, true, true, false, false, NULL,
Empty);
+ ftype = build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
unhandled_except_decl
= create_subprog_decl (get_identifier ("__gnat_unhandled_except_handler"),
NULL_TREE, ftype, NULL_TREE,
@@ -3394,9 +3398,6 @@ independent_iterations_p (tree stmt_list)
static tree
Acc_Loop_to_gnu (Node_Id gnat_loop)
{
- const struct loop_info_d * const gnu_loop_info = gnu_loop_stack->last ();
- tree gnu_loop_stmt = gnu_loop_info->stmt;
-
tree acc_loop = make_node (OACC_LOOP);
tree acc_bind_expr = NULL_TREE;
Node_Id cur_loop = gnat_loop;
@@ -3513,7 +3514,7 @@ Acc_Loop_to_gnu (Node_Id gnat_loop)
BIND_EXPR_BODY (acc_bind_expr) = acc_loop;
- return gnu_loop_stmt;
+ return acc_bind_expr;
}
/* Helper for Loop_Statement_to_gnu, to translate the body of a loop not
@@ -5530,7 +5531,7 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target,
tree pred_cst = build_int_cst (integer_type_node, PRED_BUILTIN_EXPECT);
enum internal_fn icode = IFN_BUILTIN_EXPECT;
- switch (DECL_FUNCTION_CODE (gnu_subprog))
+ switch (DECL_FE_FUNCTION_CODE (gnu_subprog))
{
case BUILT_IN_EXPECT:
break;
@@ -6201,37 +6202,55 @@ Exception_Handler_to_gnu_gcc (Node_Id gnat_node)
start_stmt_group ();
gnat_pushlevel ();
- /* Expand a call to the begin_handler hook at the beginning of the handler,
- and arrange for a call to the end_handler hook to occur on every possible
- exit path.
+ /* Expand a call to the begin_handler hook at the beginning of the
+ handler, and arrange for a call to the end_handler hook to occur
+ on every possible exit path. GDB sets a breakpoint in the
+ begin_handler for catchpoints.
- The hooks expect a pointer to the low level occurrence. This is required
- for our stack management scheme because a raise inside the handler pushes
- a new occurrence on top of the stack, which means that this top does not
- necessarily match the occurrence this handler was dealing with.
+ A v1 begin handler saves the cleanup from the exception object,
+ and marks the exception as in use, so that it will not be
+ released by other handlers. A v1 end handler restores the
+ cleanup and releases the exception object, unless it is still
+ claimed, or the exception is being propagated (reraised).
__builtin_eh_pointer references the exception occurrence being
- propagated. Upon handler entry, this is the exception for which the
- handler is triggered. This might not be the case upon handler exit,
- however, as we might have a new occurrence propagated by the handler's
- body, and the end_handler hook called as a cleanup in this context.
-
- We use a local variable to retrieve the incoming value at handler entry
- time, and reuse it to feed the end_handler hook's argument at exit. */
-
+ handled or propagated. Within the handler region, it is the
+ former, but within the else branch of the EH_ELSE_EXPR, i.e. the
+ exceptional cleanup path, it is the latter, so we must save the
+ occurrence being handled early on, so that, should an exception
+ be (re)raised, we can release the current exception, or figure
+ out we're not to release it because we're propagating a reraise
+ thereof.
+
+ We use local variables to retrieve the incoming value at handler
+ entry time (EXPTR), the saved cleanup (EXCLN) and the token
+ (EXVTK), and reuse them to feed the end_handler hook's argument
+ at exit. */
+
+ /* CODE: void *EXPTR = __builtin_eh_pointer (0); */
tree gnu_current_exc_ptr
= build_call_expr (builtin_decl_explicit (BUILT_IN_EH_POINTER),
1, integer_zero_node);
- tree prev_gnu_incoming_exc_ptr = gnu_incoming_exc_ptr;
- gnu_incoming_exc_ptr
+ tree exc_ptr
= create_var_decl (get_identifier ("EXPTR"), NULL_TREE,
ptr_type_node, gnu_current_exc_ptr,
- false, false, false, false, false, true, true,
+ true, false, false, false, false, true, true,
NULL, gnat_node);
- add_stmt_with_node (build_call_n_expr (begin_handler_decl, 1,
- gnu_incoming_exc_ptr),
- gnat_node);
+ tree prev_gnu_incoming_exc_ptr = gnu_incoming_exc_ptr;
+ gnu_incoming_exc_ptr = exc_ptr;
+
+ /* begin_handler_decl must not throw, so we can use it as an
+ initializer for a variable used in cleanups.
+
+ CODE: void *EXCLN = __gnat_begin_handler_v1 (EXPTR); */
+ tree exc_cleanup
+ = create_var_decl (get_identifier ("EXCLN"), NULL_TREE,
+ ptr_type_node,
+ build_call_n_expr (begin_handler_decl, 1,
+ exc_ptr),
+ true, false, false, false, false,
+ true, true, NULL, gnat_node);
/* Declare and initialize the choice parameter, if present. */
if (Present (Choice_Parameter (gnat_node)))
@@ -6239,21 +6258,64 @@ Exception_Handler_to_gnu_gcc (Node_Id gnat_node)
tree gnu_param
= gnat_to_gnu_entity (Choice_Parameter (gnat_node), NULL_TREE, true);
+ /* CODE: __gnat_set_exception_parameter (&choice_param, EXPTR); */
add_stmt (build_call_n_expr
(set_exception_parameter_decl, 2,
build_unary_op (ADDR_EXPR, NULL_TREE, gnu_param),
gnu_incoming_exc_ptr));
}
+ /* CODE: <handler proper> */
add_stmt_list (Statements (gnat_node));
- /* We don't have an End_Label at hand to set the location of the cleanup
- actions, so we use that of the exception handler itself instead. */
- tree stmt = build_call_n_expr (end_handler_decl, 1, gnu_incoming_exc_ptr);
+ tree call = build_call_n_expr (end_handler_decl, 3,
+ exc_ptr,
+ exc_cleanup,
+ null_pointer_node);
+ /* If the handler can only end by falling off the end, don't bother
+ with cleanups. */
if (stmt_list_cannot_alter_control_flow_p (Statements (gnat_node)))
- add_stmt_with_node (stmt, gnat_node);
+ /* CODE: __gnat_end_handler_v1 (EXPTR, EXCLN, NULL); */
+ add_stmt_with_node (call, gnat_node);
+ /* Otherwise, all of the above is after
+ CODE: try {
+
+ The call above will appear after
+ CODE: } finally {
+
+ And the code below will appear after
+ CODE: } else {
+
+ The else block to a finally block is taken instead of the finally
+ block when an exception propagates out of the try block. */
else
- add_cleanup (stmt, gnat_node);
+ {
+ start_stmt_group ();
+ gnat_pushlevel ();
+ /* CODE: void *EXPRP = __builtin_eh_handler (0); */
+ tree prop_ptr
+ = create_var_decl (get_identifier ("EXPRP"), NULL_TREE,
+ ptr_type_node,
+ build_call_expr (builtin_decl_explicit
+ (BUILT_IN_EH_POINTER),
+ 1, integer_zero_node),
+ true, false, false, false, false,
+ true, true, NULL, gnat_node);
+
+ /* CODE: __gnat_end_handler_v1 (EXPTR, EXCLN, EXPRP); */
+ tree ecall = build_call_n_expr (end_handler_decl, 3,
+ exc_ptr,
+ exc_cleanup,
+ prop_ptr);
+
+ add_stmt_with_node (ecall, gnat_node);
+
+ /* CODE: } */
+ gnat_poplevel ();
+ tree eblk = end_stmt_group ();
+ tree ehls = build2 (EH_ELSE_EXPR, void_type_node, call, eblk);
+ add_cleanup (ehls, gnat_node);
+ }
gnat_poplevel ();
@@ -8270,19 +8332,11 @@ gnat_to_gnu (Node_Id gnat_node)
gcc_assert (No (Name (gnat_node)) && Back_End_Exceptions ());
start_stmt_group ();
- gnat_pushlevel ();
- /* Clear the current exception pointer so that the occurrence won't be
- deallocated. */
- gnu_expr = create_var_decl (get_identifier ("SAVED_EXPTR"), NULL_TREE,
- ptr_type_node, gnu_incoming_exc_ptr,
- false, false, false, false, false,
- true, true, NULL, gnat_node);
+ add_stmt_with_node (build_call_n_expr (reraise_zcx_decl, 1,
+ gnu_incoming_exc_ptr),
+ gnat_node);
- add_stmt (build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_incoming_exc_ptr,
- build_int_cst (ptr_type_node, 0)));
- add_stmt (build_call_n_expr (reraise_zcx_decl, 1, gnu_expr));
- gnat_poplevel ();
gnu_result = end_stmt_group ();
break;
@@ -9073,7 +9127,23 @@ add_cleanup (tree gnu_cleanup, Node_Id gnat_node)
{
if (Present (gnat_node))
set_expr_location_from_node (gnu_cleanup, gnat_node, true);
- append_to_statement_list (gnu_cleanup, &current_stmt_group->cleanups);
+ /* An EH_ELSE_EXPR must be by itself, and that's all we need when we
+ use it. The assert below makes sure that is so. Should we ever
+ need more than that, we could combine EH_ELSE_EXPRs, and copy
+ non-EH_ELSE_EXPR stmts into both cleanup paths of an
+ EH_ELSE_EXPR. */
+ if (TREE_CODE (gnu_cleanup) == EH_ELSE_EXPR)
+ {
+ gcc_assert (!current_stmt_group->cleanups);
+ current_stmt_group->cleanups = gnu_cleanup;
+ }
+ else
+ {
+ gcc_assert (!current_stmt_group->cleanups
+ || (TREE_CODE (current_stmt_group->cleanups)
+ != EH_ELSE_EXPR));
+ append_to_statement_list (gnu_cleanup, &current_stmt_group->cleanups);
+ }
}
/* Set the BLOCK node corresponding to the current code group to GNU_BLOCK. */
diff --git a/gcc/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb
index ecb3ccd..af07a06 100644
--- a/gcc/ada/gnat1drv.adb
+++ b/gcc/ada/gnat1drv.adb
@@ -803,6 +803,10 @@ procedure Gnat1drv is
not Generate_C_Code
+ -- No back-end inlining available in ASIS mode
+
+ and then not ASIS_Mode
+
-- No back-end inlining in GNATprove mode, since it just confuses
-- the formal verification process.
@@ -1018,9 +1022,11 @@ procedure Gnat1drv is
Atree.Unlock;
Nlists.Unlock;
+ Elists.Unlock;
Sem.Unlock;
Sem_Prag.Validate_Compile_Time_Warning_Errors;
Sem.Lock;
+ Elists.Lock;
Nlists.Lock;
Atree.Lock;
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index 257c394..be31ed8 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -21,7 +21,7 @@
@copying
@quotation
-GNAT Reference Manual , Jun 21, 2019
+GNAT Reference Manual , Aug 01, 2019
AdaCore
@@ -207,6 +207,7 @@ Implementation Defined Pragmas
* Pragma Main_Storage::
* Pragma Max_Queue_Length::
* Pragma No_Body::
+* Pragma No_Caching::
* Pragma No_Component_Reordering::
* Pragma No_Elaboration_Code_All::
* Pragma No_Heap_Finalization::
@@ -331,6 +332,7 @@ Implementation Defined Aspects
* Aspect Linker_Section::
* Aspect Lock_Free::
* Aspect Max_Queue_Length::
+* Aspect No_Caching::
* Aspect No_Elaboration_Code_All::
* Aspect No_Inline::
* Aspect No_Tagged_Streams::
@@ -575,7 +577,7 @@ Implementation Advice
* RM 13.9(14-17); Unchecked Conversion: RM 13 9 14-17 Unchecked Conversion.
* RM 13.11(23-25); Implicit Heap Usage: RM 13 11 23-25 Implicit Heap Usage.
* RM 13.11.2(17); Unchecked Deallocation: RM 13 11 2 17 Unchecked Deallocation.
-* RM 13.13.2(17); Stream Oriented Attributes: RM 13 13 2 17 Stream Oriented Attributes.
+* RM 13.13.2(1.6); Stream Oriented Attributes: RM 13 13 2 1 6 Stream Oriented Attributes.
* RM A.1(52); Names of Predefined Numeric Types: RM A 1 52 Names of Predefined Numeric Types.
* RM A.3.2(49); Ada.Characters.Handling: RM A 3 2 49 Ada Characters Handling.
* RM A.4.4(106); Bounded-Length String Handling: RM A 4 4 106 Bounded-Length String Handling.
@@ -1282,6 +1284,7 @@ consideration, the use of these pragmas should be minimized.
* Pragma Main_Storage::
* Pragma Max_Queue_Length::
* Pragma No_Body::
+* Pragma No_Caching::
* Pragma No_Component_Reordering::
* Pragma No_Elaboration_Code_All::
* Pragma No_Heap_Finalization::
@@ -5335,7 +5338,7 @@ individual protected entries and entry families. It accepts a single
positive integer as a parameter and must appear after the declaration
of an entry.
-@node Pragma No_Body,Pragma No_Component_Reordering,Pragma Max_Queue_Length,Implementation Defined Pragmas
+@node Pragma No_Body,Pragma No_Caching,Pragma Max_Queue_Length,Implementation Defined Pragmas
@anchor{gnat_rm/implementation_defined_pragmas pragma-no-body}@anchor{a0}
@section Pragma No_Body
@@ -5358,8 +5361,22 @@ such a way that a body needed before is no longer needed. The provision of a
dummy body with a No_Body pragma ensures that there is no interference from
earlier versions of the package body.
-@node Pragma No_Component_Reordering,Pragma No_Elaboration_Code_All,Pragma No_Body,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-no-component-reordering}@anchor{a1}
+@node Pragma No_Caching,Pragma No_Component_Reordering,Pragma No_Body,Implementation Defined Pragmas
+@anchor{gnat_rm/implementation_defined_pragmas pragma-no-caching}@anchor{a1}@anchor{gnat_rm/implementation_defined_pragmas id23}@anchor{a2}
+@section Pragma No_Caching
+
+
+Syntax:
+
+@example
+pragma No_Caching [ (boolean_EXPRESSION) ];
+@end example
+
+For the semantics of this pragma, see the entry for aspect @code{No_Caching} in
+the SPARK 2014 Reference Manual, section 7.1.2.
+
+@node Pragma No_Component_Reordering,Pragma No_Elaboration_Code_All,Pragma No_Caching,Implementation Defined Pragmas
+@anchor{gnat_rm/implementation_defined_pragmas pragma-no-component-reordering}@anchor{a3}
@section Pragma No_Component_Reordering
@@ -5378,7 +5395,7 @@ declared in units to which the pragma applies and there is a requirement
that this pragma be used consistently within a partition.
@node Pragma No_Elaboration_Code_All,Pragma No_Heap_Finalization,Pragma No_Component_Reordering,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas id23}@anchor{a2}@anchor{gnat_rm/implementation_defined_pragmas pragma-no-elaboration-code-all}@anchor{a3}
+@anchor{gnat_rm/implementation_defined_pragmas id24}@anchor{a4}@anchor{gnat_rm/implementation_defined_pragmas pragma-no-elaboration-code-all}@anchor{a5}
@section Pragma No_Elaboration_Code_All
@@ -5397,7 +5414,7 @@ current unit, it must also have the No_Elaboration_Code_All aspect set.
It may be applied to package or subprogram specs or their generic versions.
@node Pragma No_Heap_Finalization,Pragma No_Inline,Pragma No_Elaboration_Code_All,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-no-heap-finalization}@anchor{a4}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-no-heap-finalization}@anchor{a6}
@section Pragma No_Heap_Finalization
@@ -5429,7 +5446,7 @@ lose its @code{No_Heap_Finalization} pragma when the corresponding instance does
appear at the library level.
@node Pragma No_Inline,Pragma No_Return,Pragma No_Heap_Finalization,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas id24}@anchor{a5}@anchor{gnat_rm/implementation_defined_pragmas pragma-no-inline}@anchor{a6}
+@anchor{gnat_rm/implementation_defined_pragmas id25}@anchor{a7}@anchor{gnat_rm/implementation_defined_pragmas pragma-no-inline}@anchor{a8}
@section Pragma No_Inline
@@ -5447,7 +5464,7 @@ in particular it is not subject to the use of option @emph{-gnatn} or
pragma @code{Inline_Always} for the same @code{NAME}.
@node Pragma No_Return,Pragma No_Run_Time,Pragma No_Inline,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-no-return}@anchor{a7}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-no-return}@anchor{a9}
@section Pragma No_Return
@@ -5474,7 +5491,7 @@ available in all earlier versions of Ada as an implementation-defined
pragma.
@node Pragma No_Run_Time,Pragma No_Strict_Aliasing,Pragma No_Return,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-no-run-time}@anchor{a8}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-no-run-time}@anchor{aa}
@section Pragma No_Run_Time
@@ -5490,7 +5507,7 @@ internal testing. The pragma has been superseded by the reconfigurable
runtime capability of GNAT.
@node Pragma No_Strict_Aliasing,Pragma No_Tagged_Streams,Pragma No_Run_Time,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-no-strict-aliasing}@anchor{a9}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-no-strict-aliasing}@anchor{ab}
@section Pragma No_Strict_Aliasing
@@ -5512,7 +5529,7 @@ in the @cite{GNAT User's Guide}.
This pragma currently has no effects on access to unconstrained array types.
@node Pragma No_Tagged_Streams,Pragma Normalize_Scalars,Pragma No_Strict_Aliasing,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-no-tagged-streams}@anchor{aa}@anchor{gnat_rm/implementation_defined_pragmas id25}@anchor{ab}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-no-tagged-streams}@anchor{ac}@anchor{gnat_rm/implementation_defined_pragmas id26}@anchor{ad}
@section Pragma No_Tagged_Streams
@@ -5551,7 +5568,7 @@ with empty strings. This is useful to avoid exposing entity names at binary
level but has a negative impact on the debuggability of tagged types.
@node Pragma Normalize_Scalars,Pragma Obsolescent,Pragma No_Tagged_Streams,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-normalize-scalars}@anchor{ac}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-normalize-scalars}@anchor{ae}
@section Pragma Normalize_Scalars
@@ -5633,7 +5650,7 @@ will always generate an invalid value if one exists.
@end table
@node Pragma Obsolescent,Pragma Optimize_Alignment,Pragma Normalize_Scalars,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-obsolescent}@anchor{ad}@anchor{gnat_rm/implementation_defined_pragmas id26}@anchor{ae}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-obsolescent}@anchor{af}@anchor{gnat_rm/implementation_defined_pragmas id27}@anchor{b0}
@section Pragma Obsolescent
@@ -5729,7 +5746,7 @@ So if you specify @code{Entity =>} for the @code{Entity} argument, and a @code{M
argument is present, it must be preceded by @code{Message =>}.
@node Pragma Optimize_Alignment,Pragma Ordered,Pragma Obsolescent,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-optimize-alignment}@anchor{af}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-optimize-alignment}@anchor{b1}
@section Pragma Optimize_Alignment
@@ -5815,7 +5832,7 @@ latter are compiled by default in pragma Optimize_Alignment (Off) mode if no
pragma appears at the start of the file.
@node Pragma Ordered,Pragma Overflow_Mode,Pragma Optimize_Alignment,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-ordered}@anchor{b0}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-ordered}@anchor{b2}
@section Pragma Ordered
@@ -5907,7 +5924,7 @@ For additional information please refer to the description of the
@emph{-gnatw.u} switch in the GNAT User's Guide.
@node Pragma Overflow_Mode,Pragma Overriding_Renamings,Pragma Ordered,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-overflow-mode}@anchor{b1}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-overflow-mode}@anchor{b3}
@section Pragma Overflow_Mode
@@ -5946,7 +5963,7 @@ The pragma @code{Unsuppress (Overflow_Check)} unsuppresses (enables)
overflow checking, but does not affect the overflow mode.
@node Pragma Overriding_Renamings,Pragma Partition_Elaboration_Policy,Pragma Overflow_Mode,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-overriding-renamings}@anchor{b2}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-overriding-renamings}@anchor{b4}
@section Pragma Overriding_Renamings
@@ -5981,7 +5998,7 @@ RM 8.3 (15) stipulates that an overridden operation is not visible within the
declaration of the overriding operation.
@node Pragma Partition_Elaboration_Policy,Pragma Part_Of,Pragma Overriding_Renamings,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-partition-elaboration-policy}@anchor{b3}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-partition-elaboration-policy}@anchor{b5}
@section Pragma Partition_Elaboration_Policy
@@ -5998,7 +6015,7 @@ versions of Ada as an implementation-defined pragma.
See Ada 2012 Reference Manual for details.
@node Pragma Part_Of,Pragma Passive,Pragma Partition_Elaboration_Policy,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas id27}@anchor{b4}@anchor{gnat_rm/implementation_defined_pragmas pragma-part-of}@anchor{b5}
+@anchor{gnat_rm/implementation_defined_pragmas id28}@anchor{b6}@anchor{gnat_rm/implementation_defined_pragmas pragma-part-of}@anchor{b7}
@section Pragma Part_Of
@@ -6014,7 +6031,7 @@ For the semantics of this pragma, see the entry for aspect @code{Part_Of} in the
SPARK 2014 Reference Manual, section 7.2.6.
@node Pragma Passive,Pragma Persistent_BSS,Pragma Part_Of,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-passive}@anchor{b6}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-passive}@anchor{b8}
@section Pragma Passive
@@ -6038,7 +6055,7 @@ For more information on the subject of passive tasks, see the section
'Passive Task Optimization' in the GNAT Users Guide.
@node Pragma Persistent_BSS,Pragma Polling,Pragma Passive,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas id28}@anchor{b7}@anchor{gnat_rm/implementation_defined_pragmas pragma-persistent-bss}@anchor{b8}
+@anchor{gnat_rm/implementation_defined_pragmas id29}@anchor{b9}@anchor{gnat_rm/implementation_defined_pragmas pragma-persistent-bss}@anchor{ba}
@section Pragma Persistent_BSS
@@ -6069,7 +6086,7 @@ If this pragma is used on a target where this feature is not supported,
then the pragma will be ignored. See also @code{pragma Linker_Section}.
@node Pragma Polling,Pragma Post,Pragma Persistent_BSS,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-polling}@anchor{b9}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-polling}@anchor{bb}
@section Pragma Polling
@@ -6111,7 +6128,7 @@ Note that polling can also be enabled by use of the @emph{-gnatP} switch.
See the section on switches for gcc in the @cite{GNAT User's Guide}.
@node Pragma Post,Pragma Postcondition,Pragma Polling,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-post}@anchor{ba}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-post}@anchor{bc}
@section Pragma Post
@@ -6136,7 +6153,7 @@ appear at the start of the declarations in a subprogram body
(preceded only by other pragmas).
@node Pragma Postcondition,Pragma Post_Class,Pragma Post,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-postcondition}@anchor{bb}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-postcondition}@anchor{bd}
@section Pragma Postcondition
@@ -6301,7 +6318,7 @@ Ada 2012, and has been retained in its original form for
compatibility purposes.
@node Pragma Post_Class,Pragma Rename_Pragma,Pragma Postcondition,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-post-class}@anchor{bc}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-post-class}@anchor{be}
@section Pragma Post_Class
@@ -6336,7 +6353,7 @@ policy that controls this pragma is @code{Post'Class}, not
@code{Post_Class}.
@node Pragma Rename_Pragma,Pragma Pre,Pragma Post_Class,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-rename-pragma}@anchor{bd}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-rename-pragma}@anchor{bf}
@section Pragma Rename_Pragma
@@ -6375,7 +6392,7 @@ Pragma Inline_Only will not necessarily mean the same thing as the other Ada
compiler; it's up to you to make sure the semantics are close enough.
@node Pragma Pre,Pragma Precondition,Pragma Rename_Pragma,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-pre}@anchor{be}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-pre}@anchor{c0}
@section Pragma Pre
@@ -6400,7 +6417,7 @@ appear at the start of the declarations in a subprogram body
(preceded only by other pragmas).
@node Pragma Precondition,Pragma Predicate,Pragma Pre,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-precondition}@anchor{bf}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-precondition}@anchor{c1}
@section Pragma Precondition
@@ -6459,7 +6476,7 @@ Ada 2012, and has been retained in its original form for
compatibility purposes.
@node Pragma Predicate,Pragma Predicate_Failure,Pragma Precondition,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas id29}@anchor{c0}@anchor{gnat_rm/implementation_defined_pragmas pragma-predicate}@anchor{c1}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-predicate}@anchor{c2}@anchor{gnat_rm/implementation_defined_pragmas id30}@anchor{c3}
@section Pragma Predicate
@@ -6513,7 +6530,7 @@ defined for subtype B). When following this approach, the
use of predicates should be avoided.
@node Pragma Predicate_Failure,Pragma Preelaborable_Initialization,Pragma Predicate,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-predicate-failure}@anchor{c2}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-predicate-failure}@anchor{c4}
@section Pragma Predicate_Failure
@@ -6530,7 +6547,7 @@ the language-defined
@code{Predicate_Failure} aspect, and shares its restrictions and semantics.
@node Pragma Preelaborable_Initialization,Pragma Prefix_Exception_Messages,Pragma Predicate_Failure,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-preelaborable-initialization}@anchor{c3}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-preelaborable-initialization}@anchor{c5}
@section Pragma Preelaborable_Initialization
@@ -6545,7 +6562,7 @@ versions of Ada as an implementation-defined pragma.
See Ada 2012 Reference Manual for details.
@node Pragma Prefix_Exception_Messages,Pragma Pre_Class,Pragma Preelaborable_Initialization,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-prefix-exception-messages}@anchor{c4}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-prefix-exception-messages}@anchor{c6}
@section Pragma Prefix_Exception_Messages
@@ -6576,7 +6593,7 @@ prefixing in this case, you can always call
@code{GNAT.Source_Info.Enclosing_Entity} and prepend the string manually.
@node Pragma Pre_Class,Pragma Priority_Specific_Dispatching,Pragma Prefix_Exception_Messages,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-pre-class}@anchor{c5}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-pre-class}@anchor{c7}
@section Pragma Pre_Class
@@ -6611,7 +6628,7 @@ policy that controls this pragma is @code{Pre'Class}, not
@code{Pre_Class}.
@node Pragma Priority_Specific_Dispatching,Pragma Profile,Pragma Pre_Class,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-priority-specific-dispatching}@anchor{c6}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-priority-specific-dispatching}@anchor{c8}
@section Pragma Priority_Specific_Dispatching
@@ -6635,7 +6652,7 @@ versions of Ada as an implementation-defined pragma.
See Ada 2012 Reference Manual for details.
@node Pragma Profile,Pragma Profile_Warnings,Pragma Priority_Specific_Dispatching,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-profile}@anchor{c7}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-profile}@anchor{c9}
@section Pragma Profile
@@ -6909,7 +6926,7 @@ conforming Ada constructs. The profile enables the following three pragmas:
@end itemize
@node Pragma Profile_Warnings,Pragma Propagate_Exceptions,Pragma Profile,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-profile-warnings}@anchor{c8}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-profile-warnings}@anchor{ca}
@section Pragma Profile_Warnings
@@ -6927,7 +6944,7 @@ violations of the profile generate warning messages instead
of error messages.
@node Pragma Propagate_Exceptions,Pragma Provide_Shift_Operators,Pragma Profile_Warnings,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-propagate-exceptions}@anchor{c9}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-propagate-exceptions}@anchor{cb}
@section Pragma Propagate_Exceptions
@@ -6946,7 +6963,7 @@ purposes. It used to be used in connection with optimization of
a now-obsolete mechanism for implementation of exceptions.
@node Pragma Provide_Shift_Operators,Pragma Psect_Object,Pragma Propagate_Exceptions,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-provide-shift-operators}@anchor{ca}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-provide-shift-operators}@anchor{cc}
@section Pragma Provide_Shift_Operators
@@ -6966,7 +6983,7 @@ including the function declarations for these five operators, together
with the pragma Import (Intrinsic, ...) statements.
@node Pragma Psect_Object,Pragma Pure_Function,Pragma Provide_Shift_Operators,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-psect-object}@anchor{cb}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-psect-object}@anchor{cd}
@section Pragma Psect_Object
@@ -6986,7 +7003,7 @@ EXTERNAL_SYMBOL ::=
This pragma is identical in effect to pragma @code{Common_Object}.
@node Pragma Pure_Function,Pragma Rational,Pragma Psect_Object,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-pure-function}@anchor{cc}@anchor{gnat_rm/implementation_defined_pragmas id30}@anchor{cd}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-pure-function}@anchor{ce}@anchor{gnat_rm/implementation_defined_pragmas id31}@anchor{cf}
@section Pragma Pure_Function
@@ -7048,7 +7065,7 @@ unit is not a Pure unit in the categorization sense. So for example, a function
thus marked is free to @code{with} non-pure units.
@node Pragma Rational,Pragma Ravenscar,Pragma Pure_Function,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-rational}@anchor{ce}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-rational}@anchor{d0}
@section Pragma Rational
@@ -7066,7 +7083,7 @@ pragma Profile (Rational);
@end example
@node Pragma Ravenscar,Pragma Refined_Depends,Pragma Rational,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-ravenscar}@anchor{cf}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-ravenscar}@anchor{d1}
@section Pragma Ravenscar
@@ -7086,7 +7103,7 @@ pragma Profile (Ravenscar);
which is the preferred method of setting the @code{Ravenscar} profile.
@node Pragma Refined_Depends,Pragma Refined_Global,Pragma Ravenscar,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-depends}@anchor{d0}@anchor{gnat_rm/implementation_defined_pragmas id31}@anchor{d1}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-depends}@anchor{d2}@anchor{gnat_rm/implementation_defined_pragmas id32}@anchor{d3}
@section Pragma Refined_Depends
@@ -7119,7 +7136,7 @@ For the semantics of this pragma, see the entry for aspect @code{Refined_Depends
the SPARK 2014 Reference Manual, section 6.1.5.
@node Pragma Refined_Global,Pragma Refined_Post,Pragma Refined_Depends,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-global}@anchor{d2}@anchor{gnat_rm/implementation_defined_pragmas id32}@anchor{d3}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-global}@anchor{d4}@anchor{gnat_rm/implementation_defined_pragmas id33}@anchor{d5}
@section Pragma Refined_Global
@@ -7144,7 +7161,7 @@ For the semantics of this pragma, see the entry for aspect @code{Refined_Global}
the SPARK 2014 Reference Manual, section 6.1.4.
@node Pragma Refined_Post,Pragma Refined_State,Pragma Refined_Global,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-post}@anchor{d4}@anchor{gnat_rm/implementation_defined_pragmas id33}@anchor{d5}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-post}@anchor{d6}@anchor{gnat_rm/implementation_defined_pragmas id34}@anchor{d7}
@section Pragma Refined_Post
@@ -7158,7 +7175,7 @@ For the semantics of this pragma, see the entry for aspect @code{Refined_Post} i
the SPARK 2014 Reference Manual, section 7.2.7.
@node Pragma Refined_State,Pragma Relative_Deadline,Pragma Refined_Post,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-state}@anchor{d6}@anchor{gnat_rm/implementation_defined_pragmas id34}@anchor{d7}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-refined-state}@anchor{d8}@anchor{gnat_rm/implementation_defined_pragmas id35}@anchor{d9}
@section Pragma Refined_State
@@ -7184,7 +7201,7 @@ For the semantics of this pragma, see the entry for aspect @code{Refined_State}
the SPARK 2014 Reference Manual, section 7.2.2.
@node Pragma Relative_Deadline,Pragma Remote_Access_Type,Pragma Refined_State,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-relative-deadline}@anchor{d8}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-relative-deadline}@anchor{da}
@section Pragma Relative_Deadline
@@ -7199,7 +7216,7 @@ versions of Ada as an implementation-defined pragma.
See Ada 2012 Reference Manual for details.
@node Pragma Remote_Access_Type,Pragma Restricted_Run_Time,Pragma Relative_Deadline,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas id35}@anchor{d9}@anchor{gnat_rm/implementation_defined_pragmas pragma-remote-access-type}@anchor{da}
+@anchor{gnat_rm/implementation_defined_pragmas id36}@anchor{db}@anchor{gnat_rm/implementation_defined_pragmas pragma-remote-access-type}@anchor{dc}
@section Pragma Remote_Access_Type
@@ -7225,7 +7242,7 @@ pertaining to remote access to class-wide types. At instantiation, the
actual type must be a remote access to class-wide type.
@node Pragma Restricted_Run_Time,Pragma Restriction_Warnings,Pragma Remote_Access_Type,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-restricted-run-time}@anchor{db}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-restricted-run-time}@anchor{dd}
@section Pragma Restricted_Run_Time
@@ -7246,7 +7263,7 @@ which is the preferred method of setting the restricted run time
profile.
@node Pragma Restriction_Warnings,Pragma Reviewable,Pragma Restricted_Run_Time,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-restriction-warnings}@anchor{dc}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-restriction-warnings}@anchor{de}
@section Pragma Restriction_Warnings
@@ -7284,7 +7301,7 @@ generating a warning, but any other use of implementation
defined pragmas will cause a warning to be generated.
@node Pragma Reviewable,Pragma Secondary_Stack_Size,Pragma Restriction_Warnings,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-reviewable}@anchor{dd}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-reviewable}@anchor{df}
@section Pragma Reviewable
@@ -7388,7 +7405,7 @@ comprehensive messages identifying possible problems based on this
information.
@node Pragma Secondary_Stack_Size,Pragma Share_Generic,Pragma Reviewable,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas id36}@anchor{de}@anchor{gnat_rm/implementation_defined_pragmas pragma-secondary-stack-size}@anchor{df}
+@anchor{gnat_rm/implementation_defined_pragmas id37}@anchor{e0}@anchor{gnat_rm/implementation_defined_pragmas pragma-secondary-stack-size}@anchor{e1}
@section Pragma Secondary_Stack_Size
@@ -7424,7 +7441,7 @@ Note the pragma cannot appear when the restriction @code{No_Secondary_Stack}
is in effect.
@node Pragma Share_Generic,Pragma Shared,Pragma Secondary_Stack_Size,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-share-generic}@anchor{e0}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-share-generic}@anchor{e2}
@section Pragma Share_Generic
@@ -7442,7 +7459,7 @@ than to check that the given names are all names of generic units or
generic instances.
@node Pragma Shared,Pragma Short_Circuit_And_Or,Pragma Share_Generic,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas id37}@anchor{e1}@anchor{gnat_rm/implementation_defined_pragmas pragma-shared}@anchor{e2}
+@anchor{gnat_rm/implementation_defined_pragmas id38}@anchor{e3}@anchor{gnat_rm/implementation_defined_pragmas pragma-shared}@anchor{e4}
@section Pragma Shared
@@ -7450,7 +7467,7 @@ This pragma is provided for compatibility with Ada 83. The syntax and
semantics are identical to pragma Atomic.
@node Pragma Short_Circuit_And_Or,Pragma Short_Descriptors,Pragma Shared,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-short-circuit-and-or}@anchor{e3}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-short-circuit-and-or}@anchor{e5}
@section Pragma Short_Circuit_And_Or
@@ -7469,7 +7486,7 @@ within the file being compiled, it applies only to the file being compiled.
There is no requirement that all units in a partition use this option.
@node Pragma Short_Descriptors,Pragma Simple_Storage_Pool_Type,Pragma Short_Circuit_And_Or,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-short-descriptors}@anchor{e4}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-short-descriptors}@anchor{e6}
@section Pragma Short_Descriptors
@@ -7483,7 +7500,7 @@ This pragma is provided for compatibility with other Ada implementations. It
is recognized but ignored by all current versions of GNAT.
@node Pragma Simple_Storage_Pool_Type,Pragma Source_File_Name,Pragma Short_Descriptors,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-simple-storage-pool-type}@anchor{e5}@anchor{gnat_rm/implementation_defined_pragmas id38}@anchor{e6}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-simple-storage-pool-type}@anchor{e7}@anchor{gnat_rm/implementation_defined_pragmas id39}@anchor{e8}
@section Pragma Simple_Storage_Pool_Type
@@ -7537,7 +7554,7 @@ storage-management discipline).
An object of a simple storage pool type can be associated with an access
type by specifying the attribute
-@ref{e7,,Simple_Storage_Pool}. For example:
+@ref{e9,,Simple_Storage_Pool}. For example:
@example
My_Pool : My_Simple_Storage_Pool_Type;
@@ -7547,11 +7564,11 @@ type Acc is access My_Data_Type;
for Acc'Simple_Storage_Pool use My_Pool;
@end example
-See attribute @ref{e7,,Simple_Storage_Pool}
+See attribute @ref{e9,,Simple_Storage_Pool}
for further details.
@node Pragma Source_File_Name,Pragma Source_File_Name_Project,Pragma Simple_Storage_Pool_Type,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name}@anchor{e8}@anchor{gnat_rm/implementation_defined_pragmas id39}@anchor{e9}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name}@anchor{ea}@anchor{gnat_rm/implementation_defined_pragmas id40}@anchor{eb}
@section Pragma Source_File_Name
@@ -7643,19 +7660,19 @@ aware of these pragmas, and so other tools that use the projet file would not
be aware of the intended naming conventions. If you are using project files,
file naming is controlled by Source_File_Name_Project pragmas, which are
usually supplied automatically by the project manager. A pragma
-Source_File_Name cannot appear after a @ref{ea,,Pragma Source_File_Name_Project}.
+Source_File_Name cannot appear after a @ref{ec,,Pragma Source_File_Name_Project}.
For more details on the use of the @code{Source_File_Name} pragma, see the
sections on @code{Using Other File Names} and @cite{Alternative File Naming Schemes' in the :title:`GNAT User's Guide}.
@node Pragma Source_File_Name_Project,Pragma Source_Reference,Pragma Source_File_Name,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name-project}@anchor{ea}@anchor{gnat_rm/implementation_defined_pragmas id40}@anchor{eb}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-source-file-name-project}@anchor{ec}@anchor{gnat_rm/implementation_defined_pragmas id41}@anchor{ed}
@section Pragma Source_File_Name_Project
This pragma has the same syntax and semantics as pragma Source_File_Name.
It is only allowed as a stand-alone configuration pragma.
-It cannot appear after a @ref{e8,,Pragma Source_File_Name}, and
+It cannot appear after a @ref{ea,,Pragma Source_File_Name}, and
most importantly, once pragma Source_File_Name_Project appears,
no further Source_File_Name pragmas are allowed.
@@ -7667,7 +7684,7 @@ Source_File_Name or Source_File_Name_Project pragmas (which would not be
known to the project manager).
@node Pragma Source_Reference,Pragma SPARK_Mode,Pragma Source_File_Name_Project,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-source-reference}@anchor{ec}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-source-reference}@anchor{ee}
@section Pragma Source_Reference
@@ -7691,7 +7708,7 @@ string expression other than a string literal. This is because its value
is needed for error messages issued by all phases of the compiler.
@node Pragma SPARK_Mode,Pragma Static_Elaboration_Desired,Pragma Source_Reference,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-spark-mode}@anchor{ed}@anchor{gnat_rm/implementation_defined_pragmas id41}@anchor{ee}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-spark-mode}@anchor{ef}@anchor{gnat_rm/implementation_defined_pragmas id42}@anchor{f0}
@section Pragma SPARK_Mode
@@ -7773,7 +7790,7 @@ SPARK_Mode (@code{Off}), then that pragma will need to be repeated in
the package body.
@node Pragma Static_Elaboration_Desired,Pragma Stream_Convert,Pragma SPARK_Mode,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-static-elaboration-desired}@anchor{ef}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-static-elaboration-desired}@anchor{f1}
@section Pragma Static_Elaboration_Desired
@@ -7797,7 +7814,7 @@ construction of larger aggregates with static components that include an others
choice.)
@node Pragma Stream_Convert,Pragma Style_Checks,Pragma Static_Elaboration_Desired,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-stream-convert}@anchor{f0}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-stream-convert}@anchor{f2}
@section Pragma Stream_Convert
@@ -7874,7 +7891,7 @@ the pragma is silently ignored, and the default implementation of the stream
attributes is used instead.
@node Pragma Style_Checks,Pragma Subtitle,Pragma Stream_Convert,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-style-checks}@anchor{f1}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-style-checks}@anchor{f3}
@section Pragma Style_Checks
@@ -7947,7 +7964,7 @@ Rf2 : Integer := ARG; -- OK, no error
@end example
@node Pragma Subtitle,Pragma Suppress,Pragma Style_Checks,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-subtitle}@anchor{f2}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-subtitle}@anchor{f4}
@section Pragma Subtitle
@@ -7961,7 +7978,7 @@ This pragma is recognized for compatibility with other Ada compilers
but is ignored by GNAT.
@node Pragma Suppress,Pragma Suppress_All,Pragma Subtitle,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress}@anchor{f3}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress}@anchor{f5}
@section Pragma Suppress
@@ -8034,7 +8051,7 @@ Of course, run-time checks are omitted whenever the compiler can prove
that they will not fail, whether or not checks are suppressed.
@node Pragma Suppress_All,Pragma Suppress_Debug_Info,Pragma Suppress,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-all}@anchor{f4}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-all}@anchor{f6}
@section Pragma Suppress_All
@@ -8053,7 +8070,7 @@ The use of the standard Ada pragma @code{Suppress (All_Checks)}
as a normal configuration pragma is the preferred usage in GNAT.
@node Pragma Suppress_Debug_Info,Pragma Suppress_Exception_Locations,Pragma Suppress_All,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-debug-info}@anchor{f5}@anchor{gnat_rm/implementation_defined_pragmas id42}@anchor{f6}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-debug-info}@anchor{f7}@anchor{gnat_rm/implementation_defined_pragmas id43}@anchor{f8}
@section Pragma Suppress_Debug_Info
@@ -8068,7 +8085,7 @@ for the specified entity. It is intended primarily for use in debugging
the debugger, and navigating around debugger problems.
@node Pragma Suppress_Exception_Locations,Pragma Suppress_Initialization,Pragma Suppress_Debug_Info,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-exception-locations}@anchor{f7}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-exception-locations}@anchor{f9}
@section Pragma Suppress_Exception_Locations
@@ -8091,7 +8108,7 @@ a partition, so it is fine to have some units within a partition compiled
with this pragma and others compiled in normal mode without it.
@node Pragma Suppress_Initialization,Pragma Task_Name,Pragma Suppress_Exception_Locations,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas id43}@anchor{f8}@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-initialization}@anchor{f9}
+@anchor{gnat_rm/implementation_defined_pragmas id44}@anchor{fa}@anchor{gnat_rm/implementation_defined_pragmas pragma-suppress-initialization}@anchor{fb}
@section Pragma Suppress_Initialization
@@ -8136,7 +8153,7 @@ is suppressed, just as though its subtype had been given in a pragma
Suppress_Initialization, as described above.
@node Pragma Task_Name,Pragma Task_Storage,Pragma Suppress_Initialization,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-task-name}@anchor{fa}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-task-name}@anchor{fc}
@section Pragma Task_Name
@@ -8192,7 +8209,7 @@ end;
@end example
@node Pragma Task_Storage,Pragma Test_Case,Pragma Task_Name,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-task-storage}@anchor{fb}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-task-storage}@anchor{fd}
@section Pragma Task_Storage
@@ -8212,7 +8229,7 @@ created, depending on the target. This pragma can appear anywhere a
type.
@node Pragma Test_Case,Pragma Thread_Local_Storage,Pragma Task_Storage,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-test-case}@anchor{fc}@anchor{gnat_rm/implementation_defined_pragmas id44}@anchor{fd}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-test-case}@anchor{fe}@anchor{gnat_rm/implementation_defined_pragmas id45}@anchor{ff}
@section Pragma Test_Case
@@ -8268,7 +8285,7 @@ postcondition. Mode @code{Robustness} indicates that the precondition and
postcondition of the subprogram should be ignored for this test case.
@node Pragma Thread_Local_Storage,Pragma Time_Slice,Pragma Test_Case,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-thread-local-storage}@anchor{fe}@anchor{gnat_rm/implementation_defined_pragmas id45}@anchor{ff}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-thread-local-storage}@anchor{100}@anchor{gnat_rm/implementation_defined_pragmas id46}@anchor{101}
@section Pragma Thread_Local_Storage
@@ -8306,7 +8323,7 @@ If this pragma is used on a system where @code{TLS} is not supported,
then an error message will be generated and the program will be rejected.
@node Pragma Time_Slice,Pragma Title,Pragma Thread_Local_Storage,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-time-slice}@anchor{100}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-time-slice}@anchor{102}
@section Pragma Time_Slice
@@ -8322,7 +8339,7 @@ It is ignored if it is used in a system that does not allow this control,
or if it appears in other than the main program unit.
@node Pragma Title,Pragma Type_Invariant,Pragma Time_Slice,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-title}@anchor{101}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-title}@anchor{103}
@section Pragma Title
@@ -8347,7 +8364,7 @@ notation is used, and named and positional notation can be mixed
following the normal rules for procedure calls in Ada.
@node Pragma Type_Invariant,Pragma Type_Invariant_Class,Pragma Title,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-type-invariant}@anchor{102}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-type-invariant}@anchor{104}
@section Pragma Type_Invariant
@@ -8368,7 +8385,7 @@ controlled by the assertion identifier @code{Type_Invariant}
rather than @code{Invariant}.
@node Pragma Type_Invariant_Class,Pragma Unchecked_Union,Pragma Type_Invariant,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas id46}@anchor{103}@anchor{gnat_rm/implementation_defined_pragmas pragma-type-invariant-class}@anchor{104}
+@anchor{gnat_rm/implementation_defined_pragmas id47}@anchor{105}@anchor{gnat_rm/implementation_defined_pragmas pragma-type-invariant-class}@anchor{106}
@section Pragma Type_Invariant_Class
@@ -8395,7 +8412,7 @@ policy that controls this pragma is @code{Type_Invariant'Class},
not @code{Type_Invariant_Class}.
@node Pragma Unchecked_Union,Pragma Unevaluated_Use_Of_Old,Pragma Type_Invariant_Class,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-unchecked-union}@anchor{105}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-unchecked-union}@anchor{107}
@section Pragma Unchecked_Union
@@ -8415,7 +8432,7 @@ version in all language modes (Ada 83, Ada 95, and Ada 2005). For full
details, consult the Ada 2012 Reference Manual, section B.3.3.
@node Pragma Unevaluated_Use_Of_Old,Pragma Unimplemented_Unit,Pragma Unchecked_Union,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-unevaluated-use-of-old}@anchor{106}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-unevaluated-use-of-old}@anchor{108}
@section Pragma Unevaluated_Use_Of_Old
@@ -8470,7 +8487,7 @@ uses up to the end of the corresponding statement sequence or
sequence of package declarations.
@node Pragma Unimplemented_Unit,Pragma Universal_Aliasing,Pragma Unevaluated_Use_Of_Old,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-unimplemented-unit}@anchor{107}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-unimplemented-unit}@anchor{109}
@section Pragma Unimplemented_Unit
@@ -8490,7 +8507,7 @@ The abort only happens if code is being generated. Thus you can use
specs of unimplemented packages in syntax or semantic checking mode.
@node Pragma Universal_Aliasing,Pragma Universal_Data,Pragma Unimplemented_Unit,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas id47}@anchor{108}@anchor{gnat_rm/implementation_defined_pragmas pragma-universal-aliasing}@anchor{109}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-universal-aliasing}@anchor{10a}@anchor{gnat_rm/implementation_defined_pragmas id48}@anchor{10b}
@section Pragma Universal_Aliasing
@@ -8509,7 +8526,7 @@ situations in which it must be suppressed, see the section on
@code{Optimization and Strict Aliasing} in the @cite{GNAT User's Guide}.
@node Pragma Universal_Data,Pragma Unmodified,Pragma Universal_Aliasing,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-universal-data}@anchor{10a}@anchor{gnat_rm/implementation_defined_pragmas id48}@anchor{10b}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-universal-data}@anchor{10c}@anchor{gnat_rm/implementation_defined_pragmas id49}@anchor{10d}
@section Pragma Universal_Data
@@ -8533,7 +8550,7 @@ of this pragma is also available by applying the -univ switch on the
compilations of units where universal addressing of the data is desired.
@node Pragma Unmodified,Pragma Unreferenced,Pragma Universal_Data,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-unmodified}@anchor{10c}@anchor{gnat_rm/implementation_defined_pragmas id49}@anchor{10d}
+@anchor{gnat_rm/implementation_defined_pragmas id50}@anchor{10e}@anchor{gnat_rm/implementation_defined_pragmas pragma-unmodified}@anchor{10f}
@section Pragma Unmodified
@@ -8567,7 +8584,7 @@ Thus it is never necessary to use @code{pragma Unmodified} for such
variables, though it is harmless to do so.
@node Pragma Unreferenced,Pragma Unreferenced_Objects,Pragma Unmodified,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced}@anchor{10e}@anchor{gnat_rm/implementation_defined_pragmas id50}@anchor{10f}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced}@anchor{110}@anchor{gnat_rm/implementation_defined_pragmas id51}@anchor{111}
@section Pragma Unreferenced
@@ -8611,7 +8628,7 @@ Note that if a warning is desired for all calls to a given subprogram,
regardless of whether they occur in the same unit as the subprogram
declaration, then this pragma should not be used (calls from another
unit would not be flagged); pragma Obsolescent can be used instead
-for this purpose, see @ref{ad,,Pragma Obsolescent}.
+for this purpose, see @ref{af,,Pragma Obsolescent}.
The second form of pragma @code{Unreferenced} is used within a context
clause. In this case the arguments must be unit names of units previously
@@ -8627,7 +8644,7 @@ Thus it is never necessary to use @code{pragma Unreferenced} for such
variables, though it is harmless to do so.
@node Pragma Unreferenced_Objects,Pragma Unreserve_All_Interrupts,Pragma Unreferenced,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced-objects}@anchor{110}@anchor{gnat_rm/implementation_defined_pragmas id51}@anchor{111}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-unreferenced-objects}@anchor{112}@anchor{gnat_rm/implementation_defined_pragmas id52}@anchor{113}
@section Pragma Unreferenced_Objects
@@ -8652,7 +8669,7 @@ compiler will automatically suppress unwanted warnings about these variables
not being referenced.
@node Pragma Unreserve_All_Interrupts,Pragma Unsuppress,Pragma Unreferenced_Objects,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-unreserve-all-interrupts}@anchor{112}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-unreserve-all-interrupts}@anchor{114}
@section Pragma Unreserve_All_Interrupts
@@ -8688,7 +8705,7 @@ handled, see pragma @code{Interrupt_State}, which subsumes the functionality
of the @code{Unreserve_All_Interrupts} pragma.
@node Pragma Unsuppress,Pragma Use_VADS_Size,Pragma Unreserve_All_Interrupts,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-unsuppress}@anchor{113}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-unsuppress}@anchor{115}
@section Pragma Unsuppress
@@ -8724,7 +8741,7 @@ number of implementation-defined check names. See the description of pragma
@code{Suppress} for full details.
@node Pragma Use_VADS_Size,Pragma Unused,Pragma Unsuppress,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-use-vads-size}@anchor{114}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-use-vads-size}@anchor{116}
@section Pragma Use_VADS_Size
@@ -8748,7 +8765,7 @@ as implemented in the VADS compiler. See description of the VADS_Size
attribute for further details.
@node Pragma Unused,Pragma Validity_Checks,Pragma Use_VADS_Size,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-unused}@anchor{115}@anchor{gnat_rm/implementation_defined_pragmas id52}@anchor{116}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-unused}@anchor{117}@anchor{gnat_rm/implementation_defined_pragmas id53}@anchor{118}
@section Pragma Unused
@@ -8782,7 +8799,7 @@ Thus it is never necessary to use @code{pragma Unmodified} for such
variables, though it is harmless to do so.
@node Pragma Validity_Checks,Pragma Volatile,Pragma Unused,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-validity-checks}@anchor{117}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-validity-checks}@anchor{119}
@section Pragma Validity_Checks
@@ -8838,7 +8855,7 @@ A := C; -- C will be validity checked
@end example
@node Pragma Volatile,Pragma Volatile_Full_Access,Pragma Validity_Checks,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile}@anchor{118}
+@anchor{gnat_rm/implementation_defined_pragmas id54}@anchor{11a}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile}@anchor{11b}
@section Pragma Volatile
@@ -8856,7 +8873,7 @@ implementation of pragma Volatile is upwards compatible with the
implementation in DEC Ada 83.
@node Pragma Volatile_Full_Access,Pragma Volatile_Function,Pragma Volatile,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile-full-access}@anchor{119}@anchor{gnat_rm/implementation_defined_pragmas id53}@anchor{11a}
+@anchor{gnat_rm/implementation_defined_pragmas id55}@anchor{11c}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile-full-access}@anchor{11d}
@section Pragma Volatile_Full_Access
@@ -8888,7 +8905,7 @@ It is not permissible to specify @code{Volatile_Full_Access} for a composite
(record or array) type or object that has at least one @code{Aliased} component.
@node Pragma Volatile_Function,Pragma Warning_As_Error,Pragma Volatile_Full_Access,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas id54}@anchor{11b}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile-function}@anchor{11c}
+@anchor{gnat_rm/implementation_defined_pragmas id56}@anchor{11e}@anchor{gnat_rm/implementation_defined_pragmas pragma-volatile-function}@anchor{11f}
@section Pragma Volatile_Function
@@ -8902,7 +8919,7 @@ For the semantics of this pragma, see the entry for aspect @code{Volatile_Functi
in the SPARK 2014 Reference Manual, section 7.1.2.
@node Pragma Warning_As_Error,Pragma Warnings,Pragma Volatile_Function,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-warning-as-error}@anchor{11d}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-warning-as-error}@anchor{120}
@section Pragma Warning_As_Error
@@ -8937,7 +8954,7 @@ as shown in the example below, to treat a class of warnings as errors.
The above use of patterns to match the message applies only to warning
messages generated by the front end. This pragma can also be applied to
-warnings provided by the back end and mentioned in @ref{11e,,Pragma Warnings}.
+warnings provided by the back end and mentioned in @ref{121,,Pragma Warnings}.
By using a single full @emph{-Wxxx} switch in the pragma, such warnings
can also be treated as errors.
@@ -8987,7 +9004,7 @@ the tag is changed from "warning:" to "error:" and the string
"[warning-as-error]" is appended to the end of the message.
@node Pragma Warnings,Pragma Weak_External,Pragma Warning_As_Error,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas id55}@anchor{11f}@anchor{gnat_rm/implementation_defined_pragmas pragma-warnings}@anchor{11e}
+@anchor{gnat_rm/implementation_defined_pragmas id57}@anchor{122}@anchor{gnat_rm/implementation_defined_pragmas pragma-warnings}@anchor{121}
@section Pragma Warnings
@@ -9143,7 +9160,7 @@ selectively for each tool, and as a consequence to detect useless pragma
Warnings with switch @code{-gnatw.w}.
@node Pragma Weak_External,Pragma Wide_Character_Encoding,Pragma Warnings,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-weak-external}@anchor{120}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-weak-external}@anchor{123}
@section Pragma Weak_External
@@ -9194,7 +9211,7 @@ end External_Module;
@end example
@node Pragma Wide_Character_Encoding,,Pragma Weak_External,Implementation Defined Pragmas
-@anchor{gnat_rm/implementation_defined_pragmas pragma-wide-character-encoding}@anchor{121}
+@anchor{gnat_rm/implementation_defined_pragmas pragma-wide-character-encoding}@anchor{124}
@section Pragma Wide_Character_Encoding
@@ -9225,7 +9242,7 @@ encoding within that file, and does not affect withed units, specs,
or subunits.
@node Implementation Defined Aspects,Implementation Defined Attributes,Implementation Defined Pragmas,Top
-@anchor{gnat_rm/implementation_defined_aspects implementation-defined-aspects}@anchor{122}@anchor{gnat_rm/implementation_defined_aspects doc}@anchor{123}@anchor{gnat_rm/implementation_defined_aspects id1}@anchor{124}
+@anchor{gnat_rm/implementation_defined_aspects implementation-defined-aspects}@anchor{125}@anchor{gnat_rm/implementation_defined_aspects doc}@anchor{126}@anchor{gnat_rm/implementation_defined_aspects id1}@anchor{127}
@chapter Implementation Defined Aspects
@@ -9306,6 +9323,7 @@ or attribute definition clause.
* Aspect Linker_Section::
* Aspect Lock_Free::
* Aspect Max_Queue_Length::
+* Aspect No_Caching::
* Aspect No_Elaboration_Code_All::
* Aspect No_Inline::
* Aspect No_Tagged_Streams::
@@ -9343,7 +9361,7 @@ or attribute definition clause.
@end menu
@node Aspect Abstract_State,Aspect Annotate,,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-abstract-state}@anchor{125}
+@anchor{gnat_rm/implementation_defined_aspects aspect-abstract-state}@anchor{128}
@section Aspect Abstract_State
@@ -9352,7 +9370,7 @@ or attribute definition clause.
This aspect is equivalent to @ref{1c,,pragma Abstract_State}.
@node Aspect Annotate,Aspect Async_Readers,Aspect Abstract_State,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-annotate}@anchor{126}
+@anchor{gnat_rm/implementation_defined_aspects aspect-annotate}@anchor{129}
@section Aspect Annotate
@@ -9379,7 +9397,7 @@ Equivalent to @code{pragma Annotate (ID, ID @{, ARG@}, Entity => Name);}
@end table
@node Aspect Async_Readers,Aspect Async_Writers,Aspect Annotate,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-async-readers}@anchor{127}
+@anchor{gnat_rm/implementation_defined_aspects aspect-async-readers}@anchor{12a}
@section Aspect Async_Readers
@@ -9388,7 +9406,7 @@ Equivalent to @code{pragma Annotate (ID, ID @{, ARG@}, Entity => Name);}
This boolean aspect is equivalent to @ref{30,,pragma Async_Readers}.
@node Aspect Async_Writers,Aspect Constant_After_Elaboration,Aspect Async_Readers,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-async-writers}@anchor{128}
+@anchor{gnat_rm/implementation_defined_aspects aspect-async-writers}@anchor{12b}
@section Aspect Async_Writers
@@ -9397,7 +9415,7 @@ This boolean aspect is equivalent to @ref{30,,pragma Async_Readers}.
This boolean aspect is equivalent to @ref{33,,pragma Async_Writers}.
@node Aspect Constant_After_Elaboration,Aspect Contract_Cases,Aspect Async_Writers,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-constant-after-elaboration}@anchor{129}
+@anchor{gnat_rm/implementation_defined_aspects aspect-constant-after-elaboration}@anchor{12c}
@section Aspect Constant_After_Elaboration
@@ -9406,7 +9424,7 @@ This boolean aspect is equivalent to @ref{33,,pragma Async_Writers}.
This aspect is equivalent to @ref{44,,pragma Constant_After_Elaboration}.
@node Aspect Contract_Cases,Aspect Depends,Aspect Constant_After_Elaboration,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-contract-cases}@anchor{12a}
+@anchor{gnat_rm/implementation_defined_aspects aspect-contract-cases}@anchor{12d}
@section Aspect Contract_Cases
@@ -9417,7 +9435,7 @@ of clauses being enclosed in parentheses so that syntactically it is an
aggregate.
@node Aspect Depends,Aspect Default_Initial_Condition,Aspect Contract_Cases,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-depends}@anchor{12b}
+@anchor{gnat_rm/implementation_defined_aspects aspect-depends}@anchor{12e}
@section Aspect Depends
@@ -9426,7 +9444,7 @@ aggregate.
This aspect is equivalent to @ref{55,,pragma Depends}.
@node Aspect Default_Initial_Condition,Aspect Dimension,Aspect Depends,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-default-initial-condition}@anchor{12c}
+@anchor{gnat_rm/implementation_defined_aspects aspect-default-initial-condition}@anchor{12f}
@section Aspect Default_Initial_Condition
@@ -9435,7 +9453,7 @@ This aspect is equivalent to @ref{55,,pragma Depends}.
This aspect is equivalent to @ref{50,,pragma Default_Initial_Condition}.
@node Aspect Dimension,Aspect Dimension_System,Aspect Default_Initial_Condition,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-dimension}@anchor{12d}
+@anchor{gnat_rm/implementation_defined_aspects aspect-dimension}@anchor{130}
@section Aspect Dimension
@@ -9471,7 +9489,7 @@ Note that when the dimensioned type is an integer type, then any
dimension value must be an integer literal.
@node Aspect Dimension_System,Aspect Disable_Controlled,Aspect Dimension,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-dimension-system}@anchor{12e}
+@anchor{gnat_rm/implementation_defined_aspects aspect-dimension-system}@anchor{131}
@section Aspect Dimension_System
@@ -9531,7 +9549,7 @@ See section 'Performing Dimensionality Analysis in GNAT' in the GNAT Users
Guide for detailed examples of use of the dimension system.
@node Aspect Disable_Controlled,Aspect Effective_Reads,Aspect Dimension_System,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-disable-controlled}@anchor{12f}
+@anchor{gnat_rm/implementation_defined_aspects aspect-disable-controlled}@anchor{132}
@section Aspect Disable_Controlled
@@ -9544,7 +9562,7 @@ where for example you might want a record to be controlled or not depending on
whether some run-time check is enabled or suppressed.
@node Aspect Effective_Reads,Aspect Effective_Writes,Aspect Disable_Controlled,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-effective-reads}@anchor{130}
+@anchor{gnat_rm/implementation_defined_aspects aspect-effective-reads}@anchor{133}
@section Aspect Effective_Reads
@@ -9553,7 +9571,7 @@ whether some run-time check is enabled or suppressed.
This aspect is equivalent to @ref{5b,,pragma Effective_Reads}.
@node Aspect Effective_Writes,Aspect Extensions_Visible,Aspect Effective_Reads,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-effective-writes}@anchor{131}
+@anchor{gnat_rm/implementation_defined_aspects aspect-effective-writes}@anchor{134}
@section Aspect Effective_Writes
@@ -9562,7 +9580,7 @@ This aspect is equivalent to @ref{5b,,pragma Effective_Reads}.
This aspect is equivalent to @ref{5d,,pragma Effective_Writes}.
@node Aspect Extensions_Visible,Aspect Favor_Top_Level,Aspect Effective_Writes,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-extensions-visible}@anchor{132}
+@anchor{gnat_rm/implementation_defined_aspects aspect-extensions-visible}@anchor{135}
@section Aspect Extensions_Visible
@@ -9571,7 +9589,7 @@ This aspect is equivalent to @ref{5d,,pragma Effective_Writes}.
This aspect is equivalent to @ref{69,,pragma Extensions_Visible}.
@node Aspect Favor_Top_Level,Aspect Ghost,Aspect Extensions_Visible,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-favor-top-level}@anchor{133}
+@anchor{gnat_rm/implementation_defined_aspects aspect-favor-top-level}@anchor{136}
@section Aspect Favor_Top_Level
@@ -9580,7 +9598,7 @@ This aspect is equivalent to @ref{69,,pragma Extensions_Visible}.
This boolean aspect is equivalent to @ref{6e,,pragma Favor_Top_Level}.
@node Aspect Ghost,Aspect Global,Aspect Favor_Top_Level,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-ghost}@anchor{134}
+@anchor{gnat_rm/implementation_defined_aspects aspect-ghost}@anchor{137}
@section Aspect Ghost
@@ -9589,7 +9607,7 @@ This boolean aspect is equivalent to @ref{6e,,pragma Favor_Top_Level}.
This aspect is equivalent to @ref{71,,pragma Ghost}.
@node Aspect Global,Aspect Initial_Condition,Aspect Ghost,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-global}@anchor{135}
+@anchor{gnat_rm/implementation_defined_aspects aspect-global}@anchor{138}
@section Aspect Global
@@ -9598,7 +9616,7 @@ This aspect is equivalent to @ref{71,,pragma Ghost}.
This aspect is equivalent to @ref{73,,pragma Global}.
@node Aspect Initial_Condition,Aspect Initializes,Aspect Global,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-initial-condition}@anchor{136}
+@anchor{gnat_rm/implementation_defined_aspects aspect-initial-condition}@anchor{139}
@section Aspect Initial_Condition
@@ -9607,7 +9625,7 @@ This aspect is equivalent to @ref{73,,pragma Global}.
This aspect is equivalent to @ref{81,,pragma Initial_Condition}.
@node Aspect Initializes,Aspect Inline_Always,Aspect Initial_Condition,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-initializes}@anchor{137}
+@anchor{gnat_rm/implementation_defined_aspects aspect-initializes}@anchor{13a}
@section Aspect Initializes
@@ -9616,7 +9634,7 @@ This aspect is equivalent to @ref{81,,pragma Initial_Condition}.
This aspect is equivalent to @ref{83,,pragma Initializes}.
@node Aspect Inline_Always,Aspect Invariant,Aspect Initializes,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-inline-always}@anchor{138}
+@anchor{gnat_rm/implementation_defined_aspects aspect-inline-always}@anchor{13b}
@section Aspect Inline_Always
@@ -9625,7 +9643,7 @@ This aspect is equivalent to @ref{83,,pragma Initializes}.
This boolean aspect is equivalent to @ref{86,,pragma Inline_Always}.
@node Aspect Invariant,Aspect Invariant'Class,Aspect Inline_Always,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-invariant}@anchor{139}
+@anchor{gnat_rm/implementation_defined_aspects aspect-invariant}@anchor{13c}
@section Aspect Invariant
@@ -9636,18 +9654,18 @@ synonym for the language defined aspect @code{Type_Invariant} except
that it is separately controllable using pragma @code{Assertion_Policy}.
@node Aspect Invariant'Class,Aspect Iterable,Aspect Invariant,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-invariant-class}@anchor{13a}
+@anchor{gnat_rm/implementation_defined_aspects aspect-invariant-class}@anchor{13d}
@section Aspect Invariant'Class
@geindex Invariant'Class
-This aspect is equivalent to @ref{104,,pragma Type_Invariant_Class}. It is a
+This aspect is equivalent to @ref{106,,pragma Type_Invariant_Class}. It is a
synonym for the language defined aspect @code{Type_Invariant'Class} except
that it is separately controllable using pragma @code{Assertion_Policy}.
@node Aspect Iterable,Aspect Linker_Section,Aspect Invariant'Class,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-iterable}@anchor{13b}
+@anchor{gnat_rm/implementation_defined_aspects aspect-iterable}@anchor{13e}
@section Aspect Iterable
@@ -9727,7 +9745,7 @@ function Get_Element (Cont : Container; Position : Cursor) return Element_Type;
This aspect is used in the GNAT-defined formal container packages.
@node Aspect Linker_Section,Aspect Lock_Free,Aspect Iterable,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-linker-section}@anchor{13c}
+@anchor{gnat_rm/implementation_defined_aspects aspect-linker-section}@anchor{13f}
@section Aspect Linker_Section
@@ -9736,7 +9754,7 @@ This aspect is used in the GNAT-defined formal container packages.
This aspect is equivalent to @ref{95,,pragma Linker_Section}.
@node Aspect Lock_Free,Aspect Max_Queue_Length,Aspect Linker_Section,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-lock-free}@anchor{13d}
+@anchor{gnat_rm/implementation_defined_aspects aspect-lock-free}@anchor{140}
@section Aspect Lock_Free
@@ -9744,8 +9762,8 @@ This aspect is equivalent to @ref{95,,pragma Linker_Section}.
This boolean aspect is equivalent to @ref{97,,pragma Lock_Free}.
-@node Aspect Max_Queue_Length,Aspect No_Elaboration_Code_All,Aspect Lock_Free,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-max-queue-length}@anchor{13e}
+@node Aspect Max_Queue_Length,Aspect No_Caching,Aspect Lock_Free,Implementation Defined Aspects
+@anchor{gnat_rm/implementation_defined_aspects aspect-max-queue-length}@anchor{141}
@section Aspect Max_Queue_Length
@@ -9753,82 +9771,91 @@ This boolean aspect is equivalent to @ref{97,,pragma Lock_Free}.
This aspect is equivalent to @ref{9f,,pragma Max_Queue_Length}.
-@node Aspect No_Elaboration_Code_All,Aspect No_Inline,Aspect Max_Queue_Length,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-no-elaboration-code-all}@anchor{13f}
+@node Aspect No_Caching,Aspect No_Elaboration_Code_All,Aspect Max_Queue_Length,Implementation Defined Aspects
+@anchor{gnat_rm/implementation_defined_aspects aspect-no-caching}@anchor{142}
+@section Aspect No_Caching
+
+
+@geindex No_Caching
+
+This boolean aspect is equivalent to @ref{a1,,pragma No_Caching}.
+
+@node Aspect No_Elaboration_Code_All,Aspect No_Inline,Aspect No_Caching,Implementation Defined Aspects
+@anchor{gnat_rm/implementation_defined_aspects aspect-no-elaboration-code-all}@anchor{143}
@section Aspect No_Elaboration_Code_All
@geindex No_Elaboration_Code_All
-This aspect is equivalent to @ref{a3,,pragma No_Elaboration_Code_All}
+This aspect is equivalent to @ref{a5,,pragma No_Elaboration_Code_All}
for a program unit.
@node Aspect No_Inline,Aspect No_Tagged_Streams,Aspect No_Elaboration_Code_All,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-no-inline}@anchor{140}
+@anchor{gnat_rm/implementation_defined_aspects aspect-no-inline}@anchor{144}
@section Aspect No_Inline
@geindex No_Inline
-This boolean aspect is equivalent to @ref{a6,,pragma No_Inline}.
+This boolean aspect is equivalent to @ref{a8,,pragma No_Inline}.
@node Aspect No_Tagged_Streams,Aspect Object_Size,Aspect No_Inline,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-no-tagged-streams}@anchor{141}
+@anchor{gnat_rm/implementation_defined_aspects aspect-no-tagged-streams}@anchor{145}
@section Aspect No_Tagged_Streams
@geindex No_Tagged_Streams
-This aspect is equivalent to @ref{aa,,pragma No_Tagged_Streams} with an
+This aspect is equivalent to @ref{ac,,pragma No_Tagged_Streams} with an
argument specifying a root tagged type (thus this aspect can only be
applied to such a type).
@node Aspect Object_Size,Aspect Obsolescent,Aspect No_Tagged_Streams,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-object-size}@anchor{142}
+@anchor{gnat_rm/implementation_defined_aspects aspect-object-size}@anchor{146}
@section Aspect Object_Size
@geindex Object_Size
-This aspect is equivalent to @ref{143,,attribute Object_Size}.
+This aspect is equivalent to @ref{147,,attribute Object_Size}.
@node Aspect Obsolescent,Aspect Part_Of,Aspect Object_Size,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-obsolescent}@anchor{144}
+@anchor{gnat_rm/implementation_defined_aspects aspect-obsolescent}@anchor{148}
@section Aspect Obsolescent
@geindex Obsolsecent
-This aspect is equivalent to @ref{ad,,pragma Obsolescent}. Note that the
+This aspect is equivalent to @ref{af,,pragma Obsolescent}. Note that the
evaluation of this aspect happens at the point of occurrence, it is not
delayed until the freeze point.
@node Aspect Part_Of,Aspect Persistent_BSS,Aspect Obsolescent,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-part-of}@anchor{145}
+@anchor{gnat_rm/implementation_defined_aspects aspect-part-of}@anchor{149}
@section Aspect Part_Of
@geindex Part_Of
-This aspect is equivalent to @ref{b5,,pragma Part_Of}.
+This aspect is equivalent to @ref{b7,,pragma Part_Of}.
@node Aspect Persistent_BSS,Aspect Predicate,Aspect Part_Of,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-persistent-bss}@anchor{146}
+@anchor{gnat_rm/implementation_defined_aspects aspect-persistent-bss}@anchor{14a}
@section Aspect Persistent_BSS
@geindex Persistent_BSS
-This boolean aspect is equivalent to @ref{b8,,pragma Persistent_BSS}.
+This boolean aspect is equivalent to @ref{ba,,pragma Persistent_BSS}.
@node Aspect Predicate,Aspect Pure_Function,Aspect Persistent_BSS,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-predicate}@anchor{147}
+@anchor{gnat_rm/implementation_defined_aspects aspect-predicate}@anchor{14b}
@section Aspect Predicate
@geindex Predicate
-This aspect is equivalent to @ref{c1,,pragma Predicate}. It is thus
+This aspect is equivalent to @ref{c2,,pragma Predicate}. It is thus
similar to the language defined aspects @code{Dynamic_Predicate}
and @code{Static_Predicate} except that whether the resulting
predicate is static or dynamic is controlled by the form of the
@@ -9836,239 +9863,239 @@ expression. It is also separately controllable using pragma
@code{Assertion_Policy}.
@node Aspect Pure_Function,Aspect Refined_Depends,Aspect Predicate,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-pure-function}@anchor{148}
+@anchor{gnat_rm/implementation_defined_aspects aspect-pure-function}@anchor{14c}
@section Aspect Pure_Function
@geindex Pure_Function
-This boolean aspect is equivalent to @ref{cc,,pragma Pure_Function}.
+This boolean aspect is equivalent to @ref{ce,,pragma Pure_Function}.
@node Aspect Refined_Depends,Aspect Refined_Global,Aspect Pure_Function,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-refined-depends}@anchor{149}
+@anchor{gnat_rm/implementation_defined_aspects aspect-refined-depends}@anchor{14d}
@section Aspect Refined_Depends
@geindex Refined_Depends
-This aspect is equivalent to @ref{d0,,pragma Refined_Depends}.
+This aspect is equivalent to @ref{d2,,pragma Refined_Depends}.
@node Aspect Refined_Global,Aspect Refined_Post,Aspect Refined_Depends,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-refined-global}@anchor{14a}
+@anchor{gnat_rm/implementation_defined_aspects aspect-refined-global}@anchor{14e}
@section Aspect Refined_Global
@geindex Refined_Global
-This aspect is equivalent to @ref{d2,,pragma Refined_Global}.
+This aspect is equivalent to @ref{d4,,pragma Refined_Global}.
@node Aspect Refined_Post,Aspect Refined_State,Aspect Refined_Global,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-refined-post}@anchor{14b}
+@anchor{gnat_rm/implementation_defined_aspects aspect-refined-post}@anchor{14f}
@section Aspect Refined_Post
@geindex Refined_Post
-This aspect is equivalent to @ref{d4,,pragma Refined_Post}.
+This aspect is equivalent to @ref{d6,,pragma Refined_Post}.
@node Aspect Refined_State,Aspect Remote_Access_Type,Aspect Refined_Post,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-refined-state}@anchor{14c}
+@anchor{gnat_rm/implementation_defined_aspects aspect-refined-state}@anchor{150}
@section Aspect Refined_State
@geindex Refined_State
-This aspect is equivalent to @ref{d6,,pragma Refined_State}.
+This aspect is equivalent to @ref{d8,,pragma Refined_State}.
@node Aspect Remote_Access_Type,Aspect Secondary_Stack_Size,Aspect Refined_State,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-remote-access-type}@anchor{14d}
+@anchor{gnat_rm/implementation_defined_aspects aspect-remote-access-type}@anchor{151}
@section Aspect Remote_Access_Type
@geindex Remote_Access_Type
-This aspect is equivalent to @ref{da,,pragma Remote_Access_Type}.
+This aspect is equivalent to @ref{dc,,pragma Remote_Access_Type}.
@node Aspect Secondary_Stack_Size,Aspect Scalar_Storage_Order,Aspect Remote_Access_Type,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-secondary-stack-size}@anchor{14e}
+@anchor{gnat_rm/implementation_defined_aspects aspect-secondary-stack-size}@anchor{152}
@section Aspect Secondary_Stack_Size
@geindex Secondary_Stack_Size
-This aspect is equivalent to @ref{df,,pragma Secondary_Stack_Size}.
+This aspect is equivalent to @ref{e1,,pragma Secondary_Stack_Size}.
@node Aspect Scalar_Storage_Order,Aspect Shared,Aspect Secondary_Stack_Size,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-scalar-storage-order}@anchor{14f}
+@anchor{gnat_rm/implementation_defined_aspects aspect-scalar-storage-order}@anchor{153}
@section Aspect Scalar_Storage_Order
@geindex Scalar_Storage_Order
-This aspect is equivalent to a @ref{150,,attribute Scalar_Storage_Order}.
+This aspect is equivalent to a @ref{154,,attribute Scalar_Storage_Order}.
@node Aspect Shared,Aspect Simple_Storage_Pool,Aspect Scalar_Storage_Order,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-shared}@anchor{151}
+@anchor{gnat_rm/implementation_defined_aspects aspect-shared}@anchor{155}
@section Aspect Shared
@geindex Shared
-This boolean aspect is equivalent to @ref{e2,,pragma Shared}
+This boolean aspect is equivalent to @ref{e4,,pragma Shared}
and is thus a synonym for aspect @code{Atomic}.
@node Aspect Simple_Storage_Pool,Aspect Simple_Storage_Pool_Type,Aspect Shared,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-simple-storage-pool}@anchor{152}
+@anchor{gnat_rm/implementation_defined_aspects aspect-simple-storage-pool}@anchor{156}
@section Aspect Simple_Storage_Pool
@geindex Simple_Storage_Pool
-This aspect is equivalent to @ref{e7,,attribute Simple_Storage_Pool}.
+This aspect is equivalent to @ref{e9,,attribute Simple_Storage_Pool}.
@node Aspect Simple_Storage_Pool_Type,Aspect SPARK_Mode,Aspect Simple_Storage_Pool,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-simple-storage-pool-type}@anchor{153}
+@anchor{gnat_rm/implementation_defined_aspects aspect-simple-storage-pool-type}@anchor{157}
@section Aspect Simple_Storage_Pool_Type
@geindex Simple_Storage_Pool_Type
-This boolean aspect is equivalent to @ref{e5,,pragma Simple_Storage_Pool_Type}.
+This boolean aspect is equivalent to @ref{e7,,pragma Simple_Storage_Pool_Type}.
@node Aspect SPARK_Mode,Aspect Suppress_Debug_Info,Aspect Simple_Storage_Pool_Type,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-spark-mode}@anchor{154}
+@anchor{gnat_rm/implementation_defined_aspects aspect-spark-mode}@anchor{158}
@section Aspect SPARK_Mode
@geindex SPARK_Mode
-This aspect is equivalent to @ref{ed,,pragma SPARK_Mode} and
+This aspect is equivalent to @ref{ef,,pragma SPARK_Mode} and
may be specified for either or both of the specification and body
of a subprogram or package.
@node Aspect Suppress_Debug_Info,Aspect Suppress_Initialization,Aspect SPARK_Mode,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-suppress-debug-info}@anchor{155}
+@anchor{gnat_rm/implementation_defined_aspects aspect-suppress-debug-info}@anchor{159}
@section Aspect Suppress_Debug_Info
@geindex Suppress_Debug_Info
-This boolean aspect is equivalent to @ref{f5,,pragma Suppress_Debug_Info}.
+This boolean aspect is equivalent to @ref{f7,,pragma Suppress_Debug_Info}.
@node Aspect Suppress_Initialization,Aspect Test_Case,Aspect Suppress_Debug_Info,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-suppress-initialization}@anchor{156}
+@anchor{gnat_rm/implementation_defined_aspects aspect-suppress-initialization}@anchor{15a}
@section Aspect Suppress_Initialization
@geindex Suppress_Initialization
-This boolean aspect is equivalent to @ref{f9,,pragma Suppress_Initialization}.
+This boolean aspect is equivalent to @ref{fb,,pragma Suppress_Initialization}.
@node Aspect Test_Case,Aspect Thread_Local_Storage,Aspect Suppress_Initialization,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-test-case}@anchor{157}
+@anchor{gnat_rm/implementation_defined_aspects aspect-test-case}@anchor{15b}
@section Aspect Test_Case
@geindex Test_Case
-This aspect is equivalent to @ref{fc,,pragma Test_Case}.
+This aspect is equivalent to @ref{fe,,pragma Test_Case}.
@node Aspect Thread_Local_Storage,Aspect Universal_Aliasing,Aspect Test_Case,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-thread-local-storage}@anchor{158}
+@anchor{gnat_rm/implementation_defined_aspects aspect-thread-local-storage}@anchor{15c}
@section Aspect Thread_Local_Storage
@geindex Thread_Local_Storage
-This boolean aspect is equivalent to @ref{fe,,pragma Thread_Local_Storage}.
+This boolean aspect is equivalent to @ref{100,,pragma Thread_Local_Storage}.
@node Aspect Universal_Aliasing,Aspect Universal_Data,Aspect Thread_Local_Storage,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-universal-aliasing}@anchor{159}
+@anchor{gnat_rm/implementation_defined_aspects aspect-universal-aliasing}@anchor{15d}
@section Aspect Universal_Aliasing
@geindex Universal_Aliasing
-This boolean aspect is equivalent to @ref{109,,pragma Universal_Aliasing}.
+This boolean aspect is equivalent to @ref{10a,,pragma Universal_Aliasing}.
@node Aspect Universal_Data,Aspect Unmodified,Aspect Universal_Aliasing,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-universal-data}@anchor{15a}
+@anchor{gnat_rm/implementation_defined_aspects aspect-universal-data}@anchor{15e}
@section Aspect Universal_Data
@geindex Universal_Data
-This aspect is equivalent to @ref{10a,,pragma Universal_Data}.
+This aspect is equivalent to @ref{10c,,pragma Universal_Data}.
@node Aspect Unmodified,Aspect Unreferenced,Aspect Universal_Data,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-unmodified}@anchor{15b}
+@anchor{gnat_rm/implementation_defined_aspects aspect-unmodified}@anchor{15f}
@section Aspect Unmodified
@geindex Unmodified
-This boolean aspect is equivalent to @ref{10c,,pragma Unmodified}.
+This boolean aspect is equivalent to @ref{10f,,pragma Unmodified}.
@node Aspect Unreferenced,Aspect Unreferenced_Objects,Aspect Unmodified,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-unreferenced}@anchor{15c}
+@anchor{gnat_rm/implementation_defined_aspects aspect-unreferenced}@anchor{160}
@section Aspect Unreferenced
@geindex Unreferenced
-This boolean aspect is equivalent to @ref{10e,,pragma Unreferenced}. Note that
+This boolean aspect is equivalent to @ref{110,,pragma Unreferenced}. Note that
in the case of formal parameters, it is not permitted to have aspects for
a formal parameter, so in this case the pragma form must be used.
@node Aspect Unreferenced_Objects,Aspect Value_Size,Aspect Unreferenced,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-unreferenced-objects}@anchor{15d}
+@anchor{gnat_rm/implementation_defined_aspects aspect-unreferenced-objects}@anchor{161}
@section Aspect Unreferenced_Objects
@geindex Unreferenced_Objects
-This boolean aspect is equivalent to @ref{110,,pragma Unreferenced_Objects}.
+This boolean aspect is equivalent to @ref{112,,pragma Unreferenced_Objects}.
@node Aspect Value_Size,Aspect Volatile_Full_Access,Aspect Unreferenced_Objects,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-value-size}@anchor{15e}
+@anchor{gnat_rm/implementation_defined_aspects aspect-value-size}@anchor{162}
@section Aspect Value_Size
@geindex Value_Size
-This aspect is equivalent to @ref{15f,,attribute Value_Size}.
+This aspect is equivalent to @ref{163,,attribute Value_Size}.
@node Aspect Volatile_Full_Access,Aspect Volatile_Function,Aspect Value_Size,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-volatile-full-access}@anchor{160}
+@anchor{gnat_rm/implementation_defined_aspects aspect-volatile-full-access}@anchor{164}
@section Aspect Volatile_Full_Access
@geindex Volatile_Full_Access
-This boolean aspect is equivalent to @ref{119,,pragma Volatile_Full_Access}.
+This boolean aspect is equivalent to @ref{11d,,pragma Volatile_Full_Access}.
@node Aspect Volatile_Function,Aspect Warnings,Aspect Volatile_Full_Access,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-volatile-function}@anchor{161}
+@anchor{gnat_rm/implementation_defined_aspects aspect-volatile-function}@anchor{165}
@section Aspect Volatile_Function
@geindex Volatile_Function
-This boolean aspect is equivalent to @ref{11c,,pragma Volatile_Function}.
+This boolean aspect is equivalent to @ref{11f,,pragma Volatile_Function}.
@node Aspect Warnings,,Aspect Volatile_Function,Implementation Defined Aspects
-@anchor{gnat_rm/implementation_defined_aspects aspect-warnings}@anchor{162}
+@anchor{gnat_rm/implementation_defined_aspects aspect-warnings}@anchor{166}
@section Aspect Warnings
@geindex Warnings
-This aspect is equivalent to the two argument form of @ref{11e,,pragma Warnings},
+This aspect is equivalent to the two argument form of @ref{121,,pragma Warnings},
where the first argument is @code{ON} or @code{OFF} and the second argument
is the entity.
@node Implementation Defined Attributes,Standard and Implementation Defined Restrictions,Implementation Defined Aspects,Top
-@anchor{gnat_rm/implementation_defined_attributes doc}@anchor{163}@anchor{gnat_rm/implementation_defined_attributes implementation-defined-attributes}@anchor{8}@anchor{gnat_rm/implementation_defined_attributes id1}@anchor{164}
+@anchor{gnat_rm/implementation_defined_attributes doc}@anchor{167}@anchor{gnat_rm/implementation_defined_attributes implementation-defined-attributes}@anchor{8}@anchor{gnat_rm/implementation_defined_attributes id1}@anchor{168}
@chapter Implementation Defined Attributes
@@ -10169,7 +10196,7 @@ consideration, you should minimize the use of these attributes.
@end menu
@node Attribute Abort_Signal,Attribute Address_Size,,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-abort-signal}@anchor{165}
+@anchor{gnat_rm/implementation_defined_attributes attribute-abort-signal}@anchor{169}
@section Attribute Abort_Signal
@@ -10183,7 +10210,7 @@ completely outside the normal semantics of Ada, for a user program to
intercept the abort exception).
@node Attribute Address_Size,Attribute Asm_Input,Attribute Abort_Signal,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-address-size}@anchor{166}
+@anchor{gnat_rm/implementation_defined_attributes attribute-address-size}@anchor{16a}
@section Attribute Address_Size
@@ -10199,7 +10226,7 @@ reference to System.Address'Size is nonstatic because Address
is a private type.
@node Attribute Asm_Input,Attribute Asm_Output,Attribute Address_Size,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-asm-input}@anchor{167}
+@anchor{gnat_rm/implementation_defined_attributes attribute-asm-input}@anchor{16b}
@section Attribute Asm_Input
@@ -10213,10 +10240,10 @@ to be a static expression, and is the constraint for the parameter,
value to be used as the input argument. The possible values for the
constant are the same as those used in the RTL, and are dependent on
the configuration file used to built the GCC back end.
-@ref{168,,Machine Code Insertions}
+@ref{16c,,Machine Code Insertions}
@node Attribute Asm_Output,Attribute Atomic_Always_Lock_Free,Attribute Asm_Input,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-asm-output}@anchor{169}
+@anchor{gnat_rm/implementation_defined_attributes attribute-asm-output}@anchor{16d}
@section Attribute Asm_Output
@@ -10232,10 +10259,10 @@ result. The possible values for constraint are the same as those used in
the RTL, and are dependent on the configuration file used to build the
GCC back end. If there are no output operands, then this argument may
either be omitted, or explicitly given as @code{No_Output_Operands}.
-@ref{168,,Machine Code Insertions}
+@ref{16c,,Machine Code Insertions}
@node Attribute Atomic_Always_Lock_Free,Attribute Bit,Attribute Asm_Output,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-atomic-always-lock-free}@anchor{16a}
+@anchor{gnat_rm/implementation_defined_attributes attribute-atomic-always-lock-free}@anchor{16e}
@section Attribute Atomic_Always_Lock_Free
@@ -10247,7 +10274,7 @@ and False otherwise. The result indicate whether atomic operations are
supported by the target for the given type.
@node Attribute Bit,Attribute Bit_Position,Attribute Atomic_Always_Lock_Free,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-bit}@anchor{16b}
+@anchor{gnat_rm/implementation_defined_attributes attribute-bit}@anchor{16f}
@section Attribute Bit
@@ -10278,7 +10305,7 @@ This attribute is designed to be compatible with the DEC Ada 83 definition
and implementation of the @code{Bit} attribute.
@node Attribute Bit_Position,Attribute Code_Address,Attribute Bit,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-bit-position}@anchor{16c}
+@anchor{gnat_rm/implementation_defined_attributes attribute-bit-position}@anchor{170}
@section Attribute Bit_Position
@@ -10293,7 +10320,7 @@ type @emph{universal_integer}. The value depends only on the field
the containing record @code{R}.
@node Attribute Code_Address,Attribute Compiler_Version,Attribute Bit_Position,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-code-address}@anchor{16d}
+@anchor{gnat_rm/implementation_defined_attributes attribute-code-address}@anchor{171}
@section Attribute Code_Address
@@ -10336,7 +10363,7 @@ the same value as is returned by the corresponding @code{'Address}
attribute.
@node Attribute Compiler_Version,Attribute Constrained,Attribute Code_Address,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-compiler-version}@anchor{16e}
+@anchor{gnat_rm/implementation_defined_attributes attribute-compiler-version}@anchor{172}
@section Attribute Compiler_Version
@@ -10347,7 +10374,7 @@ prefix) yields a static string identifying the version of the compiler
being used to compile the unit containing the attribute reference.
@node Attribute Constrained,Attribute Default_Bit_Order,Attribute Compiler_Version,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-constrained}@anchor{16f}
+@anchor{gnat_rm/implementation_defined_attributes attribute-constrained}@anchor{173}
@section Attribute Constrained
@@ -10362,7 +10389,7 @@ record type without discriminants is always @code{True}. This usage is
compatible with older Ada compilers, including notably DEC Ada.
@node Attribute Default_Bit_Order,Attribute Default_Scalar_Storage_Order,Attribute Constrained,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-default-bit-order}@anchor{170}
+@anchor{gnat_rm/implementation_defined_attributes attribute-default-bit-order}@anchor{174}
@section Attribute Default_Bit_Order
@@ -10379,7 +10406,7 @@ as a @code{Pos} value (0 for @code{High_Order_First}, 1 for
@code{Default_Bit_Order} in package @code{System}.
@node Attribute Default_Scalar_Storage_Order,Attribute Deref,Attribute Default_Bit_Order,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-default-scalar-storage-order}@anchor{171}
+@anchor{gnat_rm/implementation_defined_attributes attribute-default-scalar-storage-order}@anchor{175}
@section Attribute Default_Scalar_Storage_Order
@@ -10396,7 +10423,7 @@ equal to @code{Default_Bit_Order} if unspecified) as a
@code{System.Bit_Order} value. This is a static attribute.
@node Attribute Deref,Attribute Descriptor_Size,Attribute Default_Scalar_Storage_Order,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-deref}@anchor{172}
+@anchor{gnat_rm/implementation_defined_attributes attribute-deref}@anchor{176}
@section Attribute Deref
@@ -10409,7 +10436,7 @@ a named access-to-@cite{typ} type, except that it yields a variable, so it can b
used on the left side of an assignment.
@node Attribute Descriptor_Size,Attribute Elaborated,Attribute Deref,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-descriptor-size}@anchor{173}
+@anchor{gnat_rm/implementation_defined_attributes attribute-descriptor-size}@anchor{177}
@section Attribute Descriptor_Size
@@ -10436,7 +10463,7 @@ In the example above, the descriptor contains two values of type
a size of 31 bits and an alignment of 4, the descriptor size is @code{2 * Positive'Size + 2} or 64 bits.
@node Attribute Elaborated,Attribute Elab_Body,Attribute Descriptor_Size,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-elaborated}@anchor{174}
+@anchor{gnat_rm/implementation_defined_attributes attribute-elaborated}@anchor{178}
@section Attribute Elaborated
@@ -10451,7 +10478,7 @@ units has been completed. An exception is for units which need no
elaboration, the value is always False for such units.
@node Attribute Elab_Body,Attribute Elab_Spec,Attribute Elaborated,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-elab-body}@anchor{175}
+@anchor{gnat_rm/implementation_defined_attributes attribute-elab-body}@anchor{179}
@section Attribute Elab_Body
@@ -10467,7 +10494,7 @@ e.g., if it is necessary to do selective re-elaboration to fix some
error.
@node Attribute Elab_Spec,Attribute Elab_Subp_Body,Attribute Elab_Body,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-elab-spec}@anchor{176}
+@anchor{gnat_rm/implementation_defined_attributes attribute-elab-spec}@anchor{17a}
@section Attribute Elab_Spec
@@ -10483,7 +10510,7 @@ Ada code, e.g., if it is necessary to do selective re-elaboration to fix
some error.
@node Attribute Elab_Subp_Body,Attribute Emax,Attribute Elab_Spec,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-elab-subp-body}@anchor{177}
+@anchor{gnat_rm/implementation_defined_attributes attribute-elab-subp-body}@anchor{17b}
@section Attribute Elab_Subp_Body
@@ -10497,7 +10524,7 @@ elaboration procedure by the binder in CodePeer mode only and is unrecognized
otherwise.
@node Attribute Emax,Attribute Enabled,Attribute Elab_Subp_Body,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-emax}@anchor{178}
+@anchor{gnat_rm/implementation_defined_attributes attribute-emax}@anchor{17c}
@section Attribute Emax
@@ -10510,7 +10537,7 @@ the Ada 83 reference manual for an exact description of the semantics of
this attribute.
@node Attribute Enabled,Attribute Enum_Rep,Attribute Emax,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-enabled}@anchor{179}
+@anchor{gnat_rm/implementation_defined_attributes attribute-enabled}@anchor{17d}
@section Attribute Enabled
@@ -10534,7 +10561,7 @@ a @code{pragma Suppress} or @code{pragma Unsuppress} before instantiating
the package or subprogram, controlling whether the check will be present.
@node Attribute Enum_Rep,Attribute Enum_Val,Attribute Enabled,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-enum-rep}@anchor{17a}
+@anchor{gnat_rm/implementation_defined_attributes attribute-enum-rep}@anchor{17e}
@section Attribute Enum_Rep
@@ -10571,7 +10598,7 @@ integer calculation is done at run time, then the call to @code{Enum_Rep}
may raise @code{Constraint_Error}.
@node Attribute Enum_Val,Attribute Epsilon,Attribute Enum_Rep,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-enum-val}@anchor{17b}
+@anchor{gnat_rm/implementation_defined_attributes attribute-enum-val}@anchor{17f}
@section Attribute Enum_Val
@@ -10594,7 +10621,7 @@ absence of an enumeration representation clause. This is a static
attribute (i.e., the result is static if the argument is static).
@node Attribute Epsilon,Attribute Fast_Math,Attribute Enum_Val,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-epsilon}@anchor{17c}
+@anchor{gnat_rm/implementation_defined_attributes attribute-epsilon}@anchor{180}
@section Attribute Epsilon
@@ -10607,7 +10634,7 @@ the Ada 83 reference manual for an exact description of the semantics of
this attribute.
@node Attribute Fast_Math,Attribute Finalization_Size,Attribute Epsilon,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-fast-math}@anchor{17d}
+@anchor{gnat_rm/implementation_defined_attributes attribute-fast-math}@anchor{181}
@section Attribute Fast_Math
@@ -10618,7 +10645,7 @@ prefix) yields a static Boolean value that is True if pragma
@code{Fast_Math} is active, and False otherwise.
@node Attribute Finalization_Size,Attribute Fixed_Value,Attribute Fast_Math,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-finalization-size}@anchor{17e}
+@anchor{gnat_rm/implementation_defined_attributes attribute-finalization-size}@anchor{182}
@section Attribute Finalization_Size
@@ -10636,7 +10663,7 @@ class-wide type whose tag denotes a type with no controlled parts.
Note that only heap-allocated objects contain finalization data.
@node Attribute Fixed_Value,Attribute From_Any,Attribute Finalization_Size,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-fixed-value}@anchor{17f}
+@anchor{gnat_rm/implementation_defined_attributes attribute-fixed-value}@anchor{183}
@section Attribute Fixed_Value
@@ -10663,7 +10690,7 @@ This attribute is primarily intended for use in implementation of the
input-output functions for fixed-point values.
@node Attribute From_Any,Attribute Has_Access_Values,Attribute Fixed_Value,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-from-any}@anchor{180}
+@anchor{gnat_rm/implementation_defined_attributes attribute-from-any}@anchor{184}
@section Attribute From_Any
@@ -10673,7 +10700,7 @@ This internal attribute is used for the generation of remote subprogram
stubs in the context of the Distributed Systems Annex.
@node Attribute Has_Access_Values,Attribute Has_Discriminants,Attribute From_Any,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-has-access-values}@anchor{181}
+@anchor{gnat_rm/implementation_defined_attributes attribute-has-access-values}@anchor{185}
@section Attribute Has_Access_Values
@@ -10691,7 +10718,7 @@ definitions. If the attribute is applied to a generic private type, it
indicates whether or not the corresponding actual type has access values.
@node Attribute Has_Discriminants,Attribute Img,Attribute Has_Access_Values,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-has-discriminants}@anchor{182}
+@anchor{gnat_rm/implementation_defined_attributes attribute-has-discriminants}@anchor{186}
@section Attribute Has_Discriminants
@@ -10707,7 +10734,7 @@ definitions. If the attribute is applied to a generic private type, it
indicates whether or not the corresponding actual type has discriminants.
@node Attribute Img,Attribute Integer_Value,Attribute Has_Discriminants,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-img}@anchor{183}
+@anchor{gnat_rm/implementation_defined_attributes attribute-img}@anchor{187}
@section Attribute Img
@@ -10737,7 +10764,7 @@ that returns the appropriate string when called. This means that
in an instantiation as a function parameter.
@node Attribute Integer_Value,Attribute Invalid_Value,Attribute Img,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-integer-value}@anchor{184}
+@anchor{gnat_rm/implementation_defined_attributes attribute-integer-value}@anchor{188}
@section Attribute Integer_Value
@@ -10765,7 +10792,7 @@ This attribute is primarily intended for use in implementation of the
standard input-output functions for fixed-point values.
@node Attribute Invalid_Value,Attribute Iterable,Attribute Integer_Value,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-invalid-value}@anchor{185}
+@anchor{gnat_rm/implementation_defined_attributes attribute-invalid-value}@anchor{189}
@section Attribute Invalid_Value
@@ -10779,7 +10806,7 @@ including the ability to modify the value with the binder -Sxx flag and
relevant environment variables at run time.
@node Attribute Iterable,Attribute Large,Attribute Invalid_Value,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-iterable}@anchor{186}
+@anchor{gnat_rm/implementation_defined_attributes attribute-iterable}@anchor{18a}
@section Attribute Iterable
@@ -10788,7 +10815,7 @@ relevant environment variables at run time.
Equivalent to Aspect Iterable.
@node Attribute Large,Attribute Library_Level,Attribute Iterable,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-large}@anchor{187}
+@anchor{gnat_rm/implementation_defined_attributes attribute-large}@anchor{18b}
@section Attribute Large
@@ -10801,7 +10828,7 @@ the Ada 83 reference manual for an exact description of the semantics of
this attribute.
@node Attribute Library_Level,Attribute Lock_Free,Attribute Large,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-library-level}@anchor{188}
+@anchor{gnat_rm/implementation_defined_attributes attribute-library-level}@anchor{18c}
@section Attribute Library_Level
@@ -10827,7 +10854,7 @@ end Gen;
@end example
@node Attribute Lock_Free,Attribute Loop_Entry,Attribute Library_Level,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-lock-free}@anchor{189}
+@anchor{gnat_rm/implementation_defined_attributes attribute-lock-free}@anchor{18d}
@section Attribute Lock_Free
@@ -10837,7 +10864,7 @@ end Gen;
pragma @code{Lock_Free} applies to P.
@node Attribute Loop_Entry,Attribute Machine_Size,Attribute Lock_Free,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-loop-entry}@anchor{18a}
+@anchor{gnat_rm/implementation_defined_attributes attribute-loop-entry}@anchor{18e}
@section Attribute Loop_Entry
@@ -10867,7 +10894,7 @@ entry. This copy is not performed if the loop is not entered, or if the
corresponding pragmas are ignored or disabled.
@node Attribute Machine_Size,Attribute Mantissa,Attribute Loop_Entry,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-machine-size}@anchor{18b}
+@anchor{gnat_rm/implementation_defined_attributes attribute-machine-size}@anchor{18f}
@section Attribute Machine_Size
@@ -10877,7 +10904,7 @@ This attribute is identical to the @code{Object_Size} attribute. It is
provided for compatibility with the DEC Ada 83 attribute of this name.
@node Attribute Mantissa,Attribute Maximum_Alignment,Attribute Machine_Size,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-mantissa}@anchor{18c}
+@anchor{gnat_rm/implementation_defined_attributes attribute-mantissa}@anchor{190}
@section Attribute Mantissa
@@ -10890,7 +10917,7 @@ the Ada 83 reference manual for an exact description of the semantics of
this attribute.
@node Attribute Maximum_Alignment,Attribute Mechanism_Code,Attribute Mantissa,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-maximum-alignment}@anchor{18d}@anchor{gnat_rm/implementation_defined_attributes id2}@anchor{18e}
+@anchor{gnat_rm/implementation_defined_attributes attribute-maximum-alignment}@anchor{191}@anchor{gnat_rm/implementation_defined_attributes id2}@anchor{192}
@section Attribute Maximum_Alignment
@@ -10906,7 +10933,7 @@ for an object, guaranteeing that it is properly aligned in all
cases.
@node Attribute Mechanism_Code,Attribute Null_Parameter,Attribute Maximum_Alignment,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-mechanism-code}@anchor{18f}
+@anchor{gnat_rm/implementation_defined_attributes attribute-mechanism-code}@anchor{193}
@section Attribute Mechanism_Code
@@ -10937,7 +10964,7 @@ by reference
@end table
@node Attribute Null_Parameter,Attribute Object_Size,Attribute Mechanism_Code,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-null-parameter}@anchor{190}
+@anchor{gnat_rm/implementation_defined_attributes attribute-null-parameter}@anchor{194}
@section Attribute Null_Parameter
@@ -10962,7 +10989,7 @@ There is no way of indicating this without the @code{Null_Parameter}
attribute.
@node Attribute Object_Size,Attribute Old,Attribute Null_Parameter,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-object-size}@anchor{143}@anchor{gnat_rm/implementation_defined_attributes id3}@anchor{191}
+@anchor{gnat_rm/implementation_defined_attributes attribute-object-size}@anchor{147}@anchor{gnat_rm/implementation_defined_attributes id3}@anchor{195}
@section Attribute Object_Size
@@ -11032,7 +11059,7 @@ Similar additional checks are performed in other contexts requiring
statically matching subtypes.
@node Attribute Old,Attribute Passed_By_Reference,Attribute Object_Size,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-old}@anchor{192}
+@anchor{gnat_rm/implementation_defined_attributes attribute-old}@anchor{196}
@section Attribute Old
@@ -11047,7 +11074,7 @@ definition are allowed under control of
implementation defined pragma @code{Unevaluated_Use_Of_Old}.
@node Attribute Passed_By_Reference,Attribute Pool_Address,Attribute Old,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-passed-by-reference}@anchor{193}
+@anchor{gnat_rm/implementation_defined_attributes attribute-passed-by-reference}@anchor{197}
@section Attribute Passed_By_Reference
@@ -11063,7 +11090,7 @@ passed by copy in calls. For scalar types, the result is always @code{False}
and is static. For non-scalar types, the result is nonstatic.
@node Attribute Pool_Address,Attribute Range_Length,Attribute Passed_By_Reference,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-pool-address}@anchor{194}
+@anchor{gnat_rm/implementation_defined_attributes attribute-pool-address}@anchor{198}
@section Attribute Pool_Address
@@ -11088,7 +11115,7 @@ For an object created by @code{new}, @code{Ptr.all'Pool_Address} is
what is passed to @code{Allocate} and returned from @code{Deallocate}.
@node Attribute Range_Length,Attribute Restriction_Set,Attribute Pool_Address,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-range-length}@anchor{195}
+@anchor{gnat_rm/implementation_defined_attributes attribute-range-length}@anchor{199}
@section Attribute Range_Length
@@ -11101,7 +11128,7 @@ applied to the index subtype of a one dimensional array always gives the
same result as @code{Length} applied to the array itself.
@node Attribute Restriction_Set,Attribute Result,Attribute Range_Length,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-restriction-set}@anchor{196}
+@anchor{gnat_rm/implementation_defined_attributes attribute-restriction-set}@anchor{19a}
@section Attribute Restriction_Set
@@ -11171,7 +11198,7 @@ Restrictions pragma, they are not analyzed semantically,
so they do not have a type.
@node Attribute Result,Attribute Safe_Emax,Attribute Restriction_Set,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-result}@anchor{197}
+@anchor{gnat_rm/implementation_defined_attributes attribute-result}@anchor{19b}
@section Attribute Result
@@ -11184,7 +11211,7 @@ For a further discussion of the use of this attribute and examples of its use,
see the description of pragma Postcondition.
@node Attribute Safe_Emax,Attribute Safe_Large,Attribute Result,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-safe-emax}@anchor{198}
+@anchor{gnat_rm/implementation_defined_attributes attribute-safe-emax}@anchor{19c}
@section Attribute Safe_Emax
@@ -11197,7 +11224,7 @@ the Ada 83 reference manual for an exact description of the semantics of
this attribute.
@node Attribute Safe_Large,Attribute Safe_Small,Attribute Safe_Emax,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-safe-large}@anchor{199}
+@anchor{gnat_rm/implementation_defined_attributes attribute-safe-large}@anchor{19d}
@section Attribute Safe_Large
@@ -11210,7 +11237,7 @@ the Ada 83 reference manual for an exact description of the semantics of
this attribute.
@node Attribute Safe_Small,Attribute Scalar_Storage_Order,Attribute Safe_Large,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-safe-small}@anchor{19a}
+@anchor{gnat_rm/implementation_defined_attributes attribute-safe-small}@anchor{19e}
@section Attribute Safe_Small
@@ -11223,7 +11250,7 @@ the Ada 83 reference manual for an exact description of the semantics of
this attribute.
@node Attribute Scalar_Storage_Order,Attribute Simple_Storage_Pool,Attribute Safe_Small,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes id4}@anchor{19b}@anchor{gnat_rm/implementation_defined_attributes attribute-scalar-storage-order}@anchor{150}
+@anchor{gnat_rm/implementation_defined_attributes id4}@anchor{19f}@anchor{gnat_rm/implementation_defined_attributes attribute-scalar-storage-order}@anchor{154}
@section Attribute Scalar_Storage_Order
@@ -11346,7 +11373,7 @@ Note that debuggers may be unable to display the correct value of scalar
components of a type for which the opposite storage order is specified.
@node Attribute Simple_Storage_Pool,Attribute Small,Attribute Scalar_Storage_Order,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-simple-storage-pool}@anchor{e7}@anchor{gnat_rm/implementation_defined_attributes id5}@anchor{19c}
+@anchor{gnat_rm/implementation_defined_attributes attribute-simple-storage-pool}@anchor{e9}@anchor{gnat_rm/implementation_defined_attributes id5}@anchor{1a0}
@section Attribute Simple_Storage_Pool
@@ -11409,7 +11436,7 @@ as defined in section 13.11.2 of the Ada Reference Manual, except that the
term @emph{simple storage pool} is substituted for @emph{storage pool}.
@node Attribute Small,Attribute Storage_Unit,Attribute Simple_Storage_Pool,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-small}@anchor{19d}
+@anchor{gnat_rm/implementation_defined_attributes attribute-small}@anchor{1a1}
@section Attribute Small
@@ -11425,7 +11452,7 @@ the Ada 83 reference manual for an exact description of the semantics of
this attribute when applied to floating-point types.
@node Attribute Storage_Unit,Attribute Stub_Type,Attribute Small,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-storage-unit}@anchor{19e}
+@anchor{gnat_rm/implementation_defined_attributes attribute-storage-unit}@anchor{1a2}
@section Attribute Storage_Unit
@@ -11435,7 +11462,7 @@ this attribute when applied to floating-point types.
prefix) provides the same value as @code{System.Storage_Unit}.
@node Attribute Stub_Type,Attribute System_Allocator_Alignment,Attribute Storage_Unit,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-stub-type}@anchor{19f}
+@anchor{gnat_rm/implementation_defined_attributes attribute-stub-type}@anchor{1a3}
@section Attribute Stub_Type
@@ -11459,7 +11486,7 @@ unit @code{System.Partition_Interface}. Use of this attribute will create
an implicit dependency on this unit.
@node Attribute System_Allocator_Alignment,Attribute Target_Name,Attribute Stub_Type,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-system-allocator-alignment}@anchor{1a0}
+@anchor{gnat_rm/implementation_defined_attributes attribute-system-allocator-alignment}@anchor{1a4}
@section Attribute System_Allocator_Alignment
@@ -11476,7 +11503,7 @@ with alignment too large or to enable a realignment circuitry if the
alignment request is larger than this value.
@node Attribute Target_Name,Attribute To_Address,Attribute System_Allocator_Alignment,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-target-name}@anchor{1a1}
+@anchor{gnat_rm/implementation_defined_attributes attribute-target-name}@anchor{1a5}
@section Attribute Target_Name
@@ -11489,7 +11516,7 @@ standard gcc target name without the terminating slash (for
example, GNAT 5.0 on windows yields "i586-pc-mingw32msv").
@node Attribute To_Address,Attribute To_Any,Attribute Target_Name,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-to-address}@anchor{1a2}
+@anchor{gnat_rm/implementation_defined_attributes attribute-to-address}@anchor{1a6}
@section Attribute To_Address
@@ -11512,7 +11539,7 @@ modular manner (e.g., -1 means the same as 16#FFFF_FFFF# on
a 32 bits machine).
@node Attribute To_Any,Attribute Type_Class,Attribute To_Address,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-to-any}@anchor{1a3}
+@anchor{gnat_rm/implementation_defined_attributes attribute-to-any}@anchor{1a7}
@section Attribute To_Any
@@ -11522,7 +11549,7 @@ This internal attribute is used for the generation of remote subprogram
stubs in the context of the Distributed Systems Annex.
@node Attribute Type_Class,Attribute Type_Key,Attribute To_Any,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-type-class}@anchor{1a4}
+@anchor{gnat_rm/implementation_defined_attributes attribute-type-class}@anchor{1a8}
@section Attribute Type_Class
@@ -11552,7 +11579,7 @@ applies to all concurrent types. This attribute is designed to
be compatible with the DEC Ada 83 attribute of the same name.
@node Attribute Type_Key,Attribute TypeCode,Attribute Type_Class,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-type-key}@anchor{1a5}
+@anchor{gnat_rm/implementation_defined_attributes attribute-type-key}@anchor{1a9}
@section Attribute Type_Key
@@ -11564,7 +11591,7 @@ about the type or subtype. This provides improved compatibility with
other implementations that support this attribute.
@node Attribute TypeCode,Attribute Unconstrained_Array,Attribute Type_Key,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-typecode}@anchor{1a6}
+@anchor{gnat_rm/implementation_defined_attributes attribute-typecode}@anchor{1aa}
@section Attribute TypeCode
@@ -11574,7 +11601,7 @@ This internal attribute is used for the generation of remote subprogram
stubs in the context of the Distributed Systems Annex.
@node Attribute Unconstrained_Array,Attribute Universal_Literal_String,Attribute TypeCode,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-unconstrained-array}@anchor{1a7}
+@anchor{gnat_rm/implementation_defined_attributes attribute-unconstrained-array}@anchor{1ab}
@section Attribute Unconstrained_Array
@@ -11588,7 +11615,7 @@ still static, and yields the result of applying this test to the
generic actual.
@node Attribute Universal_Literal_String,Attribute Unrestricted_Access,Attribute Unconstrained_Array,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-universal-literal-string}@anchor{1a8}
+@anchor{gnat_rm/implementation_defined_attributes attribute-universal-literal-string}@anchor{1ac}
@section Attribute Universal_Literal_String
@@ -11616,7 +11643,7 @@ end;
@end example
@node Attribute Unrestricted_Access,Attribute Update,Attribute Universal_Literal_String,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-unrestricted-access}@anchor{1a9}
+@anchor{gnat_rm/implementation_defined_attributes attribute-unrestricted-access}@anchor{1ad}
@section Attribute Unrestricted_Access
@@ -11803,7 +11830,7 @@ In general this is a risky approach. It may appear to "work" but such uses of
of GNAT to another, so are best avoided if possible.
@node Attribute Update,Attribute Valid_Scalars,Attribute Unrestricted_Access,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-update}@anchor{1aa}
+@anchor{gnat_rm/implementation_defined_attributes attribute-update}@anchor{1ae}
@section Attribute Update
@@ -11884,7 +11911,7 @@ A := A'Update ((1, 2) => 20, (3, 4) => 30);
which changes element (1,2) to 20 and (3,4) to 30.
@node Attribute Valid_Scalars,Attribute VADS_Size,Attribute Update,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-valid-scalars}@anchor{1ab}
+@anchor{gnat_rm/implementation_defined_attributes attribute-valid-scalars}@anchor{1af}
@section Attribute Valid_Scalars
@@ -11918,7 +11945,7 @@ write a function with a single use of the attribute, and then call that
function from multiple places.
@node Attribute VADS_Size,Attribute Value_Size,Attribute Valid_Scalars,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-vads-size}@anchor{1ac}
+@anchor{gnat_rm/implementation_defined_attributes attribute-vads-size}@anchor{1b0}
@section Attribute VADS_Size
@@ -11938,7 +11965,7 @@ gives the result that would be obtained by applying the attribute to
the corresponding type.
@node Attribute Value_Size,Attribute Wchar_T_Size,Attribute VADS_Size,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes id6}@anchor{1ad}@anchor{gnat_rm/implementation_defined_attributes attribute-value-size}@anchor{15f}
+@anchor{gnat_rm/implementation_defined_attributes id6}@anchor{1b1}@anchor{gnat_rm/implementation_defined_attributes attribute-value-size}@anchor{163}
@section Attribute Value_Size
@@ -11952,7 +11979,7 @@ a value of the given subtype. It is the same as @code{type'Size},
but, unlike @code{Size}, may be set for non-first subtypes.
@node Attribute Wchar_T_Size,Attribute Word_Size,Attribute Value_Size,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-wchar-t-size}@anchor{1ae}
+@anchor{gnat_rm/implementation_defined_attributes attribute-wchar-t-size}@anchor{1b2}
@section Attribute Wchar_T_Size
@@ -11964,7 +11991,7 @@ primarily for constructing the definition of this type in
package @code{Interfaces.C}. The result is a static constant.
@node Attribute Word_Size,,Attribute Wchar_T_Size,Implementation Defined Attributes
-@anchor{gnat_rm/implementation_defined_attributes attribute-word-size}@anchor{1af}
+@anchor{gnat_rm/implementation_defined_attributes attribute-word-size}@anchor{1b3}
@section Attribute Word_Size
@@ -11975,7 +12002,7 @@ prefix) provides the value @code{System.Word_Size}. The result is
a static constant.
@node Standard and Implementation Defined Restrictions,Implementation Advice,Implementation Defined Attributes,Top
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions standard-and-implementation-defined-restrictions}@anchor{9}@anchor{gnat_rm/standard_and_implementation_defined_restrictions doc}@anchor{1b0}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id1}@anchor{1b1}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions standard-and-implementation-defined-restrictions}@anchor{9}@anchor{gnat_rm/standard_and_implementation_defined_restrictions doc}@anchor{1b4}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id1}@anchor{1b5}
@chapter Standard and Implementation Defined Restrictions
@@ -12004,7 +12031,7 @@ language defined or GNAT-specific, are listed in the following.
@end menu
@node Partition-Wide Restrictions,Program Unit Level Restrictions,,Standard and Implementation Defined Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions partition-wide-restrictions}@anchor{1b2}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id2}@anchor{1b3}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions partition-wide-restrictions}@anchor{1b6}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id2}@anchor{1b7}
@section Partition-Wide Restrictions
@@ -12093,7 +12120,7 @@ then all compilation units in the partition must obey the restriction).
@end menu
@node Immediate_Reclamation,Max_Asynchronous_Select_Nesting,,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions immediate-reclamation}@anchor{1b4}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions immediate-reclamation}@anchor{1b8}
@subsection Immediate_Reclamation
@@ -12105,7 +12132,7 @@ deallocation, any storage reserved at run time for an object is
immediately reclaimed when the object no longer exists.
@node Max_Asynchronous_Select_Nesting,Max_Entry_Queue_Length,Immediate_Reclamation,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-asynchronous-select-nesting}@anchor{1b5}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-asynchronous-select-nesting}@anchor{1b9}
@subsection Max_Asynchronous_Select_Nesting
@@ -12117,7 +12144,7 @@ detected at compile time. Violations of this restriction with values
other than zero cause Storage_Error to be raised.
@node Max_Entry_Queue_Length,Max_Protected_Entries,Max_Asynchronous_Select_Nesting,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-entry-queue-length}@anchor{1b6}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-entry-queue-length}@anchor{1ba}
@subsection Max_Entry_Queue_Length
@@ -12138,7 +12165,7 @@ compatibility purposes (and a warning will be generated for its use if
warnings on obsolescent features are activated).
@node Max_Protected_Entries,Max_Select_Alternatives,Max_Entry_Queue_Length,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-protected-entries}@anchor{1b7}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-protected-entries}@anchor{1bb}
@subsection Max_Protected_Entries
@@ -12149,7 +12176,7 @@ bounds of every entry family of a protected unit shall be static, or shall be
defined by a discriminant of a subtype whose corresponding bound is static.
@node Max_Select_Alternatives,Max_Storage_At_Blocking,Max_Protected_Entries,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-select-alternatives}@anchor{1b8}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-select-alternatives}@anchor{1bc}
@subsection Max_Select_Alternatives
@@ -12158,7 +12185,7 @@ defined by a discriminant of a subtype whose corresponding bound is static.
[RM D.7] Specifies the maximum number of alternatives in a selective accept.
@node Max_Storage_At_Blocking,Max_Task_Entries,Max_Select_Alternatives,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-storage-at-blocking}@anchor{1b9}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-storage-at-blocking}@anchor{1bd}
@subsection Max_Storage_At_Blocking
@@ -12169,7 +12196,7 @@ Storage_Size that can be retained by a blocked task. A violation of this
restriction causes Storage_Error to be raised.
@node Max_Task_Entries,Max_Tasks,Max_Storage_At_Blocking,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-task-entries}@anchor{1ba}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-task-entries}@anchor{1be}
@subsection Max_Task_Entries
@@ -12182,7 +12209,7 @@ defined by a discriminant of a subtype whose
corresponding bound is static.
@node Max_Tasks,No_Abort_Statements,Max_Task_Entries,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-tasks}@anchor{1bb}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions max-tasks}@anchor{1bf}
@subsection Max_Tasks
@@ -12195,7 +12222,7 @@ time. Violations of this restriction with values other than zero cause
Storage_Error to be raised.
@node No_Abort_Statements,No_Access_Parameter_Allocators,Max_Tasks,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-abort-statements}@anchor{1bc}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-abort-statements}@anchor{1c0}
@subsection No_Abort_Statements
@@ -12205,7 +12232,7 @@ Storage_Error to be raised.
no calls to Task_Identification.Abort_Task.
@node No_Access_Parameter_Allocators,No_Access_Subprograms,No_Abort_Statements,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-access-parameter-allocators}@anchor{1bd}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-access-parameter-allocators}@anchor{1c1}
@subsection No_Access_Parameter_Allocators
@@ -12216,7 +12243,7 @@ occurrences of an allocator as the actual parameter to an access
parameter.
@node No_Access_Subprograms,No_Allocators,No_Access_Parameter_Allocators,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-access-subprograms}@anchor{1be}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-access-subprograms}@anchor{1c2}
@subsection No_Access_Subprograms
@@ -12226,7 +12253,7 @@ parameter.
declarations of access-to-subprogram types.
@node No_Allocators,No_Anonymous_Allocators,No_Access_Subprograms,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-allocators}@anchor{1bf}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-allocators}@anchor{1c3}
@subsection No_Allocators
@@ -12236,7 +12263,7 @@ declarations of access-to-subprogram types.
occurrences of an allocator.
@node No_Anonymous_Allocators,No_Asynchronous_Control,No_Allocators,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-anonymous-allocators}@anchor{1c0}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-anonymous-allocators}@anchor{1c4}
@subsection No_Anonymous_Allocators
@@ -12246,7 +12273,7 @@ occurrences of an allocator.
occurrences of an allocator of anonymous access type.
@node No_Asynchronous_Control,No_Calendar,No_Anonymous_Allocators,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-asynchronous-control}@anchor{1c1}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-asynchronous-control}@anchor{1c5}
@subsection No_Asynchronous_Control
@@ -12256,7 +12283,7 @@ occurrences of an allocator of anonymous access type.
dependences on the predefined package Asynchronous_Task_Control.
@node No_Calendar,No_Coextensions,No_Asynchronous_Control,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-calendar}@anchor{1c2}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-calendar}@anchor{1c6}
@subsection No_Calendar
@@ -12266,7 +12293,7 @@ dependences on the predefined package Asynchronous_Task_Control.
dependences on package Calendar.
@node No_Coextensions,No_Default_Initialization,No_Calendar,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-coextensions}@anchor{1c3}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-coextensions}@anchor{1c7}
@subsection No_Coextensions
@@ -12276,7 +12303,7 @@ dependences on package Calendar.
coextensions. See 3.10.2.
@node No_Default_Initialization,No_Delay,No_Coextensions,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-default-initialization}@anchor{1c4}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-default-initialization}@anchor{1c8}
@subsection No_Default_Initialization
@@ -12293,7 +12320,7 @@ is to prohibit all cases of variables declared without a specific
initializer (including the case of OUT scalar parameters).
@node No_Delay,No_Dependence,No_Default_Initialization,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-delay}@anchor{1c5}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-delay}@anchor{1c9}
@subsection No_Delay
@@ -12303,7 +12330,7 @@ initializer (including the case of OUT scalar parameters).
delay statements and no semantic dependences on package Calendar.
@node No_Dependence,No_Direct_Boolean_Operators,No_Delay,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dependence}@anchor{1c6}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dependence}@anchor{1ca}
@subsection No_Dependence
@@ -12313,7 +12340,7 @@ delay statements and no semantic dependences on package Calendar.
dependences on a library unit.
@node No_Direct_Boolean_Operators,No_Dispatch,No_Dependence,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-direct-boolean-operators}@anchor{1c7}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-direct-boolean-operators}@anchor{1cb}
@subsection No_Direct_Boolean_Operators
@@ -12326,7 +12353,7 @@ protocol requires the use of short-circuit (and then, or else) forms for all
composite boolean operations.
@node No_Dispatch,No_Dispatching_Calls,No_Direct_Boolean_Operators,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dispatch}@anchor{1c8}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dispatch}@anchor{1cc}
@subsection No_Dispatch
@@ -12336,7 +12363,7 @@ composite boolean operations.
occurrences of @code{T'Class}, for any (tagged) subtype @code{T}.
@node No_Dispatching_Calls,No_Dynamic_Attachment,No_Dispatch,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dispatching-calls}@anchor{1c9}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dispatching-calls}@anchor{1cd}
@subsection No_Dispatching_Calls
@@ -12397,7 +12424,7 @@ end Example;
@end example
@node No_Dynamic_Attachment,No_Dynamic_Priorities,No_Dispatching_Calls,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-attachment}@anchor{1ca}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-attachment}@anchor{1ce}
@subsection No_Dynamic_Attachment
@@ -12416,7 +12443,7 @@ compatibility purposes (and a warning will be generated for its use if
warnings on obsolescent features are activated).
@node No_Dynamic_Priorities,No_Entry_Calls_In_Elaboration_Code,No_Dynamic_Attachment,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-priorities}@anchor{1cb}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-priorities}@anchor{1cf}
@subsection No_Dynamic_Priorities
@@ -12425,7 +12452,7 @@ warnings on obsolescent features are activated).
[RM D.7] There are no semantic dependencies on the package Dynamic_Priorities.
@node No_Entry_Calls_In_Elaboration_Code,No_Enumeration_Maps,No_Dynamic_Priorities,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-calls-in-elaboration-code}@anchor{1cc}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-calls-in-elaboration-code}@anchor{1d0}
@subsection No_Entry_Calls_In_Elaboration_Code
@@ -12437,7 +12464,7 @@ restriction, the compiler can assume that no code past an accept statement
in a task can be executed at elaboration time.
@node No_Enumeration_Maps,No_Exception_Handlers,No_Entry_Calls_In_Elaboration_Code,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-enumeration-maps}@anchor{1cd}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-enumeration-maps}@anchor{1d1}
@subsection No_Enumeration_Maps
@@ -12448,7 +12475,7 @@ enumeration maps are used (that is Image and Value attributes applied
to enumeration types).
@node No_Exception_Handlers,No_Exception_Propagation,No_Enumeration_Maps,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-handlers}@anchor{1ce}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-handlers}@anchor{1d2}
@subsection No_Exception_Handlers
@@ -12473,7 +12500,7 @@ statement generated by the compiler). The Line parameter when nonzero
represents the line number in the source program where the raise occurs.
@node No_Exception_Propagation,No_Exception_Registration,No_Exception_Handlers,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-propagation}@anchor{1cf}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-propagation}@anchor{1d3}
@subsection No_Exception_Propagation
@@ -12490,7 +12517,7 @@ the package GNAT.Current_Exception is not permitted, and reraise
statements (raise with no operand) are not permitted.
@node No_Exception_Registration,No_Exceptions,No_Exception_Propagation,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-registration}@anchor{1d0}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exception-registration}@anchor{1d4}
@subsection No_Exception_Registration
@@ -12504,7 +12531,7 @@ code is simplified by omitting the otherwise-required global registration
of exceptions when they are declared.
@node No_Exceptions,No_Finalization,No_Exception_Registration,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exceptions}@anchor{1d1}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-exceptions}@anchor{1d5}
@subsection No_Exceptions
@@ -12515,7 +12542,7 @@ raise statements and no exception handlers and also suppresses the
generation of language-defined run-time checks.
@node No_Finalization,No_Fixed_Point,No_Exceptions,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-finalization}@anchor{1d2}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-finalization}@anchor{1d6}
@subsection No_Finalization
@@ -12556,7 +12583,7 @@ object or a nested component, either declared on the stack or on the heap. The
deallocation of a controlled object no longer finalizes its contents.
@node No_Fixed_Point,No_Floating_Point,No_Finalization,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-fixed-point}@anchor{1d3}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-fixed-point}@anchor{1d7}
@subsection No_Fixed_Point
@@ -12566,7 +12593,7 @@ deallocation of a controlled object no longer finalizes its contents.
occurrences of fixed point types and operations.
@node No_Floating_Point,No_Implicit_Conditionals,No_Fixed_Point,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-floating-point}@anchor{1d4}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-floating-point}@anchor{1d8}
@subsection No_Floating_Point
@@ -12576,7 +12603,7 @@ occurrences of fixed point types and operations.
occurrences of floating point types and operations.
@node No_Implicit_Conditionals,No_Implicit_Dynamic_Code,No_Floating_Point,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-conditionals}@anchor{1d5}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-conditionals}@anchor{1d9}
@subsection No_Implicit_Conditionals
@@ -12592,7 +12619,7 @@ normal manner. Constructs generating implicit conditionals include comparisons
of composite objects and the Max/Min attributes.
@node No_Implicit_Dynamic_Code,No_Implicit_Heap_Allocations,No_Implicit_Conditionals,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-dynamic-code}@anchor{1d6}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-dynamic-code}@anchor{1da}
@subsection No_Implicit_Dynamic_Code
@@ -12622,7 +12649,7 @@ foreign-language convention; primitive operations of nested tagged
types.
@node No_Implicit_Heap_Allocations,No_Implicit_Protected_Object_Allocations,No_Implicit_Dynamic_Code,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-heap-allocations}@anchor{1d7}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-heap-allocations}@anchor{1db}
@subsection No_Implicit_Heap_Allocations
@@ -12631,7 +12658,7 @@ types.
[RM D.7] No constructs are allowed to cause implicit heap allocation.
@node No_Implicit_Protected_Object_Allocations,No_Implicit_Task_Allocations,No_Implicit_Heap_Allocations,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-protected-object-allocations}@anchor{1d8}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-protected-object-allocations}@anchor{1dc}
@subsection No_Implicit_Protected_Object_Allocations
@@ -12641,7 +12668,7 @@ types.
protected object.
@node No_Implicit_Task_Allocations,No_Initialize_Scalars,No_Implicit_Protected_Object_Allocations,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-task-allocations}@anchor{1d9}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-task-allocations}@anchor{1dd}
@subsection No_Implicit_Task_Allocations
@@ -12650,7 +12677,7 @@ protected object.
[GNAT] No constructs are allowed to cause implicit heap allocation of a task.
@node No_Initialize_Scalars,No_IO,No_Implicit_Task_Allocations,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-initialize-scalars}@anchor{1da}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-initialize-scalars}@anchor{1de}
@subsection No_Initialize_Scalars
@@ -12662,7 +12689,7 @@ code, and in particular eliminates dummy null initialization routines that
are otherwise generated for some record and array types.
@node No_IO,No_Local_Allocators,No_Initialize_Scalars,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-io}@anchor{1db}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-io}@anchor{1df}
@subsection No_IO
@@ -12673,7 +12700,7 @@ dependences on any of the library units Sequential_IO, Direct_IO,
Text_IO, Wide_Text_IO, Wide_Wide_Text_IO, or Stream_IO.
@node No_Local_Allocators,No_Local_Protected_Objects,No_IO,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-allocators}@anchor{1dc}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-allocators}@anchor{1e0}
@subsection No_Local_Allocators
@@ -12684,7 +12711,7 @@ occurrences of an allocator in subprograms, generic subprograms, tasks,
and entry bodies.
@node No_Local_Protected_Objects,No_Local_Timing_Events,No_Local_Allocators,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-protected-objects}@anchor{1dd}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-protected-objects}@anchor{1e1}
@subsection No_Local_Protected_Objects
@@ -12694,7 +12721,7 @@ and entry bodies.
only declared at the library level.
@node No_Local_Timing_Events,No_Long_Long_Integers,No_Local_Protected_Objects,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-timing-events}@anchor{1de}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-local-timing-events}@anchor{1e2}
@subsection No_Local_Timing_Events
@@ -12704,7 +12731,7 @@ only declared at the library level.
declared at the library level.
@node No_Long_Long_Integers,No_Multiple_Elaboration,No_Local_Timing_Events,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-long-long-integers}@anchor{1df}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-long-long-integers}@anchor{1e3}
@subsection No_Long_Long_Integers
@@ -12716,7 +12743,7 @@ implicit base type is Long_Long_Integer, and modular types whose size exceeds
Long_Integer'Size.
@node No_Multiple_Elaboration,No_Nested_Finalization,No_Long_Long_Integers,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-multiple-elaboration}@anchor{1e0}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-multiple-elaboration}@anchor{1e4}
@subsection No_Multiple_Elaboration
@@ -12732,7 +12759,7 @@ possible, including non-Ada main programs and Stand Alone libraries, are not
permitted and will be diagnosed by the binder.
@node No_Nested_Finalization,No_Protected_Type_Allocators,No_Multiple_Elaboration,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-nested-finalization}@anchor{1e1}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-nested-finalization}@anchor{1e5}
@subsection No_Nested_Finalization
@@ -12741,7 +12768,7 @@ permitted and will be diagnosed by the binder.
[RM D.7] All objects requiring finalization are declared at the library level.
@node No_Protected_Type_Allocators,No_Protected_Types,No_Nested_Finalization,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-protected-type-allocators}@anchor{1e2}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-protected-type-allocators}@anchor{1e6}
@subsection No_Protected_Type_Allocators
@@ -12751,7 +12778,7 @@ permitted and will be diagnosed by the binder.
expressions that attempt to allocate protected objects.
@node No_Protected_Types,No_Recursion,No_Protected_Type_Allocators,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-protected-types}@anchor{1e3}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-protected-types}@anchor{1e7}
@subsection No_Protected_Types
@@ -12761,7 +12788,7 @@ expressions that attempt to allocate protected objects.
declarations of protected types or protected objects.
@node No_Recursion,No_Reentrancy,No_Protected_Types,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-recursion}@anchor{1e4}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-recursion}@anchor{1e8}
@subsection No_Recursion
@@ -12771,7 +12798,7 @@ declarations of protected types or protected objects.
part of its execution.
@node No_Reentrancy,No_Relative_Delay,No_Recursion,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-reentrancy}@anchor{1e5}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-reentrancy}@anchor{1e9}
@subsection No_Reentrancy
@@ -12781,7 +12808,7 @@ part of its execution.
two tasks at the same time.
@node No_Relative_Delay,No_Requeue_Statements,No_Reentrancy,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-relative-delay}@anchor{1e6}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-relative-delay}@anchor{1ea}
@subsection No_Relative_Delay
@@ -12792,7 +12819,7 @@ relative statements and prevents expressions such as @code{delay 1.23;} from
appearing in source code.
@node No_Requeue_Statements,No_Secondary_Stack,No_Relative_Delay,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-requeue-statements}@anchor{1e7}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-requeue-statements}@anchor{1eb}
@subsection No_Requeue_Statements
@@ -12810,7 +12837,7 @@ compatibility purposes (and a warning will be generated for its use if
warnings on oNobsolescent features are activated).
@node No_Secondary_Stack,No_Select_Statements,No_Requeue_Statements,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-secondary-stack}@anchor{1e8}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-secondary-stack}@anchor{1ec}
@subsection No_Secondary_Stack
@@ -12823,7 +12850,7 @@ stack is used to implement functions returning unconstrained objects
secondary stacks for tasks (excluding the environment task) at run time.
@node No_Select_Statements,No_Specific_Termination_Handlers,No_Secondary_Stack,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-select-statements}@anchor{1e9}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-select-statements}@anchor{1ed}
@subsection No_Select_Statements
@@ -12833,7 +12860,7 @@ secondary stacks for tasks (excluding the environment task) at run time.
kind are permitted, that is the keyword @code{select} may not appear.
@node No_Specific_Termination_Handlers,No_Specification_of_Aspect,No_Select_Statements,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-specific-termination-handlers}@anchor{1ea}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-specific-termination-handlers}@anchor{1ee}
@subsection No_Specific_Termination_Handlers
@@ -12843,7 +12870,7 @@ kind are permitted, that is the keyword @code{select} may not appear.
or to Ada.Task_Termination.Specific_Handler.
@node No_Specification_of_Aspect,No_Standard_Allocators_After_Elaboration,No_Specific_Termination_Handlers,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-specification-of-aspect}@anchor{1eb}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-specification-of-aspect}@anchor{1ef}
@subsection No_Specification_of_Aspect
@@ -12854,7 +12881,7 @@ specification, attribute definition clause, or pragma is given for a
given aspect.
@node No_Standard_Allocators_After_Elaboration,No_Standard_Storage_Pools,No_Specification_of_Aspect,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-standard-allocators-after-elaboration}@anchor{1ec}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-standard-allocators-after-elaboration}@anchor{1f0}
@subsection No_Standard_Allocators_After_Elaboration
@@ -12866,7 +12893,7 @@ library items of the partition has completed. Otherwise, Storage_Error
is raised.
@node No_Standard_Storage_Pools,No_Stream_Optimizations,No_Standard_Allocators_After_Elaboration,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-standard-storage-pools}@anchor{1ed}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-standard-storage-pools}@anchor{1f1}
@subsection No_Standard_Storage_Pools
@@ -12878,7 +12905,7 @@ have an explicit Storage_Pool attribute defined specifying a
user-defined storage pool.
@node No_Stream_Optimizations,No_Streams,No_Standard_Storage_Pools,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-stream-optimizations}@anchor{1ee}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-stream-optimizations}@anchor{1f2}
@subsection No_Stream_Optimizations
@@ -12891,7 +12918,7 @@ due to their superior performance. When this restriction is in effect, the
compiler performs all IO operations on a per-character basis.
@node No_Streams,No_Task_Allocators,No_Stream_Optimizations,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-streams}@anchor{1ef}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-streams}@anchor{1f3}
@subsection No_Streams
@@ -12912,7 +12939,7 @@ unit declaring a tagged type should be compiled with the restriction,
though this is not required.
@node No_Task_Allocators,No_Task_At_Interrupt_Priority,No_Streams,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-allocators}@anchor{1f0}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-allocators}@anchor{1f4}
@subsection No_Task_Allocators
@@ -12922,7 +12949,7 @@ though this is not required.
or types containing task subcomponents.
@node No_Task_At_Interrupt_Priority,No_Task_Attributes_Package,No_Task_Allocators,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-at-interrupt-priority}@anchor{1f1}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-at-interrupt-priority}@anchor{1f5}
@subsection No_Task_At_Interrupt_Priority
@@ -12934,7 +12961,7 @@ a consequence, the tasks are always created with a priority below
that an interrupt priority.
@node No_Task_Attributes_Package,No_Task_Hierarchy,No_Task_At_Interrupt_Priority,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-attributes-package}@anchor{1f2}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-attributes-package}@anchor{1f6}
@subsection No_Task_Attributes_Package
@@ -12951,7 +12978,7 @@ compatibility purposes (and a warning will be generated for its use if
warnings on obsolescent features are activated).
@node No_Task_Hierarchy,No_Task_Termination,No_Task_Attributes_Package,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-hierarchy}@anchor{1f3}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-hierarchy}@anchor{1f7}
@subsection No_Task_Hierarchy
@@ -12961,7 +12988,7 @@ warnings on obsolescent features are activated).
directly on the environment task of the partition.
@node No_Task_Termination,No_Tasking,No_Task_Hierarchy,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-termination}@anchor{1f4}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-task-termination}@anchor{1f8}
@subsection No_Task_Termination
@@ -12970,7 +12997,7 @@ directly on the environment task of the partition.
[RM D.7] Tasks that terminate are erroneous.
@node No_Tasking,No_Terminate_Alternatives,No_Task_Termination,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-tasking}@anchor{1f5}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-tasking}@anchor{1f9}
@subsection No_Tasking
@@ -12983,7 +13010,7 @@ and cause an error message to be output either by the compiler or
binder.
@node No_Terminate_Alternatives,No_Unchecked_Access,No_Tasking,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-terminate-alternatives}@anchor{1f6}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-terminate-alternatives}@anchor{1fa}
@subsection No_Terminate_Alternatives
@@ -12992,7 +13019,7 @@ binder.
[RM D.7] There are no selective accepts with terminate alternatives.
@node No_Unchecked_Access,No_Unchecked_Conversion,No_Terminate_Alternatives,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-access}@anchor{1f7}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-access}@anchor{1fb}
@subsection No_Unchecked_Access
@@ -13002,7 +13029,7 @@ binder.
occurrences of the Unchecked_Access attribute.
@node No_Unchecked_Conversion,No_Unchecked_Deallocation,No_Unchecked_Access,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-conversion}@anchor{1f8}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-conversion}@anchor{1fc}
@subsection No_Unchecked_Conversion
@@ -13012,7 +13039,7 @@ occurrences of the Unchecked_Access attribute.
dependences on the predefined generic function Unchecked_Conversion.
@node No_Unchecked_Deallocation,No_Use_Of_Entity,No_Unchecked_Conversion,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-deallocation}@anchor{1f9}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-unchecked-deallocation}@anchor{1fd}
@subsection No_Unchecked_Deallocation
@@ -13022,7 +13049,7 @@ dependences on the predefined generic function Unchecked_Conversion.
dependences on the predefined generic procedure Unchecked_Deallocation.
@node No_Use_Of_Entity,Pure_Barriers,No_Unchecked_Deallocation,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-use-of-entity}@anchor{1fa}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-use-of-entity}@anchor{1fe}
@subsection No_Use_Of_Entity
@@ -13042,7 +13069,7 @@ No_Use_Of_Entity => Ada.Text_IO.Put_Line
@end example
@node Pure_Barriers,Simple_Barriers,No_Use_Of_Entity,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions pure-barriers}@anchor{1fb}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions pure-barriers}@anchor{1ff}
@subsection Pure_Barriers
@@ -13093,7 +13120,7 @@ but still ensures absence of side effects, exceptions, and recursion
during the evaluation of the barriers.
@node Simple_Barriers,Static_Priorities,Pure_Barriers,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions simple-barriers}@anchor{1fc}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions simple-barriers}@anchor{200}
@subsection Simple_Barriers
@@ -13112,7 +13139,7 @@ compatibility purposes (and a warning will be generated for its use if
warnings on obsolescent features are activated).
@node Static_Priorities,Static_Storage_Size,Simple_Barriers,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-priorities}@anchor{1fd}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-priorities}@anchor{201}
@subsection Static_Priorities
@@ -13123,7 +13150,7 @@ are static, and that there are no dependences on the package
@code{Ada.Dynamic_Priorities}.
@node Static_Storage_Size,,Static_Priorities,Partition-Wide Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-storage-size}@anchor{1fe}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-storage-size}@anchor{202}
@subsection Static_Storage_Size
@@ -13133,7 +13160,7 @@ are static, and that there are no dependences on the package
in a Storage_Size pragma or attribute definition clause is static.
@node Program Unit Level Restrictions,,Partition-Wide Restrictions,Standard and Implementation Defined Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions program-unit-level-restrictions}@anchor{1ff}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id3}@anchor{200}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions program-unit-level-restrictions}@anchor{203}@anchor{gnat_rm/standard_and_implementation_defined_restrictions id3}@anchor{204}
@section Program Unit Level Restrictions
@@ -13163,7 +13190,7 @@ other compilation units in the partition.
@end menu
@node No_Elaboration_Code,No_Dynamic_Sized_Objects,,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-elaboration-code}@anchor{201}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-elaboration-code}@anchor{205}
@subsection No_Elaboration_Code
@@ -13219,7 +13246,7 @@ associated with the unit. This counter is typically used to check for access
before elaboration and to control multiple elaboration attempts.
@node No_Dynamic_Sized_Objects,No_Entry_Queue,No_Elaboration_Code,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-sized-objects}@anchor{202}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-dynamic-sized-objects}@anchor{206}
@subsection No_Dynamic_Sized_Objects
@@ -13237,7 +13264,7 @@ access discriminants. It is often a good idea to combine this restriction
with No_Secondary_Stack.
@node No_Entry_Queue,No_Implementation_Aspect_Specifications,No_Dynamic_Sized_Objects,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-queue}@anchor{203}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-entry-queue}@anchor{207}
@subsection No_Entry_Queue
@@ -13250,7 +13277,7 @@ checked at compile time. A program execution is erroneous if an attempt
is made to queue a second task on such an entry.
@node No_Implementation_Aspect_Specifications,No_Implementation_Attributes,No_Entry_Queue,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-aspect-specifications}@anchor{204}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-aspect-specifications}@anchor{208}
@subsection No_Implementation_Aspect_Specifications
@@ -13261,7 +13288,7 @@ GNAT-defined aspects are present. With this restriction, the only
aspects that can be used are those defined in the Ada Reference Manual.
@node No_Implementation_Attributes,No_Implementation_Identifiers,No_Implementation_Aspect_Specifications,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-attributes}@anchor{205}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-attributes}@anchor{209}
@subsection No_Implementation_Attributes
@@ -13273,7 +13300,7 @@ attributes that can be used are those defined in the Ada Reference
Manual.
@node No_Implementation_Identifiers,No_Implementation_Pragmas,No_Implementation_Attributes,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-identifiers}@anchor{206}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-identifiers}@anchor{20a}
@subsection No_Implementation_Identifiers
@@ -13284,7 +13311,7 @@ implementation-defined identifiers (marked with pragma Implementation_Defined)
occur within language-defined packages.
@node No_Implementation_Pragmas,No_Implementation_Restrictions,No_Implementation_Identifiers,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-pragmas}@anchor{207}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-pragmas}@anchor{20b}
@subsection No_Implementation_Pragmas
@@ -13295,7 +13322,7 @@ GNAT-defined pragmas are present. With this restriction, the only
pragmas that can be used are those defined in the Ada Reference Manual.
@node No_Implementation_Restrictions,No_Implementation_Units,No_Implementation_Pragmas,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-restrictions}@anchor{208}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-restrictions}@anchor{20c}
@subsection No_Implementation_Restrictions
@@ -13307,7 +13334,7 @@ are present. With this restriction, the only other restriction identifiers
that can be used are those defined in the Ada Reference Manual.
@node No_Implementation_Units,No_Implicit_Aliasing,No_Implementation_Restrictions,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-units}@anchor{209}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implementation-units}@anchor{20d}
@subsection No_Implementation_Units
@@ -13318,7 +13345,7 @@ mention in the context clause of any implementation-defined descendants
of packages Ada, Interfaces, or System.
@node No_Implicit_Aliasing,No_Implicit_Loops,No_Implementation_Units,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-aliasing}@anchor{20a}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-aliasing}@anchor{20e}
@subsection No_Implicit_Aliasing
@@ -13333,7 +13360,7 @@ to be aliased, and in such cases, it can always be replaced by
the standard attribute Unchecked_Access which is preferable.
@node No_Implicit_Loops,No_Obsolescent_Features,No_Implicit_Aliasing,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-loops}@anchor{20b}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-implicit-loops}@anchor{20f}
@subsection No_Implicit_Loops
@@ -13350,7 +13377,7 @@ arrays larger than about 5000 scalar components. Note that if this restriction
is set in the spec of a package, it will not apply to its body.
@node No_Obsolescent_Features,No_Wide_Characters,No_Implicit_Loops,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-obsolescent-features}@anchor{20c}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-obsolescent-features}@anchor{210}
@subsection No_Obsolescent_Features
@@ -13360,7 +13387,7 @@ is set in the spec of a package, it will not apply to its body.
features are used, as defined in Annex J of the Ada Reference Manual.
@node No_Wide_Characters,Static_Dispatch_Tables,No_Obsolescent_Features,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-wide-characters}@anchor{20d}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions no-wide-characters}@anchor{211}
@subsection No_Wide_Characters
@@ -13374,7 +13401,7 @@ appear in the program (that is literals representing characters not in
type @code{Character}).
@node Static_Dispatch_Tables,SPARK_05,No_Wide_Characters,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-dispatch-tables}@anchor{20e}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions static-dispatch-tables}@anchor{212}
@subsection Static_Dispatch_Tables
@@ -13384,7 +13411,7 @@ type @code{Character}).
associated with dispatch tables can be placed in read-only memory.
@node SPARK_05,,Static_Dispatch_Tables,Program Unit Level Restrictions
-@anchor{gnat_rm/standard_and_implementation_defined_restrictions spark-05}@anchor{20f}
+@anchor{gnat_rm/standard_and_implementation_defined_restrictions spark-05}@anchor{213}
@subsection SPARK_05
@@ -13758,7 +13785,7 @@ violations will be reported for constructs forbidden in SPARK 95,
instead of SPARK 2005.
@node Implementation Advice,Implementation Defined Characteristics,Standard and Implementation Defined Restrictions,Top
-@anchor{gnat_rm/implementation_advice doc}@anchor{210}@anchor{gnat_rm/implementation_advice implementation-advice}@anchor{a}@anchor{gnat_rm/implementation_advice id1}@anchor{211}
+@anchor{gnat_rm/implementation_advice doc}@anchor{214}@anchor{gnat_rm/implementation_advice implementation-advice}@anchor{a}@anchor{gnat_rm/implementation_advice id1}@anchor{215}
@chapter Implementation Advice
@@ -13818,7 +13845,7 @@ case the text describes what GNAT does and why.
* RM 13.9(14-17); Unchecked Conversion: RM 13 9 14-17 Unchecked Conversion.
* RM 13.11(23-25); Implicit Heap Usage: RM 13 11 23-25 Implicit Heap Usage.
* RM 13.11.2(17); Unchecked Deallocation: RM 13 11 2 17 Unchecked Deallocation.
-* RM 13.13.2(17); Stream Oriented Attributes: RM 13 13 2 17 Stream Oriented Attributes.
+* RM 13.13.2(1.6); Stream Oriented Attributes: RM 13 13 2 1 6 Stream Oriented Attributes.
* RM A.1(52); Names of Predefined Numeric Types: RM A 1 52 Names of Predefined Numeric Types.
* RM A.3.2(49); Ada.Characters.Handling: RM A 3 2 49 Ada Characters Handling.
* RM A.4.4(106); Bounded-Length String Handling: RM A 4 4 106 Bounded-Length String Handling.
@@ -13855,7 +13882,7 @@ case the text describes what GNAT does and why.
@end menu
@node RM 1 1 3 20 Error Detection,RM 1 1 3 31 Child Units,,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-1-1-3-20-error-detection}@anchor{212}
+@anchor{gnat_rm/implementation_advice rm-1-1-3-20-error-detection}@anchor{216}
@section RM 1.1.3(20): Error Detection
@@ -13872,7 +13899,7 @@ or diagnosed at compile time.
@geindex Child Units
@node RM 1 1 3 31 Child Units,RM 1 1 5 12 Bounded Errors,RM 1 1 3 20 Error Detection,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-1-1-3-31-child-units}@anchor{213}
+@anchor{gnat_rm/implementation_advice rm-1-1-3-31-child-units}@anchor{217}
@section RM 1.1.3(31): Child Units
@@ -13888,7 +13915,7 @@ Followed.
@geindex Bounded errors
@node RM 1 1 5 12 Bounded Errors,RM 2 8 16 Pragmas,RM 1 1 3 31 Child Units,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-1-1-5-12-bounded-errors}@anchor{214}
+@anchor{gnat_rm/implementation_advice rm-1-1-5-12-bounded-errors}@anchor{218}
@section RM 1.1.5(12): Bounded Errors
@@ -13905,7 +13932,7 @@ runtime.
@geindex Pragmas
@node RM 2 8 16 Pragmas,RM 2 8 17-19 Pragmas,RM 1 1 5 12 Bounded Errors,Implementation Advice
-@anchor{gnat_rm/implementation_advice id2}@anchor{215}@anchor{gnat_rm/implementation_advice rm-2-8-16-pragmas}@anchor{216}
+@anchor{gnat_rm/implementation_advice id2}@anchor{219}@anchor{gnat_rm/implementation_advice rm-2-8-16-pragmas}@anchor{21a}
@section RM 2.8(16): Pragmas
@@ -14018,7 +14045,7 @@ that this advice not be followed. For details see
@ref{7,,Implementation Defined Pragmas}.
@node RM 2 8 17-19 Pragmas,RM 3 5 2 5 Alternative Character Sets,RM 2 8 16 Pragmas,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-2-8-17-19-pragmas}@anchor{217}
+@anchor{gnat_rm/implementation_advice rm-2-8-17-19-pragmas}@anchor{21b}
@section RM 2.8(17-19): Pragmas
@@ -14039,14 +14066,14 @@ replacing @code{library_items}."
@end itemize
@end quotation
-See @ref{216,,RM 2.8(16); Pragmas}.
+See @ref{21a,,RM 2.8(16); Pragmas}.
@geindex Character Sets
@geindex Alternative Character Sets
@node RM 3 5 2 5 Alternative Character Sets,RM 3 5 4 28 Integer Types,RM 2 8 17-19 Pragmas,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-3-5-2-5-alternative-character-sets}@anchor{218}
+@anchor{gnat_rm/implementation_advice rm-3-5-2-5-alternative-character-sets}@anchor{21c}
@section RM 3.5.2(5): Alternative Character Sets
@@ -14074,7 +14101,7 @@ there is no such restriction.
@geindex Integer types
@node RM 3 5 4 28 Integer Types,RM 3 5 4 29 Integer Types,RM 3 5 2 5 Alternative Character Sets,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-3-5-4-28-integer-types}@anchor{219}
+@anchor{gnat_rm/implementation_advice rm-3-5-4-28-integer-types}@anchor{21d}
@section RM 3.5.4(28): Integer Types
@@ -14093,7 +14120,7 @@ are supported for convenient interface to C, and so that all hardware
types of the machine are easily available.
@node RM 3 5 4 29 Integer Types,RM 3 5 5 8 Enumeration Values,RM 3 5 4 28 Integer Types,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-3-5-4-29-integer-types}@anchor{21a}
+@anchor{gnat_rm/implementation_advice rm-3-5-4-29-integer-types}@anchor{21e}
@section RM 3.5.4(29): Integer Types
@@ -14109,7 +14136,7 @@ Followed.
@geindex Enumeration values
@node RM 3 5 5 8 Enumeration Values,RM 3 5 7 17 Float Types,RM 3 5 4 29 Integer Types,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-3-5-5-8-enumeration-values}@anchor{21b}
+@anchor{gnat_rm/implementation_advice rm-3-5-5-8-enumeration-values}@anchor{21f}
@section RM 3.5.5(8): Enumeration Values
@@ -14129,7 +14156,7 @@ Followed.
@geindex Float types
@node RM 3 5 7 17 Float Types,RM 3 6 2 11 Multidimensional Arrays,RM 3 5 5 8 Enumeration Values,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-3-5-7-17-float-types}@anchor{21c}
+@anchor{gnat_rm/implementation_advice rm-3-5-7-17-float-types}@anchor{220}
@section RM 3.5.7(17): Float Types
@@ -14159,7 +14186,7 @@ since this is a software rather than a hardware format.
@geindex multidimensional
@node RM 3 6 2 11 Multidimensional Arrays,RM 9 6 30-31 Duration'Small,RM 3 5 7 17 Float Types,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-3-6-2-11-multidimensional-arrays}@anchor{21d}
+@anchor{gnat_rm/implementation_advice rm-3-6-2-11-multidimensional-arrays}@anchor{221}
@section RM 3.6.2(11): Multidimensional Arrays
@@ -14177,7 +14204,7 @@ Followed.
@geindex Duration'Small
@node RM 9 6 30-31 Duration'Small,RM 10 2 1 12 Consistent Representation,RM 3 6 2 11 Multidimensional Arrays,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-9-6-30-31-duration-small}@anchor{21e}
+@anchor{gnat_rm/implementation_advice rm-9-6-30-31-duration-small}@anchor{222}
@section RM 9.6(30-31): Duration'Small
@@ -14198,7 +14225,7 @@ it need not be the same time base as used for @code{Calendar.Clock}."
Followed.
@node RM 10 2 1 12 Consistent Representation,RM 11 4 1 19 Exception Information,RM 9 6 30-31 Duration'Small,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-10-2-1-12-consistent-representation}@anchor{21f}
+@anchor{gnat_rm/implementation_advice rm-10-2-1-12-consistent-representation}@anchor{223}
@section RM 10.2.1(12): Consistent Representation
@@ -14220,7 +14247,7 @@ advice without severely impacting efficiency of execution.
@geindex Exception information
@node RM 11 4 1 19 Exception Information,RM 11 5 28 Suppression of Checks,RM 10 2 1 12 Consistent Representation,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-11-4-1-19-exception-information}@anchor{220}
+@anchor{gnat_rm/implementation_advice rm-11-4-1-19-exception-information}@anchor{224}
@section RM 11.4.1(19): Exception Information
@@ -14251,7 +14278,7 @@ Pragma @code{Discard_Names}.
@geindex suppression of
@node RM 11 5 28 Suppression of Checks,RM 13 1 21-24 Representation Clauses,RM 11 4 1 19 Exception Information,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-11-5-28-suppression-of-checks}@anchor{221}
+@anchor{gnat_rm/implementation_advice rm-11-5-28-suppression-of-checks}@anchor{225}
@section RM 11.5(28): Suppression of Checks
@@ -14266,7 +14293,7 @@ Followed.
@geindex Representation clauses
@node RM 13 1 21-24 Representation Clauses,RM 13 2 6-8 Packed Types,RM 11 5 28 Suppression of Checks,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-1-21-24-representation-clauses}@anchor{222}
+@anchor{gnat_rm/implementation_advice rm-13-1-21-24-representation-clauses}@anchor{226}
@section RM 13.1 (21-24): Representation Clauses
@@ -14315,7 +14342,7 @@ Followed.
@geindex Packed types
@node RM 13 2 6-8 Packed Types,RM 13 3 14-19 Address Clauses,RM 13 1 21-24 Representation Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-2-6-8-packed-types}@anchor{223}
+@anchor{gnat_rm/implementation_advice rm-13-2-6-8-packed-types}@anchor{227}
@section RM 13.2(6-8): Packed Types
@@ -14354,7 +14381,7 @@ Followed.
@geindex Address clauses
@node RM 13 3 14-19 Address Clauses,RM 13 3 29-35 Alignment Clauses,RM 13 2 6-8 Packed Types,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-3-14-19-address-clauses}@anchor{224}
+@anchor{gnat_rm/implementation_advice rm-13-3-14-19-address-clauses}@anchor{228}
@section RM 13.3(14-19): Address Clauses
@@ -14407,7 +14434,7 @@ Followed.
@geindex Alignment clauses
@node RM 13 3 29-35 Alignment Clauses,RM 13 3 42-43 Size Clauses,RM 13 3 14-19 Address Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-3-29-35-alignment-clauses}@anchor{225}
+@anchor{gnat_rm/implementation_advice rm-13-3-29-35-alignment-clauses}@anchor{229}
@section RM 13.3(29-35): Alignment Clauses
@@ -14464,7 +14491,7 @@ Followed.
@geindex Size clauses
@node RM 13 3 42-43 Size Clauses,RM 13 3 50-56 Size Clauses,RM 13 3 29-35 Alignment Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-3-42-43-size-clauses}@anchor{226}
+@anchor{gnat_rm/implementation_advice rm-13-3-42-43-size-clauses}@anchor{22a}
@section RM 13.3(42-43): Size Clauses
@@ -14482,7 +14509,7 @@ object's @code{Alignment} (if the @code{Alignment} is nonzero)."
Followed.
@node RM 13 3 50-56 Size Clauses,RM 13 3 71-73 Component Size Clauses,RM 13 3 42-43 Size Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-3-50-56-size-clauses}@anchor{227}
+@anchor{gnat_rm/implementation_advice rm-13-3-50-56-size-clauses}@anchor{22b}
@section RM 13.3(50-56): Size Clauses
@@ -14533,7 +14560,7 @@ Followed.
@geindex Component_Size clauses
@node RM 13 3 71-73 Component Size Clauses,RM 13 4 9-10 Enumeration Representation Clauses,RM 13 3 50-56 Size Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-3-71-73-component-size-clauses}@anchor{228}
+@anchor{gnat_rm/implementation_advice rm-13-3-71-73-component-size-clauses}@anchor{22c}
@section RM 13.3(71-73): Component Size Clauses
@@ -14567,7 +14594,7 @@ Followed.
@geindex enumeration
@node RM 13 4 9-10 Enumeration Representation Clauses,RM 13 5 1 17-22 Record Representation Clauses,RM 13 3 71-73 Component Size Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-4-9-10-enumeration-representation-clauses}@anchor{229}
+@anchor{gnat_rm/implementation_advice rm-13-4-9-10-enumeration-representation-clauses}@anchor{22d}
@section RM 13.4(9-10): Enumeration Representation Clauses
@@ -14589,7 +14616,7 @@ Followed.
@geindex records
@node RM 13 5 1 17-22 Record Representation Clauses,RM 13 5 2 5 Storage Place Attributes,RM 13 4 9-10 Enumeration Representation Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-5-1-17-22-record-representation-clauses}@anchor{22a}
+@anchor{gnat_rm/implementation_advice rm-13-5-1-17-22-record-representation-clauses}@anchor{22e}
@section RM 13.5.1(17-22): Record Representation Clauses
@@ -14649,7 +14676,7 @@ and all mentioned features are implemented.
@geindex Storage place attributes
@node RM 13 5 2 5 Storage Place Attributes,RM 13 5 3 7-8 Bit Ordering,RM 13 5 1 17-22 Record Representation Clauses,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-5-2-5-storage-place-attributes}@anchor{22b}
+@anchor{gnat_rm/implementation_advice rm-13-5-2-5-storage-place-attributes}@anchor{22f}
@section RM 13.5.2(5): Storage Place Attributes
@@ -14669,7 +14696,7 @@ Followed. There are no such components in GNAT.
@geindex Bit ordering
@node RM 13 5 3 7-8 Bit Ordering,RM 13 7 37 Address as Private,RM 13 5 2 5 Storage Place Attributes,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-5-3-7-8-bit-ordering}@anchor{22c}
+@anchor{gnat_rm/implementation_advice rm-13-5-3-7-8-bit-ordering}@anchor{230}
@section RM 13.5.3(7-8): Bit Ordering
@@ -14689,7 +14716,7 @@ Thus non-default bit ordering is not supported.
@geindex as private type
@node RM 13 7 37 Address as Private,RM 13 7 1 16 Address Operations,RM 13 5 3 7-8 Bit Ordering,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-7-37-address-as-private}@anchor{22d}
+@anchor{gnat_rm/implementation_advice rm-13-7-37-address-as-private}@anchor{231}
@section RM 13.7(37): Address as Private
@@ -14707,7 +14734,7 @@ Followed.
@geindex operations of
@node RM 13 7 1 16 Address Operations,RM 13 9 14-17 Unchecked Conversion,RM 13 7 37 Address as Private,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-7-1-16-address-operations}@anchor{22e}
+@anchor{gnat_rm/implementation_advice rm-13-7-1-16-address-operations}@anchor{232}
@section RM 13.7.1(16): Address Operations
@@ -14725,7 +14752,7 @@ operation raises @code{Program_Error}, since all operations make sense.
@geindex Unchecked conversion
@node RM 13 9 14-17 Unchecked Conversion,RM 13 11 23-25 Implicit Heap Usage,RM 13 7 1 16 Address Operations,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-9-14-17-unchecked-conversion}@anchor{22f}
+@anchor{gnat_rm/implementation_advice rm-13-9-14-17-unchecked-conversion}@anchor{233}
@section RM 13.9(14-17): Unchecked Conversion
@@ -14769,7 +14796,7 @@ Followed.
@geindex implicit
@node RM 13 11 23-25 Implicit Heap Usage,RM 13 11 2 17 Unchecked Deallocation,RM 13 9 14-17 Unchecked Conversion,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-11-23-25-implicit-heap-usage}@anchor{230}
+@anchor{gnat_rm/implementation_advice rm-13-11-23-25-implicit-heap-usage}@anchor{234}
@section RM 13.11(23-25): Implicit Heap Usage
@@ -14819,8 +14846,8 @@ Followed.
@geindex Unchecked deallocation
-@node RM 13 11 2 17 Unchecked Deallocation,RM 13 13 2 17 Stream Oriented Attributes,RM 13 11 23-25 Implicit Heap Usage,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-11-2-17-unchecked-deallocation}@anchor{231}
+@node RM 13 11 2 17 Unchecked Deallocation,RM 13 13 2 1 6 Stream Oriented Attributes,RM 13 11 23-25 Implicit Heap Usage,Implementation Advice
+@anchor{gnat_rm/implementation_advice rm-13-11-2-17-unchecked-deallocation}@anchor{235}
@section RM 13.11.2(17): Unchecked Deallocation
@@ -14834,28 +14861,28 @@ Followed.
@geindex Stream oriented attributes
-@node RM 13 13 2 17 Stream Oriented Attributes,RM A 1 52 Names of Predefined Numeric Types,RM 13 11 2 17 Unchecked Deallocation,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-13-13-2-17-stream-oriented-attributes}@anchor{232}
-@section RM 13.13.2(17): Stream Oriented Attributes
+@node RM 13 13 2 1 6 Stream Oriented Attributes,RM A 1 52 Names of Predefined Numeric Types,RM 13 11 2 17 Unchecked Deallocation,Implementation Advice
+@anchor{gnat_rm/implementation_advice rm-13-13-2-1-6-stream-oriented-attributes}@anchor{236}
+@section RM 13.13.2(1.6): Stream Oriented Attributes
@quotation
-"If a stream element is the same size as a storage element, then the
-normal in-memory representation should be used by @code{Read} and
-@code{Write} for scalar objects. Otherwise, @code{Read} and @code{Write}
-should use the smallest number of stream elements needed to represent
-all values in the base range of the scalar type."
+"If not specified, the value of Stream_Size for an elementary type
+should be the number of bits that corresponds to the minimum number of
+stream elements required by the first subtype of the type, rounded up
+to the nearest factor or multiple of the word size that is also a
+multiple of the stream element size."
@end quotation
-Followed. By default, GNAT uses the interpretation suggested by AI-195,
-which specifies using the size of the first subtype.
+Followed, except that the number of stream elements is a power of 2.
+The Stream_Size may be used to override the default choice.
+
However, such an implementation is based on direct binary
-representations and is therefore target- and endianness-dependent.
-To address this issue, GNAT also supplies an alternate implementation
-of the stream attributes @code{Read} and @code{Write},
-which uses the target-independent XDR standard representation
-for scalar types.
+representations and is therefore target- and endianness-dependent. To
+address this issue, GNAT also supplies an alternate implementation of
+the stream attributes @code{Read} and @code{Write}, which uses the
+target-independent XDR standard representation for scalar types.
@geindex XDR representation
@@ -14889,8 +14916,8 @@ Rebuild the GNAT run-time library as documented in
the @emph{GNAT and Libraries} section of the @cite{GNAT User's Guide}.
@end itemize
-@node RM A 1 52 Names of Predefined Numeric Types,RM A 3 2 49 Ada Characters Handling,RM 13 13 2 17 Stream Oriented Attributes,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-a-1-52-names-of-predefined-numeric-types}@anchor{233}
+@node RM A 1 52 Names of Predefined Numeric Types,RM A 3 2 49 Ada Characters Handling,RM 13 13 2 1 6 Stream Oriented Attributes,Implementation Advice
+@anchor{gnat_rm/implementation_advice rm-a-1-52-names-of-predefined-numeric-types}@anchor{237}
@section RM A.1(52): Names of Predefined Numeric Types
@@ -14908,7 +14935,7 @@ Followed.
@geindex Ada.Characters.Handling
@node RM A 3 2 49 Ada Characters Handling,RM A 4 4 106 Bounded-Length String Handling,RM A 1 52 Names of Predefined Numeric Types,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-a-3-2-49-ada-characters-handling}@anchor{234}
+@anchor{gnat_rm/implementation_advice rm-a-3-2-49-ada-characters-handling}@anchor{238}
@section RM A.3.2(49): @code{Ada.Characters.Handling}
@@ -14925,7 +14952,7 @@ Followed. GNAT provides no such localized definitions.
@geindex Bounded-length strings
@node RM A 4 4 106 Bounded-Length String Handling,RM A 5 2 46-47 Random Number Generation,RM A 3 2 49 Ada Characters Handling,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-a-4-4-106-bounded-length-string-handling}@anchor{235}
+@anchor{gnat_rm/implementation_advice rm-a-4-4-106-bounded-length-string-handling}@anchor{239}
@section RM A.4.4(106): Bounded-Length String Handling
@@ -14940,7 +14967,7 @@ Followed. No implicit pointers or dynamic allocation are used.
@geindex Random number generation
@node RM A 5 2 46-47 Random Number Generation,RM A 10 7 23 Get_Immediate,RM A 4 4 106 Bounded-Length String Handling,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-a-5-2-46-47-random-number-generation}@anchor{236}
+@anchor{gnat_rm/implementation_advice rm-a-5-2-46-47-random-number-generation}@anchor{23a}
@section RM A.5.2(46-47): Random Number Generation
@@ -14969,7 +14996,7 @@ condition here to hold true.
@geindex Get_Immediate
@node RM A 10 7 23 Get_Immediate,RM B 1 39-41 Pragma Export,RM A 5 2 46-47 Random Number Generation,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-a-10-7-23-get-immediate}@anchor{237}
+@anchor{gnat_rm/implementation_advice rm-a-10-7-23-get-immediate}@anchor{23b}
@section RM A.10.7(23): @code{Get_Immediate}
@@ -14993,7 +15020,7 @@ this functionality.
@geindex Export
@node RM B 1 39-41 Pragma Export,RM B 2 12-13 Package Interfaces,RM A 10 7 23 Get_Immediate,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-b-1-39-41-pragma-export}@anchor{238}
+@anchor{gnat_rm/implementation_advice rm-b-1-39-41-pragma-export}@anchor{23c}
@section RM B.1(39-41): Pragma @code{Export}
@@ -15041,7 +15068,7 @@ Followed.
@geindex Interfaces
@node RM B 2 12-13 Package Interfaces,RM B 3 63-71 Interfacing with C,RM B 1 39-41 Pragma Export,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-b-2-12-13-package-interfaces}@anchor{239}
+@anchor{gnat_rm/implementation_advice rm-b-2-12-13-package-interfaces}@anchor{23d}
@section RM B.2(12-13): Package @code{Interfaces}
@@ -15071,7 +15098,7 @@ Followed. GNAT provides all the packages described in this section.
@geindex interfacing with
@node RM B 3 63-71 Interfacing with C,RM B 4 95-98 Interfacing with COBOL,RM B 2 12-13 Package Interfaces,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-b-3-63-71-interfacing-with-c}@anchor{23a}
+@anchor{gnat_rm/implementation_advice rm-b-3-63-71-interfacing-with-c}@anchor{23e}
@section RM B.3(63-71): Interfacing with C
@@ -15159,7 +15186,7 @@ Followed.
@geindex interfacing with
@node RM B 4 95-98 Interfacing with COBOL,RM B 5 22-26 Interfacing with Fortran,RM B 3 63-71 Interfacing with C,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-b-4-95-98-interfacing-with-cobol}@anchor{23b}
+@anchor{gnat_rm/implementation_advice rm-b-4-95-98-interfacing-with-cobol}@anchor{23f}
@section RM B.4(95-98): Interfacing with COBOL
@@ -15200,7 +15227,7 @@ Followed.
@geindex interfacing with
@node RM B 5 22-26 Interfacing with Fortran,RM C 1 3-5 Access to Machine Operations,RM B 4 95-98 Interfacing with COBOL,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-b-5-22-26-interfacing-with-fortran}@anchor{23c}
+@anchor{gnat_rm/implementation_advice rm-b-5-22-26-interfacing-with-fortran}@anchor{240}
@section RM B.5(22-26): Interfacing with Fortran
@@ -15251,7 +15278,7 @@ Followed.
@geindex Machine operations
@node RM C 1 3-5 Access to Machine Operations,RM C 1 10-16 Access to Machine Operations,RM B 5 22-26 Interfacing with Fortran,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-1-3-5-access-to-machine-operations}@anchor{23d}
+@anchor{gnat_rm/implementation_advice rm-c-1-3-5-access-to-machine-operations}@anchor{241}
@section RM C.1(3-5): Access to Machine Operations
@@ -15286,7 +15313,7 @@ object that is specified as exported."
Followed.
@node RM C 1 10-16 Access to Machine Operations,RM C 3 28 Interrupt Support,RM C 1 3-5 Access to Machine Operations,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-1-10-16-access-to-machine-operations}@anchor{23e}
+@anchor{gnat_rm/implementation_advice rm-c-1-10-16-access-to-machine-operations}@anchor{242}
@section RM C.1(10-16): Access to Machine Operations
@@ -15347,7 +15374,7 @@ Followed on any target supporting such operations.
@geindex Interrupt support
@node RM C 3 28 Interrupt Support,RM C 3 1 20-21 Protected Procedure Handlers,RM C 1 10-16 Access to Machine Operations,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-3-28-interrupt-support}@anchor{23f}
+@anchor{gnat_rm/implementation_advice rm-c-3-28-interrupt-support}@anchor{243}
@section RM C.3(28): Interrupt Support
@@ -15365,7 +15392,7 @@ of interrupt blocking.
@geindex Protected procedure handlers
@node RM C 3 1 20-21 Protected Procedure Handlers,RM C 3 2 25 Package Interrupts,RM C 3 28 Interrupt Support,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-3-1-20-21-protected-procedure-handlers}@anchor{240}
+@anchor{gnat_rm/implementation_advice rm-c-3-1-20-21-protected-procedure-handlers}@anchor{244}
@section RM C.3.1(20-21): Protected Procedure Handlers
@@ -15391,7 +15418,7 @@ Followed. Compile time warnings are given when possible.
@geindex Interrupts
@node RM C 3 2 25 Package Interrupts,RM C 4 14 Pre-elaboration Requirements,RM C 3 1 20-21 Protected Procedure Handlers,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-3-2-25-package-interrupts}@anchor{241}
+@anchor{gnat_rm/implementation_advice rm-c-3-2-25-package-interrupts}@anchor{245}
@section RM C.3.2(25): Package @code{Interrupts}
@@ -15409,7 +15436,7 @@ Followed.
@geindex Pre-elaboration requirements
@node RM C 4 14 Pre-elaboration Requirements,RM C 5 8 Pragma Discard_Names,RM C 3 2 25 Package Interrupts,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-4-14-pre-elaboration-requirements}@anchor{242}
+@anchor{gnat_rm/implementation_advice rm-c-4-14-pre-elaboration-requirements}@anchor{246}
@section RM C.4(14): Pre-elaboration Requirements
@@ -15425,7 +15452,7 @@ Followed. Executable code is generated in some cases, e.g., loops
to initialize large arrays.
@node RM C 5 8 Pragma Discard_Names,RM C 7 2 30 The Package Task_Attributes,RM C 4 14 Pre-elaboration Requirements,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-5-8-pragma-discard-names}@anchor{243}
+@anchor{gnat_rm/implementation_advice rm-c-5-8-pragma-discard-names}@anchor{247}
@section RM C.5(8): Pragma @code{Discard_Names}
@@ -15443,7 +15470,7 @@ Followed.
@geindex Task_Attributes
@node RM C 7 2 30 The Package Task_Attributes,RM D 3 17 Locking Policies,RM C 5 8 Pragma Discard_Names,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-c-7-2-30-the-package-task-attributes}@anchor{244}
+@anchor{gnat_rm/implementation_advice rm-c-7-2-30-the-package-task-attributes}@anchor{248}
@section RM C.7.2(30): The Package Task_Attributes
@@ -15464,7 +15491,7 @@ Not followed. This implementation is not targeted to such a domain.
@geindex Locking Policies
@node RM D 3 17 Locking Policies,RM D 4 16 Entry Queuing Policies,RM C 7 2 30 The Package Task_Attributes,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-d-3-17-locking-policies}@anchor{245}
+@anchor{gnat_rm/implementation_advice rm-d-3-17-locking-policies}@anchor{249}
@section RM D.3(17): Locking Policies
@@ -15481,7 +15508,7 @@ whose names (@code{Inheritance_Locking} and
@geindex Entry queuing policies
@node RM D 4 16 Entry Queuing Policies,RM D 6 9-10 Preemptive Abort,RM D 3 17 Locking Policies,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-d-4-16-entry-queuing-policies}@anchor{246}
+@anchor{gnat_rm/implementation_advice rm-d-4-16-entry-queuing-policies}@anchor{24a}
@section RM D.4(16): Entry Queuing Policies
@@ -15496,7 +15523,7 @@ Followed. No such implementation-defined queuing policies exist.
@geindex Preemptive abort
@node RM D 6 9-10 Preemptive Abort,RM D 7 21 Tasking Restrictions,RM D 4 16 Entry Queuing Policies,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-d-6-9-10-preemptive-abort}@anchor{247}
+@anchor{gnat_rm/implementation_advice rm-d-6-9-10-preemptive-abort}@anchor{24b}
@section RM D.6(9-10): Preemptive Abort
@@ -15522,7 +15549,7 @@ Followed.
@geindex Tasking restrictions
@node RM D 7 21 Tasking Restrictions,RM D 8 47-49 Monotonic Time,RM D 6 9-10 Preemptive Abort,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-d-7-21-tasking-restrictions}@anchor{248}
+@anchor{gnat_rm/implementation_advice rm-d-7-21-tasking-restrictions}@anchor{24c}
@section RM D.7(21): Tasking Restrictions
@@ -15541,7 +15568,7 @@ pragma @code{Profile (Restricted)} for more details.
@geindex monotonic
@node RM D 8 47-49 Monotonic Time,RM E 5 28-29 Partition Communication Subsystem,RM D 7 21 Tasking Restrictions,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-d-8-47-49-monotonic-time}@anchor{249}
+@anchor{gnat_rm/implementation_advice rm-d-8-47-49-monotonic-time}@anchor{24d}
@section RM D.8(47-49): Monotonic Time
@@ -15576,7 +15603,7 @@ Followed.
@geindex PCS
@node RM E 5 28-29 Partition Communication Subsystem,RM F 7 COBOL Support,RM D 8 47-49 Monotonic Time,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-e-5-28-29-partition-communication-subsystem}@anchor{24a}
+@anchor{gnat_rm/implementation_advice rm-e-5-28-29-partition-communication-subsystem}@anchor{24e}
@section RM E.5(28-29): Partition Communication Subsystem
@@ -15604,7 +15631,7 @@ GNAT.
@geindex COBOL support
@node RM F 7 COBOL Support,RM F 1 2 Decimal Radix Support,RM E 5 28-29 Partition Communication Subsystem,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-f-7-cobol-support}@anchor{24b}
+@anchor{gnat_rm/implementation_advice rm-f-7-cobol-support}@anchor{24f}
@section RM F(7): COBOL Support
@@ -15624,7 +15651,7 @@ Followed.
@geindex Decimal radix support
@node RM F 1 2 Decimal Radix Support,RM G Numerics,RM F 7 COBOL Support,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-f-1-2-decimal-radix-support}@anchor{24c}
+@anchor{gnat_rm/implementation_advice rm-f-1-2-decimal-radix-support}@anchor{250}
@section RM F.1(2): Decimal Radix Support
@@ -15640,7 +15667,7 @@ representations.
@geindex Numerics
@node RM G Numerics,RM G 1 1 56-58 Complex Types,RM F 1 2 Decimal Radix Support,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-g-numerics}@anchor{24d}
+@anchor{gnat_rm/implementation_advice rm-g-numerics}@anchor{251}
@section RM G: Numerics
@@ -15660,7 +15687,7 @@ Followed.
@geindex Complex types
@node RM G 1 1 56-58 Complex Types,RM G 1 2 49 Complex Elementary Functions,RM G Numerics,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-g-1-1-56-58-complex-types}@anchor{24e}
+@anchor{gnat_rm/implementation_advice rm-g-1-1-56-58-complex-types}@anchor{252}
@section RM G.1.1(56-58): Complex Types
@@ -15722,7 +15749,7 @@ Followed.
@geindex Complex elementary functions
@node RM G 1 2 49 Complex Elementary Functions,RM G 2 4 19 Accuracy Requirements,RM G 1 1 56-58 Complex Types,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-g-1-2-49-complex-elementary-functions}@anchor{24f}
+@anchor{gnat_rm/implementation_advice rm-g-1-2-49-complex-elementary-functions}@anchor{253}
@section RM G.1.2(49): Complex Elementary Functions
@@ -15744,7 +15771,7 @@ Followed.
@geindex Accuracy requirements
@node RM G 2 4 19 Accuracy Requirements,RM G 2 6 15 Complex Arithmetic Accuracy,RM G 1 2 49 Complex Elementary Functions,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-g-2-4-19-accuracy-requirements}@anchor{250}
+@anchor{gnat_rm/implementation_advice rm-g-2-4-19-accuracy-requirements}@anchor{254}
@section RM G.2.4(19): Accuracy Requirements
@@ -15768,7 +15795,7 @@ Followed.
@geindex complex arithmetic
@node RM G 2 6 15 Complex Arithmetic Accuracy,RM H 6 15/2 Pragma Partition_Elaboration_Policy,RM G 2 4 19 Accuracy Requirements,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-g-2-6-15-complex-arithmetic-accuracy}@anchor{251}
+@anchor{gnat_rm/implementation_advice rm-g-2-6-15-complex-arithmetic-accuracy}@anchor{255}
@section RM G.2.6(15): Complex Arithmetic Accuracy
@@ -15786,7 +15813,7 @@ Followed.
@geindex Sequential elaboration policy
@node RM H 6 15/2 Pragma Partition_Elaboration_Policy,,RM G 2 6 15 Complex Arithmetic Accuracy,Implementation Advice
-@anchor{gnat_rm/implementation_advice rm-h-6-15-2-pragma-partition-elaboration-policy}@anchor{252}
+@anchor{gnat_rm/implementation_advice rm-h-6-15-2-pragma-partition-elaboration-policy}@anchor{256}
@section RM H.6(15/2): Pragma Partition_Elaboration_Policy
@@ -15801,7 +15828,7 @@ immediately terminated."
Not followed.
@node Implementation Defined Characteristics,Intrinsic Subprograms,Implementation Advice,Top
-@anchor{gnat_rm/implementation_defined_characteristics implementation-defined-characteristics}@anchor{b}@anchor{gnat_rm/implementation_defined_characteristics doc}@anchor{253}@anchor{gnat_rm/implementation_defined_characteristics id1}@anchor{254}
+@anchor{gnat_rm/implementation_defined_characteristics implementation-defined-characteristics}@anchor{b}@anchor{gnat_rm/implementation_defined_characteristics doc}@anchor{257}@anchor{gnat_rm/implementation_defined_characteristics id1}@anchor{258}
@chapter Implementation Defined Characteristics
@@ -16997,7 +17024,7 @@ When the @code{Pattern} parameter is not the null string, it is interpreted
according to the syntax of regular expressions as defined in the
@code{GNAT.Regexp} package.
-See @ref{255,,GNAT.Regexp (g-regexp.ads)}.
+See @ref{259,,GNAT.Regexp (g-regexp.ads)}.
@itemize *
@@ -18046,7 +18073,7 @@ H.4(27)."
There are no restrictions on pragma @code{Restrictions}.
@node Intrinsic Subprograms,Representation Clauses and Pragmas,Implementation Defined Characteristics,Top
-@anchor{gnat_rm/intrinsic_subprograms doc}@anchor{256}@anchor{gnat_rm/intrinsic_subprograms intrinsic-subprograms}@anchor{c}@anchor{gnat_rm/intrinsic_subprograms id1}@anchor{257}
+@anchor{gnat_rm/intrinsic_subprograms doc}@anchor{25a}@anchor{gnat_rm/intrinsic_subprograms intrinsic-subprograms}@anchor{c}@anchor{gnat_rm/intrinsic_subprograms id1}@anchor{25b}
@chapter Intrinsic Subprograms
@@ -18084,7 +18111,7 @@ Ada standard does not require Ada compilers to implement this feature.
@end menu
@node Intrinsic Operators,Compilation_ISO_Date,,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms id2}@anchor{258}@anchor{gnat_rm/intrinsic_subprograms intrinsic-operators}@anchor{259}
+@anchor{gnat_rm/intrinsic_subprograms id2}@anchor{25c}@anchor{gnat_rm/intrinsic_subprograms intrinsic-operators}@anchor{25d}
@section Intrinsic Operators
@@ -18115,7 +18142,7 @@ It is also possible to specify such operators for private types, if the
full views are appropriate arithmetic types.
@node Compilation_ISO_Date,Compilation_Date,Intrinsic Operators,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms id3}@anchor{25a}@anchor{gnat_rm/intrinsic_subprograms compilation-iso-date}@anchor{25b}
+@anchor{gnat_rm/intrinsic_subprograms id3}@anchor{25e}@anchor{gnat_rm/intrinsic_subprograms compilation-iso-date}@anchor{25f}
@section Compilation_ISO_Date
@@ -18129,7 +18156,7 @@ application program should simply call the function
the current compilation (in local time format YYYY-MM-DD).
@node Compilation_Date,Compilation_Time,Compilation_ISO_Date,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms compilation-date}@anchor{25c}@anchor{gnat_rm/intrinsic_subprograms id4}@anchor{25d}
+@anchor{gnat_rm/intrinsic_subprograms compilation-date}@anchor{260}@anchor{gnat_rm/intrinsic_subprograms id4}@anchor{261}
@section Compilation_Date
@@ -18139,7 +18166,7 @@ Same as Compilation_ISO_Date, except the string is in the form
MMM DD YYYY.
@node Compilation_Time,Enclosing_Entity,Compilation_Date,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms compilation-time}@anchor{25e}@anchor{gnat_rm/intrinsic_subprograms id5}@anchor{25f}
+@anchor{gnat_rm/intrinsic_subprograms compilation-time}@anchor{262}@anchor{gnat_rm/intrinsic_subprograms id5}@anchor{263}
@section Compilation_Time
@@ -18153,7 +18180,7 @@ application program should simply call the function
the current compilation (in local time format HH:MM:SS).
@node Enclosing_Entity,Exception_Information,Compilation_Time,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms id6}@anchor{260}@anchor{gnat_rm/intrinsic_subprograms enclosing-entity}@anchor{261}
+@anchor{gnat_rm/intrinsic_subprograms id6}@anchor{264}@anchor{gnat_rm/intrinsic_subprograms enclosing-entity}@anchor{265}
@section Enclosing_Entity
@@ -18167,7 +18194,7 @@ application program should simply call the function
the current subprogram, package, task, entry, or protected subprogram.
@node Exception_Information,Exception_Message,Enclosing_Entity,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms id7}@anchor{262}@anchor{gnat_rm/intrinsic_subprograms exception-information}@anchor{263}
+@anchor{gnat_rm/intrinsic_subprograms id7}@anchor{266}@anchor{gnat_rm/intrinsic_subprograms exception-information}@anchor{267}
@section Exception_Information
@@ -18181,7 +18208,7 @@ so an application program should simply call the function
the exception information associated with the current exception.
@node Exception_Message,Exception_Name,Exception_Information,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms exception-message}@anchor{264}@anchor{gnat_rm/intrinsic_subprograms id8}@anchor{265}
+@anchor{gnat_rm/intrinsic_subprograms exception-message}@anchor{268}@anchor{gnat_rm/intrinsic_subprograms id8}@anchor{269}
@section Exception_Message
@@ -18195,7 +18222,7 @@ so an application program should simply call the function
the message associated with the current exception.
@node Exception_Name,File,Exception_Message,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms exception-name}@anchor{266}@anchor{gnat_rm/intrinsic_subprograms id9}@anchor{267}
+@anchor{gnat_rm/intrinsic_subprograms exception-name}@anchor{26a}@anchor{gnat_rm/intrinsic_subprograms id9}@anchor{26b}
@section Exception_Name
@@ -18209,7 +18236,7 @@ so an application program should simply call the function
the name of the current exception.
@node File,Line,Exception_Name,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms id10}@anchor{268}@anchor{gnat_rm/intrinsic_subprograms file}@anchor{269}
+@anchor{gnat_rm/intrinsic_subprograms id10}@anchor{26c}@anchor{gnat_rm/intrinsic_subprograms file}@anchor{26d}
@section File
@@ -18223,7 +18250,7 @@ application program should simply call the function
file.
@node Line,Shifts and Rotates,File,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms id11}@anchor{26a}@anchor{gnat_rm/intrinsic_subprograms line}@anchor{26b}
+@anchor{gnat_rm/intrinsic_subprograms id11}@anchor{26e}@anchor{gnat_rm/intrinsic_subprograms line}@anchor{26f}
@section Line
@@ -18237,7 +18264,7 @@ application program should simply call the function
source line.
@node Shifts and Rotates,Source_Location,Line,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms shifts-and-rotates}@anchor{26c}@anchor{gnat_rm/intrinsic_subprograms id12}@anchor{26d}
+@anchor{gnat_rm/intrinsic_subprograms shifts-and-rotates}@anchor{270}@anchor{gnat_rm/intrinsic_subprograms id12}@anchor{271}
@section Shifts and Rotates
@@ -18276,7 +18303,7 @@ the Provide_Shift_Operators pragma, which provides the function declarations
and corresponding pragma Import's for all five shift functions.
@node Source_Location,,Shifts and Rotates,Intrinsic Subprograms
-@anchor{gnat_rm/intrinsic_subprograms source-location}@anchor{26e}@anchor{gnat_rm/intrinsic_subprograms id13}@anchor{26f}
+@anchor{gnat_rm/intrinsic_subprograms source-location}@anchor{272}@anchor{gnat_rm/intrinsic_subprograms id13}@anchor{273}
@section Source_Location
@@ -18290,7 +18317,7 @@ application program should simply call the function
source file location.
@node Representation Clauses and Pragmas,Standard Library Routines,Intrinsic Subprograms,Top
-@anchor{gnat_rm/representation_clauses_and_pragmas representation-clauses-and-pragmas}@anchor{d}@anchor{gnat_rm/representation_clauses_and_pragmas doc}@anchor{270}@anchor{gnat_rm/representation_clauses_and_pragmas id1}@anchor{271}
+@anchor{gnat_rm/representation_clauses_and_pragmas representation-clauses-and-pragmas}@anchor{d}@anchor{gnat_rm/representation_clauses_and_pragmas doc}@anchor{274}@anchor{gnat_rm/representation_clauses_and_pragmas id1}@anchor{275}
@chapter Representation Clauses and Pragmas
@@ -18336,15 +18363,17 @@ and this section describes the additional capabilities provided.
@end menu
@node Alignment Clauses,Size Clauses,,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id2}@anchor{272}@anchor{gnat_rm/representation_clauses_and_pragmas alignment-clauses}@anchor{273}
+@anchor{gnat_rm/representation_clauses_and_pragmas id2}@anchor{276}@anchor{gnat_rm/representation_clauses_and_pragmas alignment-clauses}@anchor{277}
@section Alignment Clauses
@geindex Alignment Clause
-GNAT requires that all alignment clauses specify a power of 2, and all
-default alignments are always a power of 2. The default alignment
-values are as follows:
+GNAT requires that all alignment clauses specify 0 or a power of 2, and
+all default alignments are always a power of 2. Specifying 0 is the
+same as specifying 1.
+
+The default alignment values are as follows:
@itemize *
@@ -18356,7 +18385,7 @@ For elementary types, the alignment is the minimum of the actual size of
objects of the type divided by @code{Storage_Unit},
and the maximum alignment supported by the target.
(This maximum alignment is given by the GNAT-specific attribute
-@code{Standard'Maximum_Alignment}; see @ref{18d,,Attribute Maximum_Alignment}.)
+@code{Standard'Maximum_Alignment}; see @ref{191,,Attribute Maximum_Alignment}.)
@geindex Maximum_Alignment attribute
@@ -18465,7 +18494,7 @@ assumption is non-portable, and other compilers may choose different
alignments for the subtype @code{RS}.
@node Size Clauses,Storage_Size Clauses,Alignment Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id3}@anchor{274}@anchor{gnat_rm/representation_clauses_and_pragmas size-clauses}@anchor{275}
+@anchor{gnat_rm/representation_clauses_and_pragmas id3}@anchor{278}@anchor{gnat_rm/representation_clauses_and_pragmas size-clauses}@anchor{279}
@section Size Clauses
@@ -18542,7 +18571,7 @@ if it is known that a Size value can be accommodated in an object of
type Integer.
@node Storage_Size Clauses,Size of Variant Record Objects,Size Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas storage-size-clauses}@anchor{276}@anchor{gnat_rm/representation_clauses_and_pragmas id4}@anchor{277}
+@anchor{gnat_rm/representation_clauses_and_pragmas storage-size-clauses}@anchor{27a}@anchor{gnat_rm/representation_clauses_and_pragmas id4}@anchor{27b}
@section Storage_Size Clauses
@@ -18615,7 +18644,7 @@ Of course in practice, there will not be any explicit allocators in the
case of such an access declaration.
@node Size of Variant Record Objects,Biased Representation,Storage_Size Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id5}@anchor{278}@anchor{gnat_rm/representation_clauses_and_pragmas size-of-variant-record-objects}@anchor{279}
+@anchor{gnat_rm/representation_clauses_and_pragmas id5}@anchor{27c}@anchor{gnat_rm/representation_clauses_and_pragmas size-of-variant-record-objects}@anchor{27d}
@section Size of Variant Record Objects
@@ -18725,7 +18754,7 @@ the maximum size, regardless of the current variant value, the
variant value.
@node Biased Representation,Value_Size and Object_Size Clauses,Size of Variant Record Objects,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id6}@anchor{27a}@anchor{gnat_rm/representation_clauses_and_pragmas biased-representation}@anchor{27b}
+@anchor{gnat_rm/representation_clauses_and_pragmas id6}@anchor{27e}@anchor{gnat_rm/representation_clauses_and_pragmas biased-representation}@anchor{27f}
@section Biased Representation
@@ -18763,7 +18792,7 @@ biased representation can be used for all discrete types except for
enumeration types for which a representation clause is given.
@node Value_Size and Object_Size Clauses,Component_Size Clauses,Biased Representation,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id7}@anchor{27c}@anchor{gnat_rm/representation_clauses_and_pragmas value-size-and-object-size-clauses}@anchor{27d}
+@anchor{gnat_rm/representation_clauses_and_pragmas id7}@anchor{280}@anchor{gnat_rm/representation_clauses_and_pragmas value-size-and-object-size-clauses}@anchor{281}
@section Value_Size and Object_Size Clauses
@@ -19079,7 +19108,7 @@ definition clause forces biased representation. This
warning can be turned off using @code{-gnatw.B}.
@node Component_Size Clauses,Bit_Order Clauses,Value_Size and Object_Size Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id8}@anchor{27e}@anchor{gnat_rm/representation_clauses_and_pragmas component-size-clauses}@anchor{27f}
+@anchor{gnat_rm/representation_clauses_and_pragmas id8}@anchor{282}@anchor{gnat_rm/representation_clauses_and_pragmas component-size-clauses}@anchor{283}
@section Component_Size Clauses
@@ -19126,7 +19155,7 @@ and a pragma Pack for the same array type. if such duplicate
clauses are given, the pragma Pack will be ignored.
@node Bit_Order Clauses,Effect of Bit_Order on Byte Ordering,Component_Size Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas bit-order-clauses}@anchor{280}@anchor{gnat_rm/representation_clauses_and_pragmas id9}@anchor{281}
+@anchor{gnat_rm/representation_clauses_and_pragmas bit-order-clauses}@anchor{284}@anchor{gnat_rm/representation_clauses_and_pragmas id9}@anchor{285}
@section Bit_Order Clauses
@@ -19232,7 +19261,7 @@ if desired. The following section contains additional
details regarding the issue of byte ordering.
@node Effect of Bit_Order on Byte Ordering,Pragma Pack for Arrays,Bit_Order Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id10}@anchor{282}@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-bit-order-on-byte-ordering}@anchor{283}
+@anchor{gnat_rm/representation_clauses_and_pragmas id10}@anchor{286}@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-bit-order-on-byte-ordering}@anchor{287}
@section Effect of Bit_Order on Byte Ordering
@@ -19489,7 +19518,7 @@ to set the boolean constant @code{Master_Byte_First} in
an appropriate manner.
@node Pragma Pack for Arrays,Pragma Pack for Records,Effect of Bit_Order on Byte Ordering,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-arrays}@anchor{284}@anchor{gnat_rm/representation_clauses_and_pragmas id11}@anchor{285}
+@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-arrays}@anchor{288}@anchor{gnat_rm/representation_clauses_and_pragmas id11}@anchor{289}
@section Pragma Pack for Arrays
@@ -19606,7 +19635,7 @@ Here 31-bit packing is achieved as required, and no warning is generated,
since in this case the programmer intention is clear.
@node Pragma Pack for Records,Record Representation Clauses,Pragma Pack for Arrays,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-records}@anchor{286}@anchor{gnat_rm/representation_clauses_and_pragmas id12}@anchor{287}
+@anchor{gnat_rm/representation_clauses_and_pragmas pragma-pack-for-records}@anchor{28a}@anchor{gnat_rm/representation_clauses_and_pragmas id12}@anchor{28b}
@section Pragma Pack for Records
@@ -19691,7 +19720,7 @@ the @code{L6} field is aligned to the next byte boundary, and takes an
integral number of bytes, i.e., 72 bits.
@node Record Representation Clauses,Handling of Records with Holes,Pragma Pack for Records,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id13}@anchor{288}@anchor{gnat_rm/representation_clauses_and_pragmas record-representation-clauses}@anchor{289}
+@anchor{gnat_rm/representation_clauses_and_pragmas id13}@anchor{28c}@anchor{gnat_rm/representation_clauses_and_pragmas record-representation-clauses}@anchor{28d}
@section Record Representation Clauses
@@ -19769,7 +19798,7 @@ end record;
@end example
@node Handling of Records with Holes,Enumeration Clauses,Record Representation Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas handling-of-records-with-holes}@anchor{28a}@anchor{gnat_rm/representation_clauses_and_pragmas id14}@anchor{28b}
+@anchor{gnat_rm/representation_clauses_and_pragmas handling-of-records-with-holes}@anchor{28e}@anchor{gnat_rm/representation_clauses_and_pragmas id14}@anchor{28f}
@section Handling of Records with Holes
@@ -19846,7 +19875,7 @@ for Hrec'Size use 64;
@end example
@node Enumeration Clauses,Address Clauses,Handling of Records with Holes,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas enumeration-clauses}@anchor{28c}@anchor{gnat_rm/representation_clauses_and_pragmas id15}@anchor{28d}
+@anchor{gnat_rm/representation_clauses_and_pragmas enumeration-clauses}@anchor{290}@anchor{gnat_rm/representation_clauses_and_pragmas id15}@anchor{291}
@section Enumeration Clauses
@@ -19889,7 +19918,7 @@ the overhead of converting representation values to the corresponding
positional values, (i.e., the value delivered by the @code{Pos} attribute).
@node Address Clauses,Use of Address Clauses for Memory-Mapped I/O,Enumeration Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id16}@anchor{28e}@anchor{gnat_rm/representation_clauses_and_pragmas address-clauses}@anchor{28f}
+@anchor{gnat_rm/representation_clauses_and_pragmas id16}@anchor{292}@anchor{gnat_rm/representation_clauses_and_pragmas address-clauses}@anchor{293}
@section Address Clauses
@@ -20218,7 +20247,7 @@ then the program compiles without the warning and when run will generate
the output @code{X was not clobbered}.
@node Use of Address Clauses for Memory-Mapped I/O,Effect of Convention on Representation,Address Clauses,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id17}@anchor{290}@anchor{gnat_rm/representation_clauses_and_pragmas use-of-address-clauses-for-memory-mapped-i-o}@anchor{291}
+@anchor{gnat_rm/representation_clauses_and_pragmas id17}@anchor{294}@anchor{gnat_rm/representation_clauses_and_pragmas use-of-address-clauses-for-memory-mapped-i-o}@anchor{295}
@section Use of Address Clauses for Memory-Mapped I/O
@@ -20276,7 +20305,7 @@ provides the pragma @code{Volatile_Full_Access} which can be used in lieu of
pragma @code{Atomic} and will give the additional guarantee.
@node Effect of Convention on Representation,Conventions and Anonymous Access Types,Use of Address Clauses for Memory-Mapped I/O,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id18}@anchor{292}@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-convention-on-representation}@anchor{293}
+@anchor{gnat_rm/representation_clauses_and_pragmas id18}@anchor{296}@anchor{gnat_rm/representation_clauses_and_pragmas effect-of-convention-on-representation}@anchor{297}
@section Effect of Convention on Representation
@@ -20354,7 +20383,7 @@ when one of these values is read, any nonzero value is treated as True.
@end itemize
@node Conventions and Anonymous Access Types,Determining the Representations chosen by GNAT,Effect of Convention on Representation,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas conventions-and-anonymous-access-types}@anchor{294}@anchor{gnat_rm/representation_clauses_and_pragmas id19}@anchor{295}
+@anchor{gnat_rm/representation_clauses_and_pragmas conventions-and-anonymous-access-types}@anchor{298}@anchor{gnat_rm/representation_clauses_and_pragmas id19}@anchor{299}
@section Conventions and Anonymous Access Types
@@ -20430,7 +20459,7 @@ package ConvComp is
@end example
@node Determining the Representations chosen by GNAT,,Conventions and Anonymous Access Types,Representation Clauses and Pragmas
-@anchor{gnat_rm/representation_clauses_and_pragmas id20}@anchor{296}@anchor{gnat_rm/representation_clauses_and_pragmas determining-the-representations-chosen-by-gnat}@anchor{297}
+@anchor{gnat_rm/representation_clauses_and_pragmas id20}@anchor{29a}@anchor{gnat_rm/representation_clauses_and_pragmas determining-the-representations-chosen-by-gnat}@anchor{29b}
@section Determining the Representations chosen by GNAT
@@ -20582,7 +20611,7 @@ generated by the compiler into the original source to fix and guarantee
the actual representation to be used.
@node Standard Library Routines,The Implementation of Standard I/O,Representation Clauses and Pragmas,Top
-@anchor{gnat_rm/standard_library_routines standard-library-routines}@anchor{e}@anchor{gnat_rm/standard_library_routines doc}@anchor{298}@anchor{gnat_rm/standard_library_routines id1}@anchor{299}
+@anchor{gnat_rm/standard_library_routines standard-library-routines}@anchor{e}@anchor{gnat_rm/standard_library_routines doc}@anchor{29c}@anchor{gnat_rm/standard_library_routines id1}@anchor{29d}
@chapter Standard Library Routines
@@ -21406,7 +21435,7 @@ For packages in Interfaces and System, all the RM defined packages are
available in GNAT, see the Ada 2012 RM for full details.
@node The Implementation of Standard I/O,The GNAT Library,Standard Library Routines,Top
-@anchor{gnat_rm/the_implementation_of_standard_i_o the-implementation-of-standard-i-o}@anchor{f}@anchor{gnat_rm/the_implementation_of_standard_i_o doc}@anchor{29a}@anchor{gnat_rm/the_implementation_of_standard_i_o id1}@anchor{29b}
+@anchor{gnat_rm/the_implementation_of_standard_i_o the-implementation-of-standard-i-o}@anchor{f}@anchor{gnat_rm/the_implementation_of_standard_i_o doc}@anchor{29e}@anchor{gnat_rm/the_implementation_of_standard_i_o id1}@anchor{29f}
@chapter The Implementation of Standard I/O
@@ -21458,7 +21487,7 @@ these additional facilities are also described in this chapter.
@end menu
@node Standard I/O Packages,FORM Strings,,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o standard-i-o-packages}@anchor{29c}@anchor{gnat_rm/the_implementation_of_standard_i_o id2}@anchor{29d}
+@anchor{gnat_rm/the_implementation_of_standard_i_o standard-i-o-packages}@anchor{2a0}@anchor{gnat_rm/the_implementation_of_standard_i_o id2}@anchor{2a1}
@section Standard I/O Packages
@@ -21529,7 +21558,7 @@ flush the common I/O streams and in particular Standard_Output before
elaborating the Ada code.
@node FORM Strings,Direct_IO,Standard I/O Packages,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o form-strings}@anchor{29e}@anchor{gnat_rm/the_implementation_of_standard_i_o id3}@anchor{29f}
+@anchor{gnat_rm/the_implementation_of_standard_i_o form-strings}@anchor{2a2}@anchor{gnat_rm/the_implementation_of_standard_i_o id3}@anchor{2a3}
@section FORM Strings
@@ -21555,7 +21584,7 @@ unrecognized keyword appears in a form string, it is silently ignored
and not considered invalid.
@node Direct_IO,Sequential_IO,FORM Strings,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o direct-io}@anchor{2a0}@anchor{gnat_rm/the_implementation_of_standard_i_o id4}@anchor{2a1}
+@anchor{gnat_rm/the_implementation_of_standard_i_o direct-io}@anchor{2a4}@anchor{gnat_rm/the_implementation_of_standard_i_o id4}@anchor{2a5}
@section Direct_IO
@@ -21575,7 +21604,7 @@ There is no limit on the size of Direct_IO files, they are expanded as
necessary to accommodate whatever records are written to the file.
@node Sequential_IO,Text_IO,Direct_IO,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o sequential-io}@anchor{2a2}@anchor{gnat_rm/the_implementation_of_standard_i_o id5}@anchor{2a3}
+@anchor{gnat_rm/the_implementation_of_standard_i_o sequential-io}@anchor{2a6}@anchor{gnat_rm/the_implementation_of_standard_i_o id5}@anchor{2a7}
@section Sequential_IO
@@ -21622,7 +21651,7 @@ using Stream_IO, and this is the preferred mechanism. In particular, the
above program fragment rewritten to use Stream_IO will work correctly.
@node Text_IO,Wide_Text_IO,Sequential_IO,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id6}@anchor{2a4}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io}@anchor{2a5}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id6}@anchor{2a8}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io}@anchor{2a9}
@section Text_IO
@@ -21705,7 +21734,7 @@ the file.
@end menu
@node Stream Pointer Positioning,Reading and Writing Non-Regular Files,,Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o id7}@anchor{2a6}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning}@anchor{2a7}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id7}@anchor{2aa}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning}@anchor{2ab}
@subsection Stream Pointer Positioning
@@ -21741,7 +21770,7 @@ between two Ada files, then the difference may be observable in some
situations.
@node Reading and Writing Non-Regular Files,Get_Immediate,Stream Pointer Positioning,Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files}@anchor{2a8}@anchor{gnat_rm/the_implementation_of_standard_i_o id8}@anchor{2a9}
+@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files}@anchor{2ac}@anchor{gnat_rm/the_implementation_of_standard_i_o id8}@anchor{2ad}
@subsection Reading and Writing Non-Regular Files
@@ -21792,7 +21821,7 @@ to read data past that end of
file indication, until another end of file indication is entered.
@node Get_Immediate,Treating Text_IO Files as Streams,Reading and Writing Non-Regular Files,Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o get-immediate}@anchor{2aa}@anchor{gnat_rm/the_implementation_of_standard_i_o id9}@anchor{2ab}
+@anchor{gnat_rm/the_implementation_of_standard_i_o get-immediate}@anchor{2ae}@anchor{gnat_rm/the_implementation_of_standard_i_o id9}@anchor{2af}
@subsection Get_Immediate
@@ -21810,7 +21839,7 @@ possible), it is undefined whether the FF character will be treated as a
page mark.
@node Treating Text_IO Files as Streams,Text_IO Extensions,Get_Immediate,Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o id10}@anchor{2ac}@anchor{gnat_rm/the_implementation_of_standard_i_o treating-text-io-files-as-streams}@anchor{2ad}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id10}@anchor{2b0}@anchor{gnat_rm/the_implementation_of_standard_i_o treating-text-io-files-as-streams}@anchor{2b1}
@subsection Treating Text_IO Files as Streams
@@ -21826,7 +21855,7 @@ skipped and the effect is similar to that described above for
@code{Get_Immediate}.
@node Text_IO Extensions,Text_IO Facilities for Unbounded Strings,Treating Text_IO Files as Streams,Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o id11}@anchor{2ae}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-extensions}@anchor{2af}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id11}@anchor{2b2}@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-extensions}@anchor{2b3}
@subsection Text_IO Extensions
@@ -21854,7 +21883,7 @@ the string is to be read.
@end itemize
@node Text_IO Facilities for Unbounded Strings,,Text_IO Extensions,Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-facilities-for-unbounded-strings}@anchor{2b0}@anchor{gnat_rm/the_implementation_of_standard_i_o id12}@anchor{2b1}
+@anchor{gnat_rm/the_implementation_of_standard_i_o text-io-facilities-for-unbounded-strings}@anchor{2b4}@anchor{gnat_rm/the_implementation_of_standard_i_o id12}@anchor{2b5}
@subsection Text_IO Facilities for Unbounded Strings
@@ -21902,7 +21931,7 @@ files @code{a-szuzti.ads} and @code{a-szuzti.adb} provides similar extended
@code{Wide_Wide_Text_IO} functionality for unbounded wide wide strings.
@node Wide_Text_IO,Wide_Wide_Text_IO,Text_IO,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o wide-text-io}@anchor{2b2}@anchor{gnat_rm/the_implementation_of_standard_i_o id13}@anchor{2b3}
+@anchor{gnat_rm/the_implementation_of_standard_i_o wide-text-io}@anchor{2b6}@anchor{gnat_rm/the_implementation_of_standard_i_o id13}@anchor{2b7}
@section Wide_Text_IO
@@ -22149,12 +22178,12 @@ input also causes Constraint_Error to be raised.
@end menu
@node Stream Pointer Positioning<2>,Reading and Writing Non-Regular Files<2>,,Wide_Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-1}@anchor{2b4}@anchor{gnat_rm/the_implementation_of_standard_i_o id14}@anchor{2b5}
+@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-1}@anchor{2b8}@anchor{gnat_rm/the_implementation_of_standard_i_o id14}@anchor{2b9}
@subsection Stream Pointer Positioning
@code{Ada.Wide_Text_IO} is similar to @code{Ada.Text_IO} in its handling
-of stream pointer positioning (@ref{2a5,,Text_IO}). There is one additional
+of stream pointer positioning (@ref{2a9,,Text_IO}). There is one additional
case:
If @code{Ada.Wide_Text_IO.Look_Ahead} reads a character outside the
@@ -22173,7 +22202,7 @@ to a normal program using @code{Wide_Text_IO}. However, this discrepancy
can be observed if the wide text file shares a stream with another file.
@node Reading and Writing Non-Regular Files<2>,,Stream Pointer Positioning<2>,Wide_Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-1}@anchor{2b6}@anchor{gnat_rm/the_implementation_of_standard_i_o id15}@anchor{2b7}
+@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-1}@anchor{2ba}@anchor{gnat_rm/the_implementation_of_standard_i_o id15}@anchor{2bb}
@subsection Reading and Writing Non-Regular Files
@@ -22184,7 +22213,7 @@ treated as data characters), and @code{End_Of_Page} always returns
it is possible to read beyond an end of file.
@node Wide_Wide_Text_IO,Stream_IO,Wide_Text_IO,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id16}@anchor{2b8}@anchor{gnat_rm/the_implementation_of_standard_i_o wide-wide-text-io}@anchor{2b9}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id16}@anchor{2bc}@anchor{gnat_rm/the_implementation_of_standard_i_o wide-wide-text-io}@anchor{2bd}
@section Wide_Wide_Text_IO
@@ -22353,12 +22382,12 @@ input also causes Constraint_Error to be raised.
@end menu
@node Stream Pointer Positioning<3>,Reading and Writing Non-Regular Files<3>,,Wide_Wide_Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-2}@anchor{2ba}@anchor{gnat_rm/the_implementation_of_standard_i_o id17}@anchor{2bb}
+@anchor{gnat_rm/the_implementation_of_standard_i_o stream-pointer-positioning-2}@anchor{2be}@anchor{gnat_rm/the_implementation_of_standard_i_o id17}@anchor{2bf}
@subsection Stream Pointer Positioning
@code{Ada.Wide_Wide_Text_IO} is similar to @code{Ada.Text_IO} in its handling
-of stream pointer positioning (@ref{2a5,,Text_IO}). There is one additional
+of stream pointer positioning (@ref{2a9,,Text_IO}). There is one additional
case:
If @code{Ada.Wide_Wide_Text_IO.Look_Ahead} reads a character outside the
@@ -22377,7 +22406,7 @@ to a normal program using @code{Wide_Wide_Text_IO}. However, this discrepancy
can be observed if the wide text file shares a stream with another file.
@node Reading and Writing Non-Regular Files<3>,,Stream Pointer Positioning<3>,Wide_Wide_Text_IO
-@anchor{gnat_rm/the_implementation_of_standard_i_o id18}@anchor{2bc}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-2}@anchor{2bd}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id18}@anchor{2c0}@anchor{gnat_rm/the_implementation_of_standard_i_o reading-and-writing-non-regular-files-2}@anchor{2c1}
@subsection Reading and Writing Non-Regular Files
@@ -22388,7 +22417,7 @@ treated as data characters), and @code{End_Of_Page} always returns
it is possible to read beyond an end of file.
@node Stream_IO,Text Translation,Wide_Wide_Text_IO,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id19}@anchor{2be}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-io}@anchor{2bf}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id19}@anchor{2c2}@anchor{gnat_rm/the_implementation_of_standard_i_o stream-io}@anchor{2c3}
@section Stream_IO
@@ -22410,7 +22439,7 @@ manner described for stream attributes.
@end itemize
@node Text Translation,Shared Files,Stream_IO,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id20}@anchor{2c0}@anchor{gnat_rm/the_implementation_of_standard_i_o text-translation}@anchor{2c1}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id20}@anchor{2c4}@anchor{gnat_rm/the_implementation_of_standard_i_o text-translation}@anchor{2c5}
@section Text Translation
@@ -22444,7 +22473,7 @@ mode. (corresponds to_O_U16TEXT).
@end itemize
@node Shared Files,Filenames encoding,Text Translation,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o id21}@anchor{2c2}@anchor{gnat_rm/the_implementation_of_standard_i_o shared-files}@anchor{2c3}
+@anchor{gnat_rm/the_implementation_of_standard_i_o id21}@anchor{2c6}@anchor{gnat_rm/the_implementation_of_standard_i_o shared-files}@anchor{2c7}
@section Shared Files
@@ -22507,7 +22536,7 @@ heterogeneous input-output. Although this approach will work in GNAT if
for this purpose (using the stream attributes)
@node Filenames encoding,File content encoding,Shared Files,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o filenames-encoding}@anchor{2c4}@anchor{gnat_rm/the_implementation_of_standard_i_o id22}@anchor{2c5}
+@anchor{gnat_rm/the_implementation_of_standard_i_o filenames-encoding}@anchor{2c8}@anchor{gnat_rm/the_implementation_of_standard_i_o id22}@anchor{2c9}
@section Filenames encoding
@@ -22547,7 +22576,7 @@ platform. On the other Operating Systems the run-time is supporting
UTF-8 natively.
@node File content encoding,Open Modes,Filenames encoding,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o file-content-encoding}@anchor{2c6}@anchor{gnat_rm/the_implementation_of_standard_i_o id23}@anchor{2c7}
+@anchor{gnat_rm/the_implementation_of_standard_i_o file-content-encoding}@anchor{2ca}@anchor{gnat_rm/the_implementation_of_standard_i_o id23}@anchor{2cb}
@section File content encoding
@@ -22580,7 +22609,7 @@ Unicode 8-bit encoding
This encoding is only supported on the Windows platform.
@node Open Modes,Operations on C Streams,File content encoding,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o open-modes}@anchor{2c8}@anchor{gnat_rm/the_implementation_of_standard_i_o id24}@anchor{2c9}
+@anchor{gnat_rm/the_implementation_of_standard_i_o open-modes}@anchor{2cc}@anchor{gnat_rm/the_implementation_of_standard_i_o id24}@anchor{2cd}
@section Open Modes
@@ -22683,7 +22712,7 @@ subsequently requires switching from reading to writing or vice-versa,
then the file is reopened in @code{r+} mode to permit the required operation.
@node Operations on C Streams,Interfacing to C Streams,Open Modes,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o operations-on-c-streams}@anchor{2ca}@anchor{gnat_rm/the_implementation_of_standard_i_o id25}@anchor{2cb}
+@anchor{gnat_rm/the_implementation_of_standard_i_o operations-on-c-streams}@anchor{2ce}@anchor{gnat_rm/the_implementation_of_standard_i_o id25}@anchor{2cf}
@section Operations on C Streams
@@ -22843,7 +22872,7 @@ end Interfaces.C_Streams;
@end example
@node Interfacing to C Streams,,Operations on C Streams,The Implementation of Standard I/O
-@anchor{gnat_rm/the_implementation_of_standard_i_o interfacing-to-c-streams}@anchor{2cc}@anchor{gnat_rm/the_implementation_of_standard_i_o id26}@anchor{2cd}
+@anchor{gnat_rm/the_implementation_of_standard_i_o interfacing-to-c-streams}@anchor{2d0}@anchor{gnat_rm/the_implementation_of_standard_i_o id26}@anchor{2d1}
@section Interfacing to C Streams
@@ -22936,7 +22965,7 @@ imported from a C program, allowing an Ada file to operate on an
existing C file.
@node The GNAT Library,Interfacing to Other Languages,The Implementation of Standard I/O,Top
-@anchor{gnat_rm/the_gnat_library the-gnat-library}@anchor{10}@anchor{gnat_rm/the_gnat_library doc}@anchor{2ce}@anchor{gnat_rm/the_gnat_library id1}@anchor{2cf}
+@anchor{gnat_rm/the_gnat_library the-gnat-library}@anchor{10}@anchor{gnat_rm/the_gnat_library doc}@anchor{2d2}@anchor{gnat_rm/the_gnat_library id1}@anchor{2d3}
@chapter The GNAT Library
@@ -23129,7 +23158,7 @@ of GNAT, and will generate a warning message.
@end menu
@node Ada Characters Latin_9 a-chlat9 ads,Ada Characters Wide_Latin_1 a-cwila1 ads,,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id2}@anchor{2d0}@anchor{gnat_rm/the_gnat_library ada-characters-latin-9-a-chlat9-ads}@anchor{2d1}
+@anchor{gnat_rm/the_gnat_library id2}@anchor{2d4}@anchor{gnat_rm/the_gnat_library ada-characters-latin-9-a-chlat9-ads}@anchor{2d5}
@section @code{Ada.Characters.Latin_9} (@code{a-chlat9.ads})
@@ -23146,7 +23175,7 @@ is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
@node Ada Characters Wide_Latin_1 a-cwila1 ads,Ada Characters Wide_Latin_9 a-cwila1 ads,Ada Characters Latin_9 a-chlat9 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-1-a-cwila1-ads}@anchor{2d2}@anchor{gnat_rm/the_gnat_library id3}@anchor{2d3}
+@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-1-a-cwila1-ads}@anchor{2d6}@anchor{gnat_rm/the_gnat_library id3}@anchor{2d7}
@section @code{Ada.Characters.Wide_Latin_1} (@code{a-cwila1.ads})
@@ -23163,7 +23192,7 @@ is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
@node Ada Characters Wide_Latin_9 a-cwila1 ads,Ada Characters Wide_Wide_Latin_1 a-chzla1 ads,Ada Characters Wide_Latin_1 a-cwila1 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id4}@anchor{2d4}@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-9-a-cwila1-ads}@anchor{2d5}
+@anchor{gnat_rm/the_gnat_library id4}@anchor{2d8}@anchor{gnat_rm/the_gnat_library ada-characters-wide-latin-9-a-cwila1-ads}@anchor{2d9}
@section @code{Ada.Characters.Wide_Latin_9} (@code{a-cwila1.ads})
@@ -23180,7 +23209,7 @@ is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
@node Ada Characters Wide_Wide_Latin_1 a-chzla1 ads,Ada Characters Wide_Wide_Latin_9 a-chzla9 ads,Ada Characters Wide_Latin_9 a-cwila1 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-1-a-chzla1-ads}@anchor{2d6}@anchor{gnat_rm/the_gnat_library id5}@anchor{2d7}
+@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-1-a-chzla1-ads}@anchor{2da}@anchor{gnat_rm/the_gnat_library id5}@anchor{2db}
@section @code{Ada.Characters.Wide_Wide_Latin_1} (@code{a-chzla1.ads})
@@ -23197,7 +23226,7 @@ is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
@node Ada Characters Wide_Wide_Latin_9 a-chzla9 ads,Ada Containers Formal_Doubly_Linked_Lists a-cfdlli ads,Ada Characters Wide_Wide_Latin_1 a-chzla1 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-9-a-chzla9-ads}@anchor{2d8}@anchor{gnat_rm/the_gnat_library id6}@anchor{2d9}
+@anchor{gnat_rm/the_gnat_library ada-characters-wide-wide-latin-9-a-chzla9-ads}@anchor{2dc}@anchor{gnat_rm/the_gnat_library id6}@anchor{2dd}
@section @code{Ada.Characters.Wide_Wide_Latin_9} (@code{a-chzla9.ads})
@@ -23214,7 +23243,7 @@ is specifically authorized by the Ada Reference Manual
(RM A.3.3(27)).
@node Ada Containers Formal_Doubly_Linked_Lists a-cfdlli ads,Ada Containers Formal_Hashed_Maps a-cfhama ads,Ada Characters Wide_Wide_Latin_9 a-chzla9 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id7}@anchor{2da}@anchor{gnat_rm/the_gnat_library ada-containers-formal-doubly-linked-lists-a-cfdlli-ads}@anchor{2db}
+@anchor{gnat_rm/the_gnat_library id7}@anchor{2de}@anchor{gnat_rm/the_gnat_library ada-containers-formal-doubly-linked-lists-a-cfdlli-ads}@anchor{2df}
@section @code{Ada.Containers.Formal_Doubly_Linked_Lists} (@code{a-cfdlli.ads})
@@ -23233,7 +23262,7 @@ efficient version than the one defined in the standard. In particular it
does not have the complex overhead required to detect cursor tampering.
@node Ada Containers Formal_Hashed_Maps a-cfhama ads,Ada Containers Formal_Hashed_Sets a-cfhase ads,Ada Containers Formal_Doubly_Linked_Lists a-cfdlli ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id8}@anchor{2dc}@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-maps-a-cfhama-ads}@anchor{2dd}
+@anchor{gnat_rm/the_gnat_library id8}@anchor{2e0}@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-maps-a-cfhama-ads}@anchor{2e1}
@section @code{Ada.Containers.Formal_Hashed_Maps} (@code{a-cfhama.ads})
@@ -23252,7 +23281,7 @@ efficient version than the one defined in the standard. In particular it
does not have the complex overhead required to detect cursor tampering.
@node Ada Containers Formal_Hashed_Sets a-cfhase ads,Ada Containers Formal_Ordered_Maps a-cforma ads,Ada Containers Formal_Hashed_Maps a-cfhama ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id9}@anchor{2de}@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-sets-a-cfhase-ads}@anchor{2df}
+@anchor{gnat_rm/the_gnat_library id9}@anchor{2e2}@anchor{gnat_rm/the_gnat_library ada-containers-formal-hashed-sets-a-cfhase-ads}@anchor{2e3}
@section @code{Ada.Containers.Formal_Hashed_Sets} (@code{a-cfhase.ads})
@@ -23271,7 +23300,7 @@ efficient version than the one defined in the standard. In particular it
does not have the complex overhead required to detect cursor tampering.
@node Ada Containers Formal_Ordered_Maps a-cforma ads,Ada Containers Formal_Ordered_Sets a-cforse ads,Ada Containers Formal_Hashed_Sets a-cfhase ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id10}@anchor{2e0}@anchor{gnat_rm/the_gnat_library ada-containers-formal-ordered-maps-a-cforma-ads}@anchor{2e1}
+@anchor{gnat_rm/the_gnat_library id10}@anchor{2e4}@anchor{gnat_rm/the_gnat_library ada-containers-formal-ordered-maps-a-cforma-ads}@anchor{2e5}
@section @code{Ada.Containers.Formal_Ordered_Maps} (@code{a-cforma.ads})
@@ -23290,7 +23319,7 @@ efficient version than the one defined in the standard. In particular it
does not have the complex overhead required to detect cursor tampering.
@node Ada Containers Formal_Ordered_Sets a-cforse ads,Ada Containers Formal_Vectors a-cofove ads,Ada Containers Formal_Ordered_Maps a-cforma ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-containers-formal-ordered-sets-a-cforse-ads}@anchor{2e2}@anchor{gnat_rm/the_gnat_library id11}@anchor{2e3}
+@anchor{gnat_rm/the_gnat_library ada-containers-formal-ordered-sets-a-cforse-ads}@anchor{2e6}@anchor{gnat_rm/the_gnat_library id11}@anchor{2e7}
@section @code{Ada.Containers.Formal_Ordered_Sets} (@code{a-cforse.ads})
@@ -23309,7 +23338,7 @@ efficient version than the one defined in the standard. In particular it
does not have the complex overhead required to detect cursor tampering.
@node Ada Containers Formal_Vectors a-cofove ads,Ada Containers Formal_Indefinite_Vectors a-cfinve ads,Ada Containers Formal_Ordered_Sets a-cforse ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id12}@anchor{2e4}@anchor{gnat_rm/the_gnat_library ada-containers-formal-vectors-a-cofove-ads}@anchor{2e5}
+@anchor{gnat_rm/the_gnat_library id12}@anchor{2e8}@anchor{gnat_rm/the_gnat_library ada-containers-formal-vectors-a-cofove-ads}@anchor{2e9}
@section @code{Ada.Containers.Formal_Vectors} (@code{a-cofove.ads})
@@ -23328,7 +23357,7 @@ efficient version than the one defined in the standard. In particular it
does not have the complex overhead required to detect cursor tampering.
@node Ada Containers Formal_Indefinite_Vectors a-cfinve ads,Ada Containers Functional_Vectors a-cofuve ads,Ada Containers Formal_Vectors a-cofove ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id13}@anchor{2e6}@anchor{gnat_rm/the_gnat_library ada-containers-formal-indefinite-vectors-a-cfinve-ads}@anchor{2e7}
+@anchor{gnat_rm/the_gnat_library id13}@anchor{2ea}@anchor{gnat_rm/the_gnat_library ada-containers-formal-indefinite-vectors-a-cfinve-ads}@anchor{2eb}
@section @code{Ada.Containers.Formal_Indefinite_Vectors} (@code{a-cfinve.ads})
@@ -23347,7 +23376,7 @@ efficient version than the one defined in the standard. In particular it
does not have the complex overhead required to detect cursor tampering.
@node Ada Containers Functional_Vectors a-cofuve ads,Ada Containers Functional_Sets a-cofuse ads,Ada Containers Formal_Indefinite_Vectors a-cfinve ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id14}@anchor{2e8}@anchor{gnat_rm/the_gnat_library ada-containers-functional-vectors-a-cofuve-ads}@anchor{2e9}
+@anchor{gnat_rm/the_gnat_library id14}@anchor{2ec}@anchor{gnat_rm/the_gnat_library ada-containers-functional-vectors-a-cofuve-ads}@anchor{2ed}
@section @code{Ada.Containers.Functional_Vectors} (@code{a-cofuve.ads})
@@ -23369,7 +23398,7 @@ and annotations, so that they can be removed from the final executable. The
specification of this unit is compatible with SPARK 2014.
@node Ada Containers Functional_Sets a-cofuse ads,Ada Containers Functional_Maps a-cofuma ads,Ada Containers Functional_Vectors a-cofuve ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-containers-functional-sets-a-cofuse-ads}@anchor{2ea}@anchor{gnat_rm/the_gnat_library id15}@anchor{2eb}
+@anchor{gnat_rm/the_gnat_library ada-containers-functional-sets-a-cofuse-ads}@anchor{2ee}@anchor{gnat_rm/the_gnat_library id15}@anchor{2ef}
@section @code{Ada.Containers.Functional_Sets} (@code{a-cofuse.ads})
@@ -23391,7 +23420,7 @@ and annotations, so that they can be removed from the final executable. The
specification of this unit is compatible with SPARK 2014.
@node Ada Containers Functional_Maps a-cofuma ads,Ada Containers Bounded_Holders a-coboho ads,Ada Containers Functional_Sets a-cofuse ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id16}@anchor{2ec}@anchor{gnat_rm/the_gnat_library ada-containers-functional-maps-a-cofuma-ads}@anchor{2ed}
+@anchor{gnat_rm/the_gnat_library id16}@anchor{2f0}@anchor{gnat_rm/the_gnat_library ada-containers-functional-maps-a-cofuma-ads}@anchor{2f1}
@section @code{Ada.Containers.Functional_Maps} (@code{a-cofuma.ads})
@@ -23413,7 +23442,7 @@ and annotations, so that they can be removed from the final executable. The
specification of this unit is compatible with SPARK 2014.
@node Ada Containers Bounded_Holders a-coboho ads,Ada Command_Line Environment a-colien ads,Ada Containers Functional_Maps a-cofuma ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-containers-bounded-holders-a-coboho-ads}@anchor{2ee}@anchor{gnat_rm/the_gnat_library id17}@anchor{2ef}
+@anchor{gnat_rm/the_gnat_library ada-containers-bounded-holders-a-coboho-ads}@anchor{2f2}@anchor{gnat_rm/the_gnat_library id17}@anchor{2f3}
@section @code{Ada.Containers.Bounded_Holders} (@code{a-coboho.ads})
@@ -23425,7 +23454,7 @@ This child of @code{Ada.Containers} defines a modified version of
Indefinite_Holders that avoids heap allocation.
@node Ada Command_Line Environment a-colien ads,Ada Command_Line Remove a-colire ads,Ada Containers Bounded_Holders a-coboho ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-command-line-environment-a-colien-ads}@anchor{2f0}@anchor{gnat_rm/the_gnat_library id18}@anchor{2f1}
+@anchor{gnat_rm/the_gnat_library ada-command-line-environment-a-colien-ads}@anchor{2f4}@anchor{gnat_rm/the_gnat_library id18}@anchor{2f5}
@section @code{Ada.Command_Line.Environment} (@code{a-colien.ads})
@@ -23438,7 +23467,7 @@ provides a mechanism for obtaining environment values on systems
where this concept makes sense.
@node Ada Command_Line Remove a-colire ads,Ada Command_Line Response_File a-clrefi ads,Ada Command_Line Environment a-colien ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id19}@anchor{2f2}@anchor{gnat_rm/the_gnat_library ada-command-line-remove-a-colire-ads}@anchor{2f3}
+@anchor{gnat_rm/the_gnat_library id19}@anchor{2f6}@anchor{gnat_rm/the_gnat_library ada-command-line-remove-a-colire-ads}@anchor{2f7}
@section @code{Ada.Command_Line.Remove} (@code{a-colire.ads})
@@ -23456,7 +23485,7 @@ to further calls on the subprograms in @code{Ada.Command_Line} will not
see the removed argument.
@node Ada Command_Line Response_File a-clrefi ads,Ada Direct_IO C_Streams a-diocst ads,Ada Command_Line Remove a-colire ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id20}@anchor{2f4}@anchor{gnat_rm/the_gnat_library ada-command-line-response-file-a-clrefi-ads}@anchor{2f5}
+@anchor{gnat_rm/the_gnat_library id20}@anchor{2f8}@anchor{gnat_rm/the_gnat_library ada-command-line-response-file-a-clrefi-ads}@anchor{2f9}
@section @code{Ada.Command_Line.Response_File} (@code{a-clrefi.ads})
@@ -23476,7 +23505,7 @@ Using a response file allow passing a set of arguments to an executable longer
than the maximum allowed by the system on the command line.
@node Ada Direct_IO C_Streams a-diocst ads,Ada Exceptions Is_Null_Occurrence a-einuoc ads,Ada Command_Line Response_File a-clrefi ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id21}@anchor{2f6}@anchor{gnat_rm/the_gnat_library ada-direct-io-c-streams-a-diocst-ads}@anchor{2f7}
+@anchor{gnat_rm/the_gnat_library id21}@anchor{2fa}@anchor{gnat_rm/the_gnat_library ada-direct-io-c-streams-a-diocst-ads}@anchor{2fb}
@section @code{Ada.Direct_IO.C_Streams} (@code{a-diocst.ads})
@@ -23491,7 +23520,7 @@ extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
@node Ada Exceptions Is_Null_Occurrence a-einuoc ads,Ada Exceptions Last_Chance_Handler a-elchha ads,Ada Direct_IO C_Streams a-diocst ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id22}@anchor{2f8}@anchor{gnat_rm/the_gnat_library ada-exceptions-is-null-occurrence-a-einuoc-ads}@anchor{2f9}
+@anchor{gnat_rm/the_gnat_library id22}@anchor{2fc}@anchor{gnat_rm/the_gnat_library ada-exceptions-is-null-occurrence-a-einuoc-ads}@anchor{2fd}
@section @code{Ada.Exceptions.Is_Null_Occurrence} (@code{a-einuoc.ads})
@@ -23505,7 +23534,7 @@ exception occurrence (@code{Null_Occurrence}) without raising
an exception.
@node Ada Exceptions Last_Chance_Handler a-elchha ads,Ada Exceptions Traceback a-exctra ads,Ada Exceptions Is_Null_Occurrence a-einuoc ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id23}@anchor{2fa}@anchor{gnat_rm/the_gnat_library ada-exceptions-last-chance-handler-a-elchha-ads}@anchor{2fb}
+@anchor{gnat_rm/the_gnat_library id23}@anchor{2fe}@anchor{gnat_rm/the_gnat_library ada-exceptions-last-chance-handler-a-elchha-ads}@anchor{2ff}
@section @code{Ada.Exceptions.Last_Chance_Handler} (@code{a-elchha.ads})
@@ -23519,7 +23548,7 @@ exceptions (hence the name last chance), and perform clean ups before
terminating the program. Note that this subprogram never returns.
@node Ada Exceptions Traceback a-exctra ads,Ada Sequential_IO C_Streams a-siocst ads,Ada Exceptions Last_Chance_Handler a-elchha ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-exceptions-traceback-a-exctra-ads}@anchor{2fc}@anchor{gnat_rm/the_gnat_library id24}@anchor{2fd}
+@anchor{gnat_rm/the_gnat_library ada-exceptions-traceback-a-exctra-ads}@anchor{300}@anchor{gnat_rm/the_gnat_library id24}@anchor{301}
@section @code{Ada.Exceptions.Traceback} (@code{a-exctra.ads})
@@ -23532,7 +23561,7 @@ give a traceback array of addresses based on an exception
occurrence.
@node Ada Sequential_IO C_Streams a-siocst ads,Ada Streams Stream_IO C_Streams a-ssicst ads,Ada Exceptions Traceback a-exctra ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-sequential-io-c-streams-a-siocst-ads}@anchor{2fe}@anchor{gnat_rm/the_gnat_library id25}@anchor{2ff}
+@anchor{gnat_rm/the_gnat_library ada-sequential-io-c-streams-a-siocst-ads}@anchor{302}@anchor{gnat_rm/the_gnat_library id25}@anchor{303}
@section @code{Ada.Sequential_IO.C_Streams} (@code{a-siocst.ads})
@@ -23547,7 +23576,7 @@ extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
@node Ada Streams Stream_IO C_Streams a-ssicst ads,Ada Strings Unbounded Text_IO a-suteio ads,Ada Sequential_IO C_Streams a-siocst ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id26}@anchor{300}@anchor{gnat_rm/the_gnat_library ada-streams-stream-io-c-streams-a-ssicst-ads}@anchor{301}
+@anchor{gnat_rm/the_gnat_library id26}@anchor{304}@anchor{gnat_rm/the_gnat_library ada-streams-stream-io-c-streams-a-ssicst-ads}@anchor{305}
@section @code{Ada.Streams.Stream_IO.C_Streams} (@code{a-ssicst.ads})
@@ -23562,7 +23591,7 @@ extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
@node Ada Strings Unbounded Text_IO a-suteio ads,Ada Strings Wide_Unbounded Wide_Text_IO a-swuwti ads,Ada Streams Stream_IO C_Streams a-ssicst ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-strings-unbounded-text-io-a-suteio-ads}@anchor{302}@anchor{gnat_rm/the_gnat_library id27}@anchor{303}
+@anchor{gnat_rm/the_gnat_library ada-strings-unbounded-text-io-a-suteio-ads}@anchor{306}@anchor{gnat_rm/the_gnat_library id27}@anchor{307}
@section @code{Ada.Strings.Unbounded.Text_IO} (@code{a-suteio.ads})
@@ -23579,7 +23608,7 @@ strings, avoiding the necessity for an intermediate operation
with ordinary strings.
@node Ada Strings Wide_Unbounded Wide_Text_IO a-swuwti ads,Ada Strings Wide_Wide_Unbounded Wide_Wide_Text_IO a-szuzti ads,Ada Strings Unbounded Text_IO a-suteio ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id28}@anchor{304}@anchor{gnat_rm/the_gnat_library ada-strings-wide-unbounded-wide-text-io-a-swuwti-ads}@anchor{305}
+@anchor{gnat_rm/the_gnat_library id28}@anchor{308}@anchor{gnat_rm/the_gnat_library ada-strings-wide-unbounded-wide-text-io-a-swuwti-ads}@anchor{309}
@section @code{Ada.Strings.Wide_Unbounded.Wide_Text_IO} (@code{a-swuwti.ads})
@@ -23596,7 +23625,7 @@ wide strings, avoiding the necessity for an intermediate operation
with ordinary wide strings.
@node Ada Strings Wide_Wide_Unbounded Wide_Wide_Text_IO a-szuzti ads,Ada Text_IO C_Streams a-tiocst ads,Ada Strings Wide_Unbounded Wide_Text_IO a-swuwti ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id29}@anchor{306}@anchor{gnat_rm/the_gnat_library ada-strings-wide-wide-unbounded-wide-wide-text-io-a-szuzti-ads}@anchor{307}
+@anchor{gnat_rm/the_gnat_library id29}@anchor{30a}@anchor{gnat_rm/the_gnat_library ada-strings-wide-wide-unbounded-wide-wide-text-io-a-szuzti-ads}@anchor{30b}
@section @code{Ada.Strings.Wide_Wide_Unbounded.Wide_Wide_Text_IO} (@code{a-szuzti.ads})
@@ -23613,7 +23642,7 @@ wide wide strings, avoiding the necessity for an intermediate operation
with ordinary wide wide strings.
@node Ada Text_IO C_Streams a-tiocst ads,Ada Text_IO Reset_Standard_Files a-tirsfi ads,Ada Strings Wide_Wide_Unbounded Wide_Wide_Text_IO a-szuzti ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-text-io-c-streams-a-tiocst-ads}@anchor{308}@anchor{gnat_rm/the_gnat_library id30}@anchor{309}
+@anchor{gnat_rm/the_gnat_library ada-text-io-c-streams-a-tiocst-ads}@anchor{30c}@anchor{gnat_rm/the_gnat_library id30}@anchor{30d}
@section @code{Ada.Text_IO.C_Streams} (@code{a-tiocst.ads})
@@ -23628,7 +23657,7 @@ extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
@node Ada Text_IO Reset_Standard_Files a-tirsfi ads,Ada Wide_Characters Unicode a-wichun ads,Ada Text_IO C_Streams a-tiocst ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-text-io-reset-standard-files-a-tirsfi-ads}@anchor{30a}@anchor{gnat_rm/the_gnat_library id31}@anchor{30b}
+@anchor{gnat_rm/the_gnat_library ada-text-io-reset-standard-files-a-tirsfi-ads}@anchor{30e}@anchor{gnat_rm/the_gnat_library id31}@anchor{30f}
@section @code{Ada.Text_IO.Reset_Standard_Files} (@code{a-tirsfi.ads})
@@ -23643,7 +23672,7 @@ execution (for example a standard input file may be redefined to be
interactive).
@node Ada Wide_Characters Unicode a-wichun ads,Ada Wide_Text_IO C_Streams a-wtcstr ads,Ada Text_IO Reset_Standard_Files a-tirsfi ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id32}@anchor{30c}@anchor{gnat_rm/the_gnat_library ada-wide-characters-unicode-a-wichun-ads}@anchor{30d}
+@anchor{gnat_rm/the_gnat_library id32}@anchor{310}@anchor{gnat_rm/the_gnat_library ada-wide-characters-unicode-a-wichun-ads}@anchor{311}
@section @code{Ada.Wide_Characters.Unicode} (@code{a-wichun.ads})
@@ -23656,7 +23685,7 @@ This package provides subprograms that allow categorization of
Wide_Character values according to Unicode categories.
@node Ada Wide_Text_IO C_Streams a-wtcstr ads,Ada Wide_Text_IO Reset_Standard_Files a-wrstfi ads,Ada Wide_Characters Unicode a-wichun ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-wide-text-io-c-streams-a-wtcstr-ads}@anchor{30e}@anchor{gnat_rm/the_gnat_library id33}@anchor{30f}
+@anchor{gnat_rm/the_gnat_library ada-wide-text-io-c-streams-a-wtcstr-ads}@anchor{312}@anchor{gnat_rm/the_gnat_library id33}@anchor{313}
@section @code{Ada.Wide_Text_IO.C_Streams} (@code{a-wtcstr.ads})
@@ -23671,7 +23700,7 @@ extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
@node Ada Wide_Text_IO Reset_Standard_Files a-wrstfi ads,Ada Wide_Wide_Characters Unicode a-zchuni ads,Ada Wide_Text_IO C_Streams a-wtcstr ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library ada-wide-text-io-reset-standard-files-a-wrstfi-ads}@anchor{310}@anchor{gnat_rm/the_gnat_library id34}@anchor{311}
+@anchor{gnat_rm/the_gnat_library ada-wide-text-io-reset-standard-files-a-wrstfi-ads}@anchor{314}@anchor{gnat_rm/the_gnat_library id34}@anchor{315}
@section @code{Ada.Wide_Text_IO.Reset_Standard_Files} (@code{a-wrstfi.ads})
@@ -23686,7 +23715,7 @@ execution (for example a standard input file may be redefined to be
interactive).
@node Ada Wide_Wide_Characters Unicode a-zchuni ads,Ada Wide_Wide_Text_IO C_Streams a-ztcstr ads,Ada Wide_Text_IO Reset_Standard_Files a-wrstfi ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id35}@anchor{312}@anchor{gnat_rm/the_gnat_library ada-wide-wide-characters-unicode-a-zchuni-ads}@anchor{313}
+@anchor{gnat_rm/the_gnat_library id35}@anchor{316}@anchor{gnat_rm/the_gnat_library ada-wide-wide-characters-unicode-a-zchuni-ads}@anchor{317}
@section @code{Ada.Wide_Wide_Characters.Unicode} (@code{a-zchuni.ads})
@@ -23699,7 +23728,7 @@ This package provides subprograms that allow categorization of
Wide_Wide_Character values according to Unicode categories.
@node Ada Wide_Wide_Text_IO C_Streams a-ztcstr ads,Ada Wide_Wide_Text_IO Reset_Standard_Files a-zrstfi ads,Ada Wide_Wide_Characters Unicode a-zchuni ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id36}@anchor{314}@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-c-streams-a-ztcstr-ads}@anchor{315}
+@anchor{gnat_rm/the_gnat_library id36}@anchor{318}@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-c-streams-a-ztcstr-ads}@anchor{319}
@section @code{Ada.Wide_Wide_Text_IO.C_Streams} (@code{a-ztcstr.ads})
@@ -23714,7 +23743,7 @@ extracted from a file opened on the Ada side, and an Ada file
can be constructed from a stream opened on the C side.
@node Ada Wide_Wide_Text_IO Reset_Standard_Files a-zrstfi ads,GNAT Altivec g-altive ads,Ada Wide_Wide_Text_IO C_Streams a-ztcstr ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id37}@anchor{316}@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-reset-standard-files-a-zrstfi-ads}@anchor{317}
+@anchor{gnat_rm/the_gnat_library id37}@anchor{31a}@anchor{gnat_rm/the_gnat_library ada-wide-wide-text-io-reset-standard-files-a-zrstfi-ads}@anchor{31b}
@section @code{Ada.Wide_Wide_Text_IO.Reset_Standard_Files} (@code{a-zrstfi.ads})
@@ -23729,7 +23758,7 @@ change during execution (for example a standard input file may be
redefined to be interactive).
@node GNAT Altivec g-altive ads,GNAT Altivec Conversions g-altcon ads,Ada Wide_Wide_Text_IO Reset_Standard_Files a-zrstfi ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-altivec-g-altive-ads}@anchor{318}@anchor{gnat_rm/the_gnat_library id38}@anchor{319}
+@anchor{gnat_rm/the_gnat_library gnat-altivec-g-altive-ads}@anchor{31c}@anchor{gnat_rm/the_gnat_library id38}@anchor{31d}
@section @code{GNAT.Altivec} (@code{g-altive.ads})
@@ -23742,7 +23771,7 @@ definitions of constants and types common to all the versions of the
binding.
@node GNAT Altivec Conversions g-altcon ads,GNAT Altivec Vector_Operations g-alveop ads,GNAT Altivec g-altive ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-altivec-conversions-g-altcon-ads}@anchor{31a}@anchor{gnat_rm/the_gnat_library id39}@anchor{31b}
+@anchor{gnat_rm/the_gnat_library gnat-altivec-conversions-g-altcon-ads}@anchor{31e}@anchor{gnat_rm/the_gnat_library id39}@anchor{31f}
@section @code{GNAT.Altivec.Conversions} (@code{g-altcon.ads})
@@ -23753,7 +23782,7 @@ binding.
This package provides the Vector/View conversion routines.
@node GNAT Altivec Vector_Operations g-alveop ads,GNAT Altivec Vector_Types g-alvety ads,GNAT Altivec Conversions g-altcon ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-operations-g-alveop-ads}@anchor{31c}@anchor{gnat_rm/the_gnat_library id40}@anchor{31d}
+@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-operations-g-alveop-ads}@anchor{320}@anchor{gnat_rm/the_gnat_library id40}@anchor{321}
@section @code{GNAT.Altivec.Vector_Operations} (@code{g-alveop.ads})
@@ -23767,7 +23796,7 @@ library. The hard binding is provided as a separate package. This unit
is common to both bindings.
@node GNAT Altivec Vector_Types g-alvety ads,GNAT Altivec Vector_Views g-alvevi ads,GNAT Altivec Vector_Operations g-alveop ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-types-g-alvety-ads}@anchor{31e}@anchor{gnat_rm/the_gnat_library id41}@anchor{31f}
+@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-types-g-alvety-ads}@anchor{322}@anchor{gnat_rm/the_gnat_library id41}@anchor{323}
@section @code{GNAT.Altivec.Vector_Types} (@code{g-alvety.ads})
@@ -23779,7 +23808,7 @@ This package exposes the various vector types part of the Ada binding
to AltiVec facilities.
@node GNAT Altivec Vector_Views g-alvevi ads,GNAT Array_Split g-arrspl ads,GNAT Altivec Vector_Types g-alvety ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-views-g-alvevi-ads}@anchor{320}@anchor{gnat_rm/the_gnat_library id42}@anchor{321}
+@anchor{gnat_rm/the_gnat_library gnat-altivec-vector-views-g-alvevi-ads}@anchor{324}@anchor{gnat_rm/the_gnat_library id42}@anchor{325}
@section @code{GNAT.Altivec.Vector_Views} (@code{g-alvevi.ads})
@@ -23794,7 +23823,7 @@ vector elements and provides a simple way to initialize vector
objects.
@node GNAT Array_Split g-arrspl ads,GNAT AWK g-awk ads,GNAT Altivec Vector_Views g-alvevi ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-array-split-g-arrspl-ads}@anchor{322}@anchor{gnat_rm/the_gnat_library id43}@anchor{323}
+@anchor{gnat_rm/the_gnat_library gnat-array-split-g-arrspl-ads}@anchor{326}@anchor{gnat_rm/the_gnat_library id43}@anchor{327}
@section @code{GNAT.Array_Split} (@code{g-arrspl.ads})
@@ -23807,7 +23836,7 @@ an array wherever the separators appear, and provide direct access
to the resulting slices.
@node GNAT AWK g-awk ads,GNAT Bind_Environment g-binenv ads,GNAT Array_Split g-arrspl ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id44}@anchor{324}@anchor{gnat_rm/the_gnat_library gnat-awk-g-awk-ads}@anchor{325}
+@anchor{gnat_rm/the_gnat_library id44}@anchor{328}@anchor{gnat_rm/the_gnat_library gnat-awk-g-awk-ads}@anchor{329}
@section @code{GNAT.AWK} (@code{g-awk.ads})
@@ -23822,7 +23851,7 @@ or more files containing formatted data. The file is viewed as a database
where each record is a line and a field is a data element in this line.
@node GNAT Bind_Environment g-binenv ads,GNAT Branch_Prediction g-brapre ads,GNAT AWK g-awk ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-bind-environment-g-binenv-ads}@anchor{326}@anchor{gnat_rm/the_gnat_library id45}@anchor{327}
+@anchor{gnat_rm/the_gnat_library gnat-bind-environment-g-binenv-ads}@anchor{32a}@anchor{gnat_rm/the_gnat_library id45}@anchor{32b}
@section @code{GNAT.Bind_Environment} (@code{g-binenv.ads})
@@ -23835,7 +23864,7 @@ These associations can be specified using the @code{-V} binder command
line switch.
@node GNAT Branch_Prediction g-brapre ads,GNAT Bounded_Buffers g-boubuf ads,GNAT Bind_Environment g-binenv ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id46}@anchor{328}@anchor{gnat_rm/the_gnat_library gnat-branch-prediction-g-brapre-ads}@anchor{329}
+@anchor{gnat_rm/the_gnat_library id46}@anchor{32c}@anchor{gnat_rm/the_gnat_library gnat-branch-prediction-g-brapre-ads}@anchor{32d}
@section @code{GNAT.Branch_Prediction} (@code{g-brapre.ads})
@@ -23846,7 +23875,7 @@ line switch.
Provides routines giving hints to the branch predictor of the code generator.
@node GNAT Bounded_Buffers g-boubuf ads,GNAT Bounded_Mailboxes g-boumai ads,GNAT Branch_Prediction g-brapre ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id47}@anchor{32a}@anchor{gnat_rm/the_gnat_library gnat-bounded-buffers-g-boubuf-ads}@anchor{32b}
+@anchor{gnat_rm/the_gnat_library id47}@anchor{32e}@anchor{gnat_rm/the_gnat_library gnat-bounded-buffers-g-boubuf-ads}@anchor{32f}
@section @code{GNAT.Bounded_Buffers} (@code{g-boubuf.ads})
@@ -23861,7 +23890,7 @@ useful directly or as parts of the implementations of other abstractions,
such as mailboxes.
@node GNAT Bounded_Mailboxes g-boumai ads,GNAT Bubble_Sort g-bubsor ads,GNAT Bounded_Buffers g-boubuf ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-bounded-mailboxes-g-boumai-ads}@anchor{32c}@anchor{gnat_rm/the_gnat_library id48}@anchor{32d}
+@anchor{gnat_rm/the_gnat_library gnat-bounded-mailboxes-g-boumai-ads}@anchor{330}@anchor{gnat_rm/the_gnat_library id48}@anchor{331}
@section @code{GNAT.Bounded_Mailboxes} (@code{g-boumai.ads})
@@ -23874,7 +23903,7 @@ such as mailboxes.
Provides a thread-safe asynchronous intertask mailbox communication facility.
@node GNAT Bubble_Sort g-bubsor ads,GNAT Bubble_Sort_A g-busora ads,GNAT Bounded_Mailboxes g-boumai ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-bubsor-ads}@anchor{32e}@anchor{gnat_rm/the_gnat_library id49}@anchor{32f}
+@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-bubsor-ads}@anchor{332}@anchor{gnat_rm/the_gnat_library id49}@anchor{333}
@section @code{GNAT.Bubble_Sort} (@code{g-bubsor.ads})
@@ -23889,7 +23918,7 @@ data items. Exchange and comparison procedures are provided by passing
access-to-procedure values.
@node GNAT Bubble_Sort_A g-busora ads,GNAT Bubble_Sort_G g-busorg ads,GNAT Bubble_Sort g-bubsor ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id50}@anchor{330}@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-a-g-busora-ads}@anchor{331}
+@anchor{gnat_rm/the_gnat_library id50}@anchor{334}@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-a-g-busora-ads}@anchor{335}
@section @code{GNAT.Bubble_Sort_A} (@code{g-busora.ads})
@@ -23905,7 +23934,7 @@ access-to-procedure values. This is an older version, retained for
compatibility. Usually @code{GNAT.Bubble_Sort} will be preferable.
@node GNAT Bubble_Sort_G g-busorg ads,GNAT Byte_Order_Mark g-byorma ads,GNAT Bubble_Sort_A g-busora ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-g-busorg-ads}@anchor{332}@anchor{gnat_rm/the_gnat_library id51}@anchor{333}
+@anchor{gnat_rm/the_gnat_library gnat-bubble-sort-g-g-busorg-ads}@anchor{336}@anchor{gnat_rm/the_gnat_library id51}@anchor{337}
@section @code{GNAT.Bubble_Sort_G} (@code{g-busorg.ads})
@@ -23921,7 +23950,7 @@ if the procedures can be inlined, at the expense of duplicating code for
multiple instantiations.
@node GNAT Byte_Order_Mark g-byorma ads,GNAT Byte_Swapping g-bytswa ads,GNAT Bubble_Sort_G g-busorg ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-byte-order-mark-g-byorma-ads}@anchor{334}@anchor{gnat_rm/the_gnat_library id52}@anchor{335}
+@anchor{gnat_rm/the_gnat_library gnat-byte-order-mark-g-byorma-ads}@anchor{338}@anchor{gnat_rm/the_gnat_library id52}@anchor{339}
@section @code{GNAT.Byte_Order_Mark} (@code{g-byorma.ads})
@@ -23937,7 +23966,7 @@ the encoding of the string. The routine includes detection of special XML
sequences for various UCS input formats.
@node GNAT Byte_Swapping g-bytswa ads,GNAT Calendar g-calend ads,GNAT Byte_Order_Mark g-byorma ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-byte-swapping-g-bytswa-ads}@anchor{336}@anchor{gnat_rm/the_gnat_library id53}@anchor{337}
+@anchor{gnat_rm/the_gnat_library gnat-byte-swapping-g-bytswa-ads}@anchor{33a}@anchor{gnat_rm/the_gnat_library id53}@anchor{33b}
@section @code{GNAT.Byte_Swapping} (@code{g-bytswa.ads})
@@ -23951,7 +23980,7 @@ General routines for swapping the bytes in 2-, 4-, and 8-byte quantities.
Machine-specific implementations are available in some cases.
@node GNAT Calendar g-calend ads,GNAT Calendar Time_IO g-catiio ads,GNAT Byte_Swapping g-bytswa ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id54}@anchor{338}@anchor{gnat_rm/the_gnat_library gnat-calendar-g-calend-ads}@anchor{339}
+@anchor{gnat_rm/the_gnat_library id54}@anchor{33c}@anchor{gnat_rm/the_gnat_library gnat-calendar-g-calend-ads}@anchor{33d}
@section @code{GNAT.Calendar} (@code{g-calend.ads})
@@ -23965,7 +23994,7 @@ Also provides conversion of @code{Ada.Calendar.Time} values to and from the
C @code{timeval} format.
@node GNAT Calendar Time_IO g-catiio ads,GNAT CRC32 g-crc32 ads,GNAT Calendar g-calend ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id55}@anchor{33a}@anchor{gnat_rm/the_gnat_library gnat-calendar-time-io-g-catiio-ads}@anchor{33b}
+@anchor{gnat_rm/the_gnat_library id55}@anchor{33e}@anchor{gnat_rm/the_gnat_library gnat-calendar-time-io-g-catiio-ads}@anchor{33f}
@section @code{GNAT.Calendar.Time_IO} (@code{g-catiio.ads})
@@ -23976,7 +24005,7 @@ C @code{timeval} format.
@geindex GNAT.Calendar.Time_IO (g-catiio.ads)
@node GNAT CRC32 g-crc32 ads,GNAT Case_Util g-casuti ads,GNAT Calendar Time_IO g-catiio ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id56}@anchor{33c}@anchor{gnat_rm/the_gnat_library gnat-crc32-g-crc32-ads}@anchor{33d}
+@anchor{gnat_rm/the_gnat_library id56}@anchor{340}@anchor{gnat_rm/the_gnat_library gnat-crc32-g-crc32-ads}@anchor{341}
@section @code{GNAT.CRC32} (@code{g-crc32.ads})
@@ -23993,7 +24022,7 @@ of this algorithm see
Aug. 1988. Sarwate, D.V.
@node GNAT Case_Util g-casuti ads,GNAT CGI g-cgi ads,GNAT CRC32 g-crc32 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id57}@anchor{33e}@anchor{gnat_rm/the_gnat_library gnat-case-util-g-casuti-ads}@anchor{33f}
+@anchor{gnat_rm/the_gnat_library id57}@anchor{342}@anchor{gnat_rm/the_gnat_library gnat-case-util-g-casuti-ads}@anchor{343}
@section @code{GNAT.Case_Util} (@code{g-casuti.ads})
@@ -24008,7 +24037,7 @@ without the overhead of the full casing tables
in @code{Ada.Characters.Handling}.
@node GNAT CGI g-cgi ads,GNAT CGI Cookie g-cgicoo ads,GNAT Case_Util g-casuti ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id58}@anchor{340}@anchor{gnat_rm/the_gnat_library gnat-cgi-g-cgi-ads}@anchor{341}
+@anchor{gnat_rm/the_gnat_library id58}@anchor{344}@anchor{gnat_rm/the_gnat_library gnat-cgi-g-cgi-ads}@anchor{345}
@section @code{GNAT.CGI} (@code{g-cgi.ads})
@@ -24023,7 +24052,7 @@ builds a table whose index is the key and provides some services to deal
with this table.
@node GNAT CGI Cookie g-cgicoo ads,GNAT CGI Debug g-cgideb ads,GNAT CGI g-cgi ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-cgi-cookie-g-cgicoo-ads}@anchor{342}@anchor{gnat_rm/the_gnat_library id59}@anchor{343}
+@anchor{gnat_rm/the_gnat_library gnat-cgi-cookie-g-cgicoo-ads}@anchor{346}@anchor{gnat_rm/the_gnat_library id59}@anchor{347}
@section @code{GNAT.CGI.Cookie} (@code{g-cgicoo.ads})
@@ -24038,7 +24067,7 @@ Common Gateway Interface (CGI). It exports services to deal with Web
cookies (piece of information kept in the Web client software).
@node GNAT CGI Debug g-cgideb ads,GNAT Command_Line g-comlin ads,GNAT CGI Cookie g-cgicoo ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-cgi-debug-g-cgideb-ads}@anchor{344}@anchor{gnat_rm/the_gnat_library id60}@anchor{345}
+@anchor{gnat_rm/the_gnat_library gnat-cgi-debug-g-cgideb-ads}@anchor{348}@anchor{gnat_rm/the_gnat_library id60}@anchor{349}
@section @code{GNAT.CGI.Debug} (@code{g-cgideb.ads})
@@ -24050,7 +24079,7 @@ This is a package to help debugging CGI (Common Gateway Interface)
programs written in Ada.
@node GNAT Command_Line g-comlin ads,GNAT Compiler_Version g-comver ads,GNAT CGI Debug g-cgideb ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id61}@anchor{346}@anchor{gnat_rm/the_gnat_library gnat-command-line-g-comlin-ads}@anchor{347}
+@anchor{gnat_rm/the_gnat_library id61}@anchor{34a}@anchor{gnat_rm/the_gnat_library gnat-command-line-g-comlin-ads}@anchor{34b}
@section @code{GNAT.Command_Line} (@code{g-comlin.ads})
@@ -24063,7 +24092,7 @@ including the ability to scan for named switches with optional parameters
and expand file names using wildcard notations.
@node GNAT Compiler_Version g-comver ads,GNAT Ctrl_C g-ctrl_c ads,GNAT Command_Line g-comlin ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-compiler-version-g-comver-ads}@anchor{348}@anchor{gnat_rm/the_gnat_library id62}@anchor{349}
+@anchor{gnat_rm/the_gnat_library gnat-compiler-version-g-comver-ads}@anchor{34c}@anchor{gnat_rm/the_gnat_library id62}@anchor{34d}
@section @code{GNAT.Compiler_Version} (@code{g-comver.ads})
@@ -24081,7 +24110,7 @@ of the compiler if a consistent tool set is used to compile all units
of a partition).
@node GNAT Ctrl_C g-ctrl_c ads,GNAT Current_Exception g-curexc ads,GNAT Compiler_Version g-comver ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-ctrl-c-g-ctrl-c-ads}@anchor{34a}@anchor{gnat_rm/the_gnat_library id63}@anchor{34b}
+@anchor{gnat_rm/the_gnat_library gnat-ctrl-c-g-ctrl-c-ads}@anchor{34e}@anchor{gnat_rm/the_gnat_library id63}@anchor{34f}
@section @code{GNAT.Ctrl_C} (@code{g-ctrl_c.ads})
@@ -24092,7 +24121,7 @@ of a partition).
Provides a simple interface to handle Ctrl-C keyboard events.
@node GNAT Current_Exception g-curexc ads,GNAT Debug_Pools g-debpoo ads,GNAT Ctrl_C g-ctrl_c ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id64}@anchor{34c}@anchor{gnat_rm/the_gnat_library gnat-current-exception-g-curexc-ads}@anchor{34d}
+@anchor{gnat_rm/the_gnat_library id64}@anchor{350}@anchor{gnat_rm/the_gnat_library gnat-current-exception-g-curexc-ads}@anchor{351}
@section @code{GNAT.Current_Exception} (@code{g-curexc.ads})
@@ -24109,7 +24138,7 @@ This is particularly useful in simulating typical facilities for
obtaining information about exceptions provided by Ada 83 compilers.
@node GNAT Debug_Pools g-debpoo ads,GNAT Debug_Utilities g-debuti ads,GNAT Current_Exception g-curexc ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-debug-pools-g-debpoo-ads}@anchor{34e}@anchor{gnat_rm/the_gnat_library id65}@anchor{34f}
+@anchor{gnat_rm/the_gnat_library gnat-debug-pools-g-debpoo-ads}@anchor{352}@anchor{gnat_rm/the_gnat_library id65}@anchor{353}
@section @code{GNAT.Debug_Pools} (@code{g-debpoo.ads})
@@ -24126,7 +24155,7 @@ problems.
See @code{The GNAT Debug_Pool Facility} section in the @cite{GNAT User's Guide}.
@node GNAT Debug_Utilities g-debuti ads,GNAT Decode_String g-decstr ads,GNAT Debug_Pools g-debpoo ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-debug-utilities-g-debuti-ads}@anchor{350}@anchor{gnat_rm/the_gnat_library id66}@anchor{351}
+@anchor{gnat_rm/the_gnat_library gnat-debug-utilities-g-debuti-ads}@anchor{354}@anchor{gnat_rm/the_gnat_library id66}@anchor{355}
@section @code{GNAT.Debug_Utilities} (@code{g-debuti.ads})
@@ -24139,7 +24168,7 @@ to and from string images of address values. Supports both C and Ada formats
for hexadecimal literals.
@node GNAT Decode_String g-decstr ads,GNAT Decode_UTF8_String g-deutst ads,GNAT Debug_Utilities g-debuti ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id67}@anchor{352}@anchor{gnat_rm/the_gnat_library gnat-decode-string-g-decstr-ads}@anchor{353}
+@anchor{gnat_rm/the_gnat_library id67}@anchor{356}@anchor{gnat_rm/the_gnat_library gnat-decode-string-g-decstr-ads}@anchor{357}
@section @code{GNAT.Decode_String} (@code{g-decstr.ads})
@@ -24163,7 +24192,7 @@ Useful in conjunction with Unicode character coding. Note there is a
preinstantiation for UTF-8. See next entry.
@node GNAT Decode_UTF8_String g-deutst ads,GNAT Directory_Operations g-dirope ads,GNAT Decode_String g-decstr ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-decode-utf8-string-g-deutst-ads}@anchor{354}@anchor{gnat_rm/the_gnat_library id68}@anchor{355}
+@anchor{gnat_rm/the_gnat_library gnat-decode-utf8-string-g-deutst-ads}@anchor{358}@anchor{gnat_rm/the_gnat_library id68}@anchor{359}
@section @code{GNAT.Decode_UTF8_String} (@code{g-deutst.ads})
@@ -24184,7 +24213,7 @@ preinstantiation for UTF-8. See next entry.
A preinstantiation of GNAT.Decode_Strings for UTF-8 encoding.
@node GNAT Directory_Operations g-dirope ads,GNAT Directory_Operations Iteration g-diopit ads,GNAT Decode_UTF8_String g-deutst ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id69}@anchor{356}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-g-dirope-ads}@anchor{357}
+@anchor{gnat_rm/the_gnat_library id69}@anchor{35a}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-g-dirope-ads}@anchor{35b}
@section @code{GNAT.Directory_Operations} (@code{g-dirope.ads})
@@ -24197,7 +24226,7 @@ the current directory, making new directories, and scanning the files in a
directory.
@node GNAT Directory_Operations Iteration g-diopit ads,GNAT Dynamic_HTables g-dynhta ads,GNAT Directory_Operations g-dirope ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id70}@anchor{358}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-iteration-g-diopit-ads}@anchor{359}
+@anchor{gnat_rm/the_gnat_library id70}@anchor{35c}@anchor{gnat_rm/the_gnat_library gnat-directory-operations-iteration-g-diopit-ads}@anchor{35d}
@section @code{GNAT.Directory_Operations.Iteration} (@code{g-diopit.ads})
@@ -24209,7 +24238,7 @@ A child unit of GNAT.Directory_Operations providing additional operations
for iterating through directories.
@node GNAT Dynamic_HTables g-dynhta ads,GNAT Dynamic_Tables g-dyntab ads,GNAT Directory_Operations Iteration g-diopit ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id71}@anchor{35a}@anchor{gnat_rm/the_gnat_library gnat-dynamic-htables-g-dynhta-ads}@anchor{35b}
+@anchor{gnat_rm/the_gnat_library id71}@anchor{35e}@anchor{gnat_rm/the_gnat_library gnat-dynamic-htables-g-dynhta-ads}@anchor{35f}
@section @code{GNAT.Dynamic_HTables} (@code{g-dynhta.ads})
@@ -24227,7 +24256,7 @@ dynamic instances of the hash table, while an instantiation of
@code{GNAT.HTable} creates a single instance of the hash table.
@node GNAT Dynamic_Tables g-dyntab ads,GNAT Encode_String g-encstr ads,GNAT Dynamic_HTables g-dynhta ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-dynamic-tables-g-dyntab-ads}@anchor{35c}@anchor{gnat_rm/the_gnat_library id72}@anchor{35d}
+@anchor{gnat_rm/the_gnat_library gnat-dynamic-tables-g-dyntab-ads}@anchor{360}@anchor{gnat_rm/the_gnat_library id72}@anchor{361}
@section @code{GNAT.Dynamic_Tables} (@code{g-dyntab.ads})
@@ -24247,7 +24276,7 @@ dynamic instances of the table, while an instantiation of
@code{GNAT.Table} creates a single instance of the table type.
@node GNAT Encode_String g-encstr ads,GNAT Encode_UTF8_String g-enutst ads,GNAT Dynamic_Tables g-dyntab ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id73}@anchor{35e}@anchor{gnat_rm/the_gnat_library gnat-encode-string-g-encstr-ads}@anchor{35f}
+@anchor{gnat_rm/the_gnat_library id73}@anchor{362}@anchor{gnat_rm/the_gnat_library gnat-encode-string-g-encstr-ads}@anchor{363}
@section @code{GNAT.Encode_String} (@code{g-encstr.ads})
@@ -24269,7 +24298,7 @@ encoding method. Useful in conjunction with Unicode character coding.
Note there is a preinstantiation for UTF-8. See next entry.
@node GNAT Encode_UTF8_String g-enutst ads,GNAT Exception_Actions g-excact ads,GNAT Encode_String g-encstr ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-encode-utf8-string-g-enutst-ads}@anchor{360}@anchor{gnat_rm/the_gnat_library id74}@anchor{361}
+@anchor{gnat_rm/the_gnat_library gnat-encode-utf8-string-g-enutst-ads}@anchor{364}@anchor{gnat_rm/the_gnat_library id74}@anchor{365}
@section @code{GNAT.Encode_UTF8_String} (@code{g-enutst.ads})
@@ -24290,7 +24319,7 @@ Note there is a preinstantiation for UTF-8. See next entry.
A preinstantiation of GNAT.Encode_Strings for UTF-8 encoding.
@node GNAT Exception_Actions g-excact ads,GNAT Exception_Traces g-exctra ads,GNAT Encode_UTF8_String g-enutst ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-exception-actions-g-excact-ads}@anchor{362}@anchor{gnat_rm/the_gnat_library id75}@anchor{363}
+@anchor{gnat_rm/the_gnat_library gnat-exception-actions-g-excact-ads}@anchor{366}@anchor{gnat_rm/the_gnat_library id75}@anchor{367}
@section @code{GNAT.Exception_Actions} (@code{g-excact.ads})
@@ -24303,7 +24332,7 @@ for specific exceptions, or when any exception is raised. This
can be used for instance to force a core dump to ease debugging.
@node GNAT Exception_Traces g-exctra ads,GNAT Exceptions g-except ads,GNAT Exception_Actions g-excact ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-exception-traces-g-exctra-ads}@anchor{364}@anchor{gnat_rm/the_gnat_library id76}@anchor{365}
+@anchor{gnat_rm/the_gnat_library gnat-exception-traces-g-exctra-ads}@anchor{368}@anchor{gnat_rm/the_gnat_library id76}@anchor{369}
@section @code{GNAT.Exception_Traces} (@code{g-exctra.ads})
@@ -24317,7 +24346,7 @@ Provides an interface allowing to control automatic output upon exception
occurrences.
@node GNAT Exceptions g-except ads,GNAT Expect g-expect ads,GNAT Exception_Traces g-exctra ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id77}@anchor{366}@anchor{gnat_rm/the_gnat_library gnat-exceptions-g-except-ads}@anchor{367}
+@anchor{gnat_rm/the_gnat_library id77}@anchor{36a}@anchor{gnat_rm/the_gnat_library gnat-exceptions-g-except-ads}@anchor{36b}
@section @code{GNAT.Exceptions} (@code{g-except.ads})
@@ -24338,7 +24367,7 @@ predefined exceptions, and for example allow raising
@code{Constraint_Error} with a message from a pure subprogram.
@node GNAT Expect g-expect ads,GNAT Expect TTY g-exptty ads,GNAT Exceptions g-except ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id78}@anchor{368}@anchor{gnat_rm/the_gnat_library gnat-expect-g-expect-ads}@anchor{369}
+@anchor{gnat_rm/the_gnat_library id78}@anchor{36c}@anchor{gnat_rm/the_gnat_library gnat-expect-g-expect-ads}@anchor{36d}
@section @code{GNAT.Expect} (@code{g-expect.ads})
@@ -24354,7 +24383,7 @@ It is not implemented for cross ports, and in particular is not
implemented for VxWorks or LynxOS.
@node GNAT Expect TTY g-exptty ads,GNAT Float_Control g-flocon ads,GNAT Expect g-expect ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id79}@anchor{36a}@anchor{gnat_rm/the_gnat_library gnat-expect-tty-g-exptty-ads}@anchor{36b}
+@anchor{gnat_rm/the_gnat_library id79}@anchor{36e}@anchor{gnat_rm/the_gnat_library gnat-expect-tty-g-exptty-ads}@anchor{36f}
@section @code{GNAT.Expect.TTY} (@code{g-exptty.ads})
@@ -24366,7 +24395,7 @@ ports. It is not implemented for cross ports, and
in particular is not implemented for VxWorks or LynxOS.
@node GNAT Float_Control g-flocon ads,GNAT Formatted_String g-forstr ads,GNAT Expect TTY g-exptty ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id80}@anchor{36c}@anchor{gnat_rm/the_gnat_library gnat-float-control-g-flocon-ads}@anchor{36d}
+@anchor{gnat_rm/the_gnat_library id80}@anchor{370}@anchor{gnat_rm/the_gnat_library gnat-float-control-g-flocon-ads}@anchor{371}
@section @code{GNAT.Float_Control} (@code{g-flocon.ads})
@@ -24380,7 +24409,7 @@ library calls may cause this mode to be modified, and the Reset procedure
in this package can be used to reestablish the required mode.
@node GNAT Formatted_String g-forstr ads,GNAT Heap_Sort g-heasor ads,GNAT Float_Control g-flocon ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id81}@anchor{36e}@anchor{gnat_rm/the_gnat_library gnat-formatted-string-g-forstr-ads}@anchor{36f}
+@anchor{gnat_rm/the_gnat_library id81}@anchor{372}@anchor{gnat_rm/the_gnat_library gnat-formatted-string-g-forstr-ads}@anchor{373}
@section @code{GNAT.Formatted_String} (@code{g-forstr.ads})
@@ -24395,7 +24424,7 @@ derived from Integer, Float or enumerations as values for the
formatted string.
@node GNAT Heap_Sort g-heasor ads,GNAT Heap_Sort_A g-hesora ads,GNAT Formatted_String g-forstr ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-heasor-ads}@anchor{370}@anchor{gnat_rm/the_gnat_library id82}@anchor{371}
+@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-heasor-ads}@anchor{374}@anchor{gnat_rm/the_gnat_library id82}@anchor{375}
@section @code{GNAT.Heap_Sort} (@code{g-heasor.ads})
@@ -24409,7 +24438,7 @@ access-to-procedure values. The algorithm used is a modified heap sort
that performs approximately N*log(N) comparisons in the worst case.
@node GNAT Heap_Sort_A g-hesora ads,GNAT Heap_Sort_G g-hesorg ads,GNAT Heap_Sort g-heasor ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id83}@anchor{372}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-a-g-hesora-ads}@anchor{373}
+@anchor{gnat_rm/the_gnat_library id83}@anchor{376}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-a-g-hesora-ads}@anchor{377}
@section @code{GNAT.Heap_Sort_A} (@code{g-hesora.ads})
@@ -24425,7 +24454,7 @@ This differs from @code{GNAT.Heap_Sort} in having a less convenient
interface, but may be slightly more efficient.
@node GNAT Heap_Sort_G g-hesorg ads,GNAT HTable g-htable ads,GNAT Heap_Sort_A g-hesora ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id84}@anchor{374}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-g-hesorg-ads}@anchor{375}
+@anchor{gnat_rm/the_gnat_library id84}@anchor{378}@anchor{gnat_rm/the_gnat_library gnat-heap-sort-g-g-hesorg-ads}@anchor{379}
@section @code{GNAT.Heap_Sort_G} (@code{g-hesorg.ads})
@@ -24439,7 +24468,7 @@ if the procedures can be inlined, at the expense of duplicating code for
multiple instantiations.
@node GNAT HTable g-htable ads,GNAT IO g-io ads,GNAT Heap_Sort_G g-hesorg ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id85}@anchor{376}@anchor{gnat_rm/the_gnat_library gnat-htable-g-htable-ads}@anchor{377}
+@anchor{gnat_rm/the_gnat_library id85}@anchor{37a}@anchor{gnat_rm/the_gnat_library gnat-htable-g-htable-ads}@anchor{37b}
@section @code{GNAT.HTable} (@code{g-htable.ads})
@@ -24452,7 +24481,7 @@ data. Provides two approaches, one a simple static approach, and the other
allowing arbitrary dynamic hash tables.
@node GNAT IO g-io ads,GNAT IO_Aux g-io_aux ads,GNAT HTable g-htable ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id86}@anchor{378}@anchor{gnat_rm/the_gnat_library gnat-io-g-io-ads}@anchor{379}
+@anchor{gnat_rm/the_gnat_library id86}@anchor{37c}@anchor{gnat_rm/the_gnat_library gnat-io-g-io-ads}@anchor{37d}
@section @code{GNAT.IO} (@code{g-io.ads})
@@ -24468,7 +24497,7 @@ Standard_Input, and writing characters, strings and integers to either
Standard_Output or Standard_Error.
@node GNAT IO_Aux g-io_aux ads,GNAT Lock_Files g-locfil ads,GNAT IO g-io ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id87}@anchor{37a}@anchor{gnat_rm/the_gnat_library gnat-io-aux-g-io-aux-ads}@anchor{37b}
+@anchor{gnat_rm/the_gnat_library id87}@anchor{37e}@anchor{gnat_rm/the_gnat_library gnat-io-aux-g-io-aux-ads}@anchor{37f}
@section @code{GNAT.IO_Aux} (@code{g-io_aux.ads})
@@ -24482,7 +24511,7 @@ Provides some auxiliary functions for use with Text_IO, including a test
for whether a file exists, and functions for reading a line of text.
@node GNAT Lock_Files g-locfil ads,GNAT MBBS_Discrete_Random g-mbdira ads,GNAT IO_Aux g-io_aux ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id88}@anchor{37c}@anchor{gnat_rm/the_gnat_library gnat-lock-files-g-locfil-ads}@anchor{37d}
+@anchor{gnat_rm/the_gnat_library id88}@anchor{380}@anchor{gnat_rm/the_gnat_library gnat-lock-files-g-locfil-ads}@anchor{381}
@section @code{GNAT.Lock_Files} (@code{g-locfil.ads})
@@ -24496,7 +24525,7 @@ Provides a general interface for using files as locks. Can be used for
providing program level synchronization.
@node GNAT MBBS_Discrete_Random g-mbdira ads,GNAT MBBS_Float_Random g-mbflra ads,GNAT Lock_Files g-locfil ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id89}@anchor{37e}@anchor{gnat_rm/the_gnat_library gnat-mbbs-discrete-random-g-mbdira-ads}@anchor{37f}
+@anchor{gnat_rm/the_gnat_library id89}@anchor{382}@anchor{gnat_rm/the_gnat_library gnat-mbbs-discrete-random-g-mbdira-ads}@anchor{383}
@section @code{GNAT.MBBS_Discrete_Random} (@code{g-mbdira.ads})
@@ -24508,7 +24537,7 @@ The original implementation of @code{Ada.Numerics.Discrete_Random}. Uses
a modified version of the Blum-Blum-Shub generator.
@node GNAT MBBS_Float_Random g-mbflra ads,GNAT MD5 g-md5 ads,GNAT MBBS_Discrete_Random g-mbdira ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id90}@anchor{380}@anchor{gnat_rm/the_gnat_library gnat-mbbs-float-random-g-mbflra-ads}@anchor{381}
+@anchor{gnat_rm/the_gnat_library id90}@anchor{384}@anchor{gnat_rm/the_gnat_library gnat-mbbs-float-random-g-mbflra-ads}@anchor{385}
@section @code{GNAT.MBBS_Float_Random} (@code{g-mbflra.ads})
@@ -24520,7 +24549,7 @@ The original implementation of @code{Ada.Numerics.Float_Random}. Uses
a modified version of the Blum-Blum-Shub generator.
@node GNAT MD5 g-md5 ads,GNAT Memory_Dump g-memdum ads,GNAT MBBS_Float_Random g-mbflra ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id91}@anchor{382}@anchor{gnat_rm/the_gnat_library gnat-md5-g-md5-ads}@anchor{383}
+@anchor{gnat_rm/the_gnat_library id91}@anchor{386}@anchor{gnat_rm/the_gnat_library gnat-md5-g-md5-ads}@anchor{387}
@section @code{GNAT.MD5} (@code{g-md5.ads})
@@ -24533,7 +24562,7 @@ the HMAC-MD5 message authentication function as described in RFC 2104 and
FIPS PUB 198.
@node GNAT Memory_Dump g-memdum ads,GNAT Most_Recent_Exception g-moreex ads,GNAT MD5 g-md5 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id92}@anchor{384}@anchor{gnat_rm/the_gnat_library gnat-memory-dump-g-memdum-ads}@anchor{385}
+@anchor{gnat_rm/the_gnat_library id92}@anchor{388}@anchor{gnat_rm/the_gnat_library gnat-memory-dump-g-memdum-ads}@anchor{389}
@section @code{GNAT.Memory_Dump} (@code{g-memdum.ads})
@@ -24546,7 +24575,7 @@ standard output or standard error files. Uses GNAT.IO for actual
output.
@node GNAT Most_Recent_Exception g-moreex ads,GNAT OS_Lib g-os_lib ads,GNAT Memory_Dump g-memdum ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-most-recent-exception-g-moreex-ads}@anchor{386}@anchor{gnat_rm/the_gnat_library id93}@anchor{387}
+@anchor{gnat_rm/the_gnat_library gnat-most-recent-exception-g-moreex-ads}@anchor{38a}@anchor{gnat_rm/the_gnat_library id93}@anchor{38b}
@section @code{GNAT.Most_Recent_Exception} (@code{g-moreex.ads})
@@ -24560,7 +24589,7 @@ various logging purposes, including duplicating functionality of some
Ada 83 implementation dependent extensions.
@node GNAT OS_Lib g-os_lib ads,GNAT Perfect_Hash_Generators g-pehage ads,GNAT Most_Recent_Exception g-moreex ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-os-lib-g-os-lib-ads}@anchor{388}@anchor{gnat_rm/the_gnat_library id94}@anchor{389}
+@anchor{gnat_rm/the_gnat_library gnat-os-lib-g-os-lib-ads}@anchor{38c}@anchor{gnat_rm/the_gnat_library id94}@anchor{38d}
@section @code{GNAT.OS_Lib} (@code{g-os_lib.ads})
@@ -24576,7 +24605,7 @@ including a portable spawn procedure, and access to environment variables
and error return codes.
@node GNAT Perfect_Hash_Generators g-pehage ads,GNAT Random_Numbers g-rannum ads,GNAT OS_Lib g-os_lib ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-perfect-hash-generators-g-pehage-ads}@anchor{38a}@anchor{gnat_rm/the_gnat_library id95}@anchor{38b}
+@anchor{gnat_rm/the_gnat_library gnat-perfect-hash-generators-g-pehage-ads}@anchor{38e}@anchor{gnat_rm/the_gnat_library id95}@anchor{38f}
@section @code{GNAT.Perfect_Hash_Generators} (@code{g-pehage.ads})
@@ -24594,7 +24623,7 @@ hashcode are in the same order. These hashing functions are very
convenient for use with realtime applications.
@node GNAT Random_Numbers g-rannum ads,GNAT Regexp g-regexp ads,GNAT Perfect_Hash_Generators g-pehage ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-random-numbers-g-rannum-ads}@anchor{38c}@anchor{gnat_rm/the_gnat_library id96}@anchor{38d}
+@anchor{gnat_rm/the_gnat_library gnat-random-numbers-g-rannum-ads}@anchor{390}@anchor{gnat_rm/the_gnat_library id96}@anchor{391}
@section @code{GNAT.Random_Numbers} (@code{g-rannum.ads})
@@ -24606,7 +24635,7 @@ Provides random number capabilities which extend those available in the
standard Ada library and are more convenient to use.
@node GNAT Regexp g-regexp ads,GNAT Registry g-regist ads,GNAT Random_Numbers g-rannum ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-regexp-g-regexp-ads}@anchor{255}@anchor{gnat_rm/the_gnat_library id97}@anchor{38e}
+@anchor{gnat_rm/the_gnat_library gnat-regexp-g-regexp-ads}@anchor{259}@anchor{gnat_rm/the_gnat_library id97}@anchor{392}
@section @code{GNAT.Regexp} (@code{g-regexp.ads})
@@ -24622,7 +24651,7 @@ simplest of the three pattern matching packages provided, and is particularly
suitable for 'file globbing' applications.
@node GNAT Registry g-regist ads,GNAT Regpat g-regpat ads,GNAT Regexp g-regexp ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id98}@anchor{38f}@anchor{gnat_rm/the_gnat_library gnat-registry-g-regist-ads}@anchor{390}
+@anchor{gnat_rm/the_gnat_library id98}@anchor{393}@anchor{gnat_rm/the_gnat_library gnat-registry-g-regist-ads}@anchor{394}
@section @code{GNAT.Registry} (@code{g-regist.ads})
@@ -24636,7 +24665,7 @@ registry API, but at a lower level of abstraction, refer to the Win32.Winreg
package provided with the Win32Ada binding
@node GNAT Regpat g-regpat ads,GNAT Rewrite_Data g-rewdat ads,GNAT Registry g-regist ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id99}@anchor{391}@anchor{gnat_rm/the_gnat_library gnat-regpat-g-regpat-ads}@anchor{392}
+@anchor{gnat_rm/the_gnat_library id99}@anchor{395}@anchor{gnat_rm/the_gnat_library gnat-regpat-g-regpat-ads}@anchor{396}
@section @code{GNAT.Regpat} (@code{g-regpat.ads})
@@ -24651,7 +24680,7 @@ from the original V7 style regular expression library written in C by
Henry Spencer (and binary compatible with this C library).
@node GNAT Rewrite_Data g-rewdat ads,GNAT Secondary_Stack_Info g-sestin ads,GNAT Regpat g-regpat ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id100}@anchor{393}@anchor{gnat_rm/the_gnat_library gnat-rewrite-data-g-rewdat-ads}@anchor{394}
+@anchor{gnat_rm/the_gnat_library id100}@anchor{397}@anchor{gnat_rm/the_gnat_library gnat-rewrite-data-g-rewdat-ads}@anchor{398}
@section @code{GNAT.Rewrite_Data} (@code{g-rewdat.ads})
@@ -24665,7 +24694,7 @@ full content to be processed is not loaded into memory all at once. This makes
this interface usable for large files or socket streams.
@node GNAT Secondary_Stack_Info g-sestin ads,GNAT Semaphores g-semaph ads,GNAT Rewrite_Data g-rewdat ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id101}@anchor{395}@anchor{gnat_rm/the_gnat_library gnat-secondary-stack-info-g-sestin-ads}@anchor{396}
+@anchor{gnat_rm/the_gnat_library id101}@anchor{399}@anchor{gnat_rm/the_gnat_library gnat-secondary-stack-info-g-sestin-ads}@anchor{39a}
@section @code{GNAT.Secondary_Stack_Info} (@code{g-sestin.ads})
@@ -24677,7 +24706,7 @@ Provide the capability to query the high water mark of the current task's
secondary stack.
@node GNAT Semaphores g-semaph ads,GNAT Serial_Communications g-sercom ads,GNAT Secondary_Stack_Info g-sestin ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id102}@anchor{397}@anchor{gnat_rm/the_gnat_library gnat-semaphores-g-semaph-ads}@anchor{398}
+@anchor{gnat_rm/the_gnat_library id102}@anchor{39b}@anchor{gnat_rm/the_gnat_library gnat-semaphores-g-semaph-ads}@anchor{39c}
@section @code{GNAT.Semaphores} (@code{g-semaph.ads})
@@ -24688,7 +24717,7 @@ secondary stack.
Provides classic counting and binary semaphores using protected types.
@node GNAT Serial_Communications g-sercom ads,GNAT SHA1 g-sha1 ads,GNAT Semaphores g-semaph ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-serial-communications-g-sercom-ads}@anchor{399}@anchor{gnat_rm/the_gnat_library id103}@anchor{39a}
+@anchor{gnat_rm/the_gnat_library gnat-serial-communications-g-sercom-ads}@anchor{39d}@anchor{gnat_rm/the_gnat_library id103}@anchor{39e}
@section @code{GNAT.Serial_Communications} (@code{g-sercom.ads})
@@ -24700,7 +24729,7 @@ Provides a simple interface to send and receive data over a serial
port. This is only supported on GNU/Linux and Windows.
@node GNAT SHA1 g-sha1 ads,GNAT SHA224 g-sha224 ads,GNAT Serial_Communications g-sercom ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sha1-g-sha1-ads}@anchor{39b}@anchor{gnat_rm/the_gnat_library id104}@anchor{39c}
+@anchor{gnat_rm/the_gnat_library gnat-sha1-g-sha1-ads}@anchor{39f}@anchor{gnat_rm/the_gnat_library id104}@anchor{3a0}
@section @code{GNAT.SHA1} (@code{g-sha1.ads})
@@ -24713,7 +24742,7 @@ and RFC 3174, and the HMAC-SHA1 message authentication function as described
in RFC 2104 and FIPS PUB 198.
@node GNAT SHA224 g-sha224 ads,GNAT SHA256 g-sha256 ads,GNAT SHA1 g-sha1 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sha224-g-sha224-ads}@anchor{39d}@anchor{gnat_rm/the_gnat_library id105}@anchor{39e}
+@anchor{gnat_rm/the_gnat_library gnat-sha224-g-sha224-ads}@anchor{3a1}@anchor{gnat_rm/the_gnat_library id105}@anchor{3a2}
@section @code{GNAT.SHA224} (@code{g-sha224.ads})
@@ -24726,7 +24755,7 @@ and the HMAC-SHA224 message authentication function as described
in RFC 2104 and FIPS PUB 198.
@node GNAT SHA256 g-sha256 ads,GNAT SHA384 g-sha384 ads,GNAT SHA224 g-sha224 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sha256-g-sha256-ads}@anchor{39f}@anchor{gnat_rm/the_gnat_library id106}@anchor{3a0}
+@anchor{gnat_rm/the_gnat_library gnat-sha256-g-sha256-ads}@anchor{3a3}@anchor{gnat_rm/the_gnat_library id106}@anchor{3a4}
@section @code{GNAT.SHA256} (@code{g-sha256.ads})
@@ -24739,7 +24768,7 @@ and the HMAC-SHA256 message authentication function as described
in RFC 2104 and FIPS PUB 198.
@node GNAT SHA384 g-sha384 ads,GNAT SHA512 g-sha512 ads,GNAT SHA256 g-sha256 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sha384-g-sha384-ads}@anchor{3a1}@anchor{gnat_rm/the_gnat_library id107}@anchor{3a2}
+@anchor{gnat_rm/the_gnat_library gnat-sha384-g-sha384-ads}@anchor{3a5}@anchor{gnat_rm/the_gnat_library id107}@anchor{3a6}
@section @code{GNAT.SHA384} (@code{g-sha384.ads})
@@ -24752,7 +24781,7 @@ and the HMAC-SHA384 message authentication function as described
in RFC 2104 and FIPS PUB 198.
@node GNAT SHA512 g-sha512 ads,GNAT Signals g-signal ads,GNAT SHA384 g-sha384 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id108}@anchor{3a3}@anchor{gnat_rm/the_gnat_library gnat-sha512-g-sha512-ads}@anchor{3a4}
+@anchor{gnat_rm/the_gnat_library id108}@anchor{3a7}@anchor{gnat_rm/the_gnat_library gnat-sha512-g-sha512-ads}@anchor{3a8}
@section @code{GNAT.SHA512} (@code{g-sha512.ads})
@@ -24765,7 +24794,7 @@ and the HMAC-SHA512 message authentication function as described
in RFC 2104 and FIPS PUB 198.
@node GNAT Signals g-signal ads,GNAT Sockets g-socket ads,GNAT SHA512 g-sha512 ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id109}@anchor{3a5}@anchor{gnat_rm/the_gnat_library gnat-signals-g-signal-ads}@anchor{3a6}
+@anchor{gnat_rm/the_gnat_library id109}@anchor{3a9}@anchor{gnat_rm/the_gnat_library gnat-signals-g-signal-ads}@anchor{3aa}
@section @code{GNAT.Signals} (@code{g-signal.ads})
@@ -24777,7 +24806,7 @@ Provides the ability to manipulate the blocked status of signals on supported
targets.
@node GNAT Sockets g-socket ads,GNAT Source_Info g-souinf ads,GNAT Signals g-signal ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sockets-g-socket-ads}@anchor{3a7}@anchor{gnat_rm/the_gnat_library id110}@anchor{3a8}
+@anchor{gnat_rm/the_gnat_library gnat-sockets-g-socket-ads}@anchor{3ab}@anchor{gnat_rm/the_gnat_library id110}@anchor{3ac}
@section @code{GNAT.Sockets} (@code{g-socket.ads})
@@ -24792,7 +24821,7 @@ on all native GNAT ports and on VxWorks cross prots. It is not implemented for
the LynxOS cross port.
@node GNAT Source_Info g-souinf ads,GNAT Spelling_Checker g-speche ads,GNAT Sockets g-socket ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-source-info-g-souinf-ads}@anchor{3a9}@anchor{gnat_rm/the_gnat_library id111}@anchor{3aa}
+@anchor{gnat_rm/the_gnat_library gnat-source-info-g-souinf-ads}@anchor{3ad}@anchor{gnat_rm/the_gnat_library id111}@anchor{3ae}
@section @code{GNAT.Source_Info} (@code{g-souinf.ads})
@@ -24806,7 +24835,7 @@ subprograms yielding the date and time of the current compilation (like the
C macros @code{__DATE__} and @code{__TIME__})
@node GNAT Spelling_Checker g-speche ads,GNAT Spelling_Checker_Generic g-spchge ads,GNAT Source_Info g-souinf ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id112}@anchor{3ab}@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-g-speche-ads}@anchor{3ac}
+@anchor{gnat_rm/the_gnat_library id112}@anchor{3af}@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-g-speche-ads}@anchor{3b0}
@section @code{GNAT.Spelling_Checker} (@code{g-speche.ads})
@@ -24818,7 +24847,7 @@ Provides a function for determining whether one string is a plausible
near misspelling of another string.
@node GNAT Spelling_Checker_Generic g-spchge ads,GNAT Spitbol Patterns g-spipat ads,GNAT Spelling_Checker g-speche ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-generic-g-spchge-ads}@anchor{3ad}@anchor{gnat_rm/the_gnat_library id113}@anchor{3ae}
+@anchor{gnat_rm/the_gnat_library gnat-spelling-checker-generic-g-spchge-ads}@anchor{3b1}@anchor{gnat_rm/the_gnat_library id113}@anchor{3b2}
@section @code{GNAT.Spelling_Checker_Generic} (@code{g-spchge.ads})
@@ -24831,7 +24860,7 @@ determining whether one string is a plausible near misspelling of another
string.
@node GNAT Spitbol Patterns g-spipat ads,GNAT Spitbol g-spitbo ads,GNAT Spelling_Checker_Generic g-spchge ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-spitbol-patterns-g-spipat-ads}@anchor{3af}@anchor{gnat_rm/the_gnat_library id114}@anchor{3b0}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-patterns-g-spipat-ads}@anchor{3b3}@anchor{gnat_rm/the_gnat_library id114}@anchor{3b4}
@section @code{GNAT.Spitbol.Patterns} (@code{g-spipat.ads})
@@ -24847,7 +24876,7 @@ the SNOBOL4 dynamic pattern construction and matching capabilities, using the
efficient algorithm developed by Robert Dewar for the SPITBOL system.
@node GNAT Spitbol g-spitbo ads,GNAT Spitbol Table_Boolean g-sptabo ads,GNAT Spitbol Patterns g-spipat ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-spitbol-g-spitbo-ads}@anchor{3b1}@anchor{gnat_rm/the_gnat_library id115}@anchor{3b2}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-g-spitbo-ads}@anchor{3b5}@anchor{gnat_rm/the_gnat_library id115}@anchor{3b6}
@section @code{GNAT.Spitbol} (@code{g-spitbo.ads})
@@ -24862,7 +24891,7 @@ useful for constructing arbitrary mappings from strings in the style of
the SNOBOL4 TABLE function.
@node GNAT Spitbol Table_Boolean g-sptabo ads,GNAT Spitbol Table_Integer g-sptain ads,GNAT Spitbol g-spitbo ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id116}@anchor{3b3}@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-boolean-g-sptabo-ads}@anchor{3b4}
+@anchor{gnat_rm/the_gnat_library id116}@anchor{3b7}@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-boolean-g-sptabo-ads}@anchor{3b8}
@section @code{GNAT.Spitbol.Table_Boolean} (@code{g-sptabo.ads})
@@ -24877,7 +24906,7 @@ for type @code{Standard.Boolean}, giving an implementation of sets of
string values.
@node GNAT Spitbol Table_Integer g-sptain ads,GNAT Spitbol Table_VString g-sptavs ads,GNAT Spitbol Table_Boolean g-sptabo ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-integer-g-sptain-ads}@anchor{3b5}@anchor{gnat_rm/the_gnat_library id117}@anchor{3b6}
+@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-integer-g-sptain-ads}@anchor{3b9}@anchor{gnat_rm/the_gnat_library id117}@anchor{3ba}
@section @code{GNAT.Spitbol.Table_Integer} (@code{g-sptain.ads})
@@ -24894,7 +24923,7 @@ for type @code{Standard.Integer}, giving an implementation of maps
from string to integer values.
@node GNAT Spitbol Table_VString g-sptavs ads,GNAT SSE g-sse ads,GNAT Spitbol Table_Integer g-sptain ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id118}@anchor{3b7}@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-vstring-g-sptavs-ads}@anchor{3b8}
+@anchor{gnat_rm/the_gnat_library id118}@anchor{3bb}@anchor{gnat_rm/the_gnat_library gnat-spitbol-table-vstring-g-sptavs-ads}@anchor{3bc}
@section @code{GNAT.Spitbol.Table_VString} (@code{g-sptavs.ads})
@@ -24911,7 +24940,7 @@ a variable length string type, giving an implementation of general
maps from strings to strings.
@node GNAT SSE g-sse ads,GNAT SSE Vector_Types g-ssvety ads,GNAT Spitbol Table_VString g-sptavs ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id119}@anchor{3b9}@anchor{gnat_rm/the_gnat_library gnat-sse-g-sse-ads}@anchor{3ba}
+@anchor{gnat_rm/the_gnat_library id119}@anchor{3bd}@anchor{gnat_rm/the_gnat_library gnat-sse-g-sse-ads}@anchor{3be}
@section @code{GNAT.SSE} (@code{g-sse.ads})
@@ -24923,7 +24952,7 @@ targets. It exposes vector component types together with a general
introduction to the binding contents and use.
@node GNAT SSE Vector_Types g-ssvety ads,GNAT String_Hash g-strhas ads,GNAT SSE g-sse ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-sse-vector-types-g-ssvety-ads}@anchor{3bb}@anchor{gnat_rm/the_gnat_library id120}@anchor{3bc}
+@anchor{gnat_rm/the_gnat_library gnat-sse-vector-types-g-ssvety-ads}@anchor{3bf}@anchor{gnat_rm/the_gnat_library id120}@anchor{3c0}
@section @code{GNAT.SSE.Vector_Types} (@code{g-ssvety.ads})
@@ -24932,7 +24961,7 @@ introduction to the binding contents and use.
SSE vector types for use with SSE related intrinsics.
@node GNAT String_Hash g-strhas ads,GNAT Strings g-string ads,GNAT SSE Vector_Types g-ssvety ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-string-hash-g-strhas-ads}@anchor{3bd}@anchor{gnat_rm/the_gnat_library id121}@anchor{3be}
+@anchor{gnat_rm/the_gnat_library gnat-string-hash-g-strhas-ads}@anchor{3c1}@anchor{gnat_rm/the_gnat_library id121}@anchor{3c2}
@section @code{GNAT.String_Hash} (@code{g-strhas.ads})
@@ -24944,7 +24973,7 @@ Provides a generic hash function working on arrays of scalars. Both the scalar
type and the hash result type are parameters.
@node GNAT Strings g-string ads,GNAT String_Split g-strspl ads,GNAT String_Hash g-strhas ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-strings-g-string-ads}@anchor{3bf}@anchor{gnat_rm/the_gnat_library id122}@anchor{3c0}
+@anchor{gnat_rm/the_gnat_library gnat-strings-g-string-ads}@anchor{3c3}@anchor{gnat_rm/the_gnat_library id122}@anchor{3c4}
@section @code{GNAT.Strings} (@code{g-string.ads})
@@ -24954,7 +24983,7 @@ Common String access types and related subprograms. Basically it
defines a string access and an array of string access types.
@node GNAT String_Split g-strspl ads,GNAT Table g-table ads,GNAT Strings g-string ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-string-split-g-strspl-ads}@anchor{3c1}@anchor{gnat_rm/the_gnat_library id123}@anchor{3c2}
+@anchor{gnat_rm/the_gnat_library gnat-string-split-g-strspl-ads}@anchor{3c5}@anchor{gnat_rm/the_gnat_library id123}@anchor{3c6}
@section @code{GNAT.String_Split} (@code{g-strspl.ads})
@@ -24968,7 +24997,7 @@ to the resulting slices. This package is instantiated from
@code{GNAT.Array_Split}.
@node GNAT Table g-table ads,GNAT Task_Lock g-tasloc ads,GNAT String_Split g-strspl ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id124}@anchor{3c3}@anchor{gnat_rm/the_gnat_library gnat-table-g-table-ads}@anchor{3c4}
+@anchor{gnat_rm/the_gnat_library id124}@anchor{3c7}@anchor{gnat_rm/the_gnat_library gnat-table-g-table-ads}@anchor{3c8}
@section @code{GNAT.Table} (@code{g-table.ads})
@@ -24988,7 +25017,7 @@ while an instantiation of @code{GNAT.Dynamic_Tables} creates a type that can be
used to define dynamic instances of the table.
@node GNAT Task_Lock g-tasloc ads,GNAT Time_Stamp g-timsta ads,GNAT Table g-table ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id125}@anchor{3c5}@anchor{gnat_rm/the_gnat_library gnat-task-lock-g-tasloc-ads}@anchor{3c6}
+@anchor{gnat_rm/the_gnat_library id125}@anchor{3c9}@anchor{gnat_rm/the_gnat_library gnat-task-lock-g-tasloc-ads}@anchor{3ca}
@section @code{GNAT.Task_Lock} (@code{g-tasloc.ads})
@@ -25005,7 +25034,7 @@ single global task lock. Appropriate for use in situations where contention
between tasks is very rarely expected.
@node GNAT Time_Stamp g-timsta ads,GNAT Threads g-thread ads,GNAT Task_Lock g-tasloc ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id126}@anchor{3c7}@anchor{gnat_rm/the_gnat_library gnat-time-stamp-g-timsta-ads}@anchor{3c8}
+@anchor{gnat_rm/the_gnat_library id126}@anchor{3cb}@anchor{gnat_rm/the_gnat_library gnat-time-stamp-g-timsta-ads}@anchor{3cc}
@section @code{GNAT.Time_Stamp} (@code{g-timsta.ads})
@@ -25020,7 +25049,7 @@ represents the current date and time in ISO 8601 format. This is a very simple
routine with minimal code and there are no dependencies on any other unit.
@node GNAT Threads g-thread ads,GNAT Traceback g-traceb ads,GNAT Time_Stamp g-timsta ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id127}@anchor{3c9}@anchor{gnat_rm/the_gnat_library gnat-threads-g-thread-ads}@anchor{3ca}
+@anchor{gnat_rm/the_gnat_library id127}@anchor{3cd}@anchor{gnat_rm/the_gnat_library gnat-threads-g-thread-ads}@anchor{3ce}
@section @code{GNAT.Threads} (@code{g-thread.ads})
@@ -25037,7 +25066,7 @@ further details if your program has threads that are created by a non-Ada
environment which then accesses Ada code.
@node GNAT Traceback g-traceb ads,GNAT Traceback Symbolic g-trasym ads,GNAT Threads g-thread ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id128}@anchor{3cb}@anchor{gnat_rm/the_gnat_library gnat-traceback-g-traceb-ads}@anchor{3cc}
+@anchor{gnat_rm/the_gnat_library id128}@anchor{3cf}@anchor{gnat_rm/the_gnat_library gnat-traceback-g-traceb-ads}@anchor{3d0}
@section @code{GNAT.Traceback} (@code{g-traceb.ads})
@@ -25049,7 +25078,7 @@ Provides a facility for obtaining non-symbolic traceback information, useful
in various debugging situations.
@node GNAT Traceback Symbolic g-trasym ads,GNAT UTF_32 g-table ads,GNAT Traceback g-traceb ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-traceback-symbolic-g-trasym-ads}@anchor{3cd}@anchor{gnat_rm/the_gnat_library id129}@anchor{3ce}
+@anchor{gnat_rm/the_gnat_library gnat-traceback-symbolic-g-trasym-ads}@anchor{3d1}@anchor{gnat_rm/the_gnat_library id129}@anchor{3d2}
@section @code{GNAT.Traceback.Symbolic} (@code{g-trasym.ads})
@@ -25058,7 +25087,7 @@ in various debugging situations.
@geindex Trace back facilities
@node GNAT UTF_32 g-table ads,GNAT Wide_Spelling_Checker g-u3spch ads,GNAT Traceback Symbolic g-trasym ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id130}@anchor{3cf}@anchor{gnat_rm/the_gnat_library gnat-utf-32-g-table-ads}@anchor{3d0}
+@anchor{gnat_rm/the_gnat_library id130}@anchor{3d3}@anchor{gnat_rm/the_gnat_library gnat-utf-32-g-table-ads}@anchor{3d4}
@section @code{GNAT.UTF_32} (@code{g-table.ads})
@@ -25077,7 +25106,7 @@ lower case to upper case fold routine corresponding to
the Ada 2005 rules for identifier equivalence.
@node GNAT Wide_Spelling_Checker g-u3spch ads,GNAT Wide_Spelling_Checker g-wispch ads,GNAT UTF_32 g-table ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-u3spch-ads}@anchor{3d1}@anchor{gnat_rm/the_gnat_library id131}@anchor{3d2}
+@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-u3spch-ads}@anchor{3d5}@anchor{gnat_rm/the_gnat_library id131}@anchor{3d6}
@section @code{GNAT.Wide_Spelling_Checker} (@code{g-u3spch.ads})
@@ -25090,7 +25119,7 @@ near misspelling of another wide wide string, where the strings are represented
using the UTF_32_String type defined in System.Wch_Cnv.
@node GNAT Wide_Spelling_Checker g-wispch ads,GNAT Wide_String_Split g-wistsp ads,GNAT Wide_Spelling_Checker g-u3spch ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-wispch-ads}@anchor{3d3}@anchor{gnat_rm/the_gnat_library id132}@anchor{3d4}
+@anchor{gnat_rm/the_gnat_library gnat-wide-spelling-checker-g-wispch-ads}@anchor{3d7}@anchor{gnat_rm/the_gnat_library id132}@anchor{3d8}
@section @code{GNAT.Wide_Spelling_Checker} (@code{g-wispch.ads})
@@ -25102,7 +25131,7 @@ Provides a function for determining whether one wide string is a plausible
near misspelling of another wide string.
@node GNAT Wide_String_Split g-wistsp ads,GNAT Wide_Wide_Spelling_Checker g-zspche ads,GNAT Wide_Spelling_Checker g-wispch ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id133}@anchor{3d5}@anchor{gnat_rm/the_gnat_library gnat-wide-string-split-g-wistsp-ads}@anchor{3d6}
+@anchor{gnat_rm/the_gnat_library id133}@anchor{3d9}@anchor{gnat_rm/the_gnat_library gnat-wide-string-split-g-wistsp-ads}@anchor{3da}
@section @code{GNAT.Wide_String_Split} (@code{g-wistsp.ads})
@@ -25116,7 +25145,7 @@ to the resulting slices. This package is instantiated from
@code{GNAT.Array_Split}.
@node GNAT Wide_Wide_Spelling_Checker g-zspche ads,GNAT Wide_Wide_String_Split g-zistsp ads,GNAT Wide_String_Split g-wistsp ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-wide-wide-spelling-checker-g-zspche-ads}@anchor{3d7}@anchor{gnat_rm/the_gnat_library id134}@anchor{3d8}
+@anchor{gnat_rm/the_gnat_library gnat-wide-wide-spelling-checker-g-zspche-ads}@anchor{3db}@anchor{gnat_rm/the_gnat_library id134}@anchor{3dc}
@section @code{GNAT.Wide_Wide_Spelling_Checker} (@code{g-zspche.ads})
@@ -25128,7 +25157,7 @@ Provides a function for determining whether one wide wide string is a plausible
near misspelling of another wide wide string.
@node GNAT Wide_Wide_String_Split g-zistsp ads,Interfaces C Extensions i-cexten ads,GNAT Wide_Wide_Spelling_Checker g-zspche ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library gnat-wide-wide-string-split-g-zistsp-ads}@anchor{3d9}@anchor{gnat_rm/the_gnat_library id135}@anchor{3da}
+@anchor{gnat_rm/the_gnat_library gnat-wide-wide-string-split-g-zistsp-ads}@anchor{3dd}@anchor{gnat_rm/the_gnat_library id135}@anchor{3de}
@section @code{GNAT.Wide_Wide_String_Split} (@code{g-zistsp.ads})
@@ -25142,7 +25171,7 @@ to the resulting slices. This package is instantiated from
@code{GNAT.Array_Split}.
@node Interfaces C Extensions i-cexten ads,Interfaces C Streams i-cstrea ads,GNAT Wide_Wide_String_Split g-zistsp ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library interfaces-c-extensions-i-cexten-ads}@anchor{3db}@anchor{gnat_rm/the_gnat_library id136}@anchor{3dc}
+@anchor{gnat_rm/the_gnat_library interfaces-c-extensions-i-cexten-ads}@anchor{3df}@anchor{gnat_rm/the_gnat_library id136}@anchor{3e0}
@section @code{Interfaces.C.Extensions} (@code{i-cexten.ads})
@@ -25153,7 +25182,7 @@ for use with either manually or automatically generated bindings
to C libraries.
@node Interfaces C Streams i-cstrea ads,Interfaces Packed_Decimal i-pacdec ads,Interfaces C Extensions i-cexten ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library interfaces-c-streams-i-cstrea-ads}@anchor{3dd}@anchor{gnat_rm/the_gnat_library id137}@anchor{3de}
+@anchor{gnat_rm/the_gnat_library interfaces-c-streams-i-cstrea-ads}@anchor{3e1}@anchor{gnat_rm/the_gnat_library id137}@anchor{3e2}
@section @code{Interfaces.C.Streams} (@code{i-cstrea.ads})
@@ -25166,7 +25195,7 @@ This package is a binding for the most commonly used operations
on C streams.
@node Interfaces Packed_Decimal i-pacdec ads,Interfaces VxWorks i-vxwork ads,Interfaces C Streams i-cstrea ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id138}@anchor{3df}@anchor{gnat_rm/the_gnat_library interfaces-packed-decimal-i-pacdec-ads}@anchor{3e0}
+@anchor{gnat_rm/the_gnat_library id138}@anchor{3e3}@anchor{gnat_rm/the_gnat_library interfaces-packed-decimal-i-pacdec-ads}@anchor{3e4}
@section @code{Interfaces.Packed_Decimal} (@code{i-pacdec.ads})
@@ -25181,7 +25210,7 @@ from a packed decimal format compatible with that used on IBM
mainframes.
@node Interfaces VxWorks i-vxwork ads,Interfaces VxWorks Int_Connection i-vxinco ads,Interfaces Packed_Decimal i-pacdec ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id139}@anchor{3e1}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-i-vxwork-ads}@anchor{3e2}
+@anchor{gnat_rm/the_gnat_library id139}@anchor{3e5}@anchor{gnat_rm/the_gnat_library interfaces-vxworks-i-vxwork-ads}@anchor{3e6}
@section @code{Interfaces.VxWorks} (@code{i-vxwork.ads})
@@ -25197,7 +25226,7 @@ In particular, it interfaces with the
VxWorks hardware interrupt facilities.
@node Interfaces VxWorks Int_Connection i-vxinco ads,Interfaces VxWorks IO i-vxwoio ads,Interfaces VxWorks i-vxwork ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library interfaces-vxworks-int-connection-i-vxinco-ads}@anchor{3e3}@anchor{gnat_rm/the_gnat_library id140}@anchor{3e4}
+@anchor{gnat_rm/the_gnat_library interfaces-vxworks-int-connection-i-vxinco-ads}@anchor{3e7}@anchor{gnat_rm/the_gnat_library id140}@anchor{3e8}
@section @code{Interfaces.VxWorks.Int_Connection} (@code{i-vxinco.ads})
@@ -25213,7 +25242,7 @@ intConnect() with a custom routine for installing interrupt
handlers.
@node Interfaces VxWorks IO i-vxwoio ads,System Address_Image s-addima ads,Interfaces VxWorks Int_Connection i-vxinco ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library interfaces-vxworks-io-i-vxwoio-ads}@anchor{3e5}@anchor{gnat_rm/the_gnat_library id141}@anchor{3e6}
+@anchor{gnat_rm/the_gnat_library interfaces-vxworks-io-i-vxwoio-ads}@anchor{3e9}@anchor{gnat_rm/the_gnat_library id141}@anchor{3ea}
@section @code{Interfaces.VxWorks.IO} (@code{i-vxwoio.ads})
@@ -25236,7 +25265,7 @@ function codes. A particular use of this package is
to enable the use of Get_Immediate under VxWorks.
@node System Address_Image s-addima ads,System Assertions s-assert ads,Interfaces VxWorks IO i-vxwoio ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-address-image-s-addima-ads}@anchor{3e7}@anchor{gnat_rm/the_gnat_library id142}@anchor{3e8}
+@anchor{gnat_rm/the_gnat_library system-address-image-s-addima-ads}@anchor{3eb}@anchor{gnat_rm/the_gnat_library id142}@anchor{3ec}
@section @code{System.Address_Image} (@code{s-addima.ads})
@@ -25252,7 +25281,7 @@ function that gives an (implementation dependent)
string which identifies an address.
@node System Assertions s-assert ads,System Atomic_Counters s-atocou ads,System Address_Image s-addima ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-assertions-s-assert-ads}@anchor{3e9}@anchor{gnat_rm/the_gnat_library id143}@anchor{3ea}
+@anchor{gnat_rm/the_gnat_library system-assertions-s-assert-ads}@anchor{3ed}@anchor{gnat_rm/the_gnat_library id143}@anchor{3ee}
@section @code{System.Assertions} (@code{s-assert.ads})
@@ -25268,7 +25297,7 @@ by an run-time assertion failure, as well as the routine that
is used internally to raise this assertion.
@node System Atomic_Counters s-atocou ads,System Memory s-memory ads,System Assertions s-assert ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id144}@anchor{3eb}@anchor{gnat_rm/the_gnat_library system-atomic-counters-s-atocou-ads}@anchor{3ec}
+@anchor{gnat_rm/the_gnat_library id144}@anchor{3ef}@anchor{gnat_rm/the_gnat_library system-atomic-counters-s-atocou-ads}@anchor{3f0}
@section @code{System.Atomic_Counters} (@code{s-atocou.ads})
@@ -25282,7 +25311,7 @@ on most targets, including all Alpha, ia64, PowerPC, SPARC V9,
x86, and x86_64 platforms.
@node System Memory s-memory ads,System Multiprocessors s-multip ads,System Atomic_Counters s-atocou ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-memory-s-memory-ads}@anchor{3ed}@anchor{gnat_rm/the_gnat_library id145}@anchor{3ee}
+@anchor{gnat_rm/the_gnat_library system-memory-s-memory-ads}@anchor{3f1}@anchor{gnat_rm/the_gnat_library id145}@anchor{3f2}
@section @code{System.Memory} (@code{s-memory.ads})
@@ -25300,7 +25329,7 @@ calls to this unit may be made for low level allocation uses (for
example see the body of @code{GNAT.Tables}).
@node System Multiprocessors s-multip ads,System Multiprocessors Dispatching_Domains s-mudido ads,System Memory s-memory ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id146}@anchor{3ef}@anchor{gnat_rm/the_gnat_library system-multiprocessors-s-multip-ads}@anchor{3f0}
+@anchor{gnat_rm/the_gnat_library id146}@anchor{3f3}@anchor{gnat_rm/the_gnat_library system-multiprocessors-s-multip-ads}@anchor{3f4}
@section @code{System.Multiprocessors} (@code{s-multip.ads})
@@ -25313,7 +25342,7 @@ in GNAT we also make it available in Ada 95 and Ada 2005 (where it is
technically an implementation-defined addition).
@node System Multiprocessors Dispatching_Domains s-mudido ads,System Partition_Interface s-parint ads,System Multiprocessors s-multip ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-multiprocessors-dispatching-domains-s-mudido-ads}@anchor{3f1}@anchor{gnat_rm/the_gnat_library id147}@anchor{3f2}
+@anchor{gnat_rm/the_gnat_library system-multiprocessors-dispatching-domains-s-mudido-ads}@anchor{3f5}@anchor{gnat_rm/the_gnat_library id147}@anchor{3f6}
@section @code{System.Multiprocessors.Dispatching_Domains} (@code{s-mudido.ads})
@@ -25326,7 +25355,7 @@ in GNAT we also make it available in Ada 95 and Ada 2005 (where it is
technically an implementation-defined addition).
@node System Partition_Interface s-parint ads,System Pool_Global s-pooglo ads,System Multiprocessors Dispatching_Domains s-mudido ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id148}@anchor{3f3}@anchor{gnat_rm/the_gnat_library system-partition-interface-s-parint-ads}@anchor{3f4}
+@anchor{gnat_rm/the_gnat_library id148}@anchor{3f7}@anchor{gnat_rm/the_gnat_library system-partition-interface-s-parint-ads}@anchor{3f8}
@section @code{System.Partition_Interface} (@code{s-parint.ads})
@@ -25339,7 +25368,7 @@ is used primarily in a distribution context when using Annex E
with @code{GLADE}.
@node System Pool_Global s-pooglo ads,System Pool_Local s-pooloc ads,System Partition_Interface s-parint ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id149}@anchor{3f5}@anchor{gnat_rm/the_gnat_library system-pool-global-s-pooglo-ads}@anchor{3f6}
+@anchor{gnat_rm/the_gnat_library id149}@anchor{3f9}@anchor{gnat_rm/the_gnat_library system-pool-global-s-pooglo-ads}@anchor{3fa}
@section @code{System.Pool_Global} (@code{s-pooglo.ads})
@@ -25356,7 +25385,7 @@ declared. It uses malloc/free to allocate/free and does not attempt to
do any automatic reclamation.
@node System Pool_Local s-pooloc ads,System Restrictions s-restri ads,System Pool_Global s-pooglo ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-pool-local-s-pooloc-ads}@anchor{3f7}@anchor{gnat_rm/the_gnat_library id150}@anchor{3f8}
+@anchor{gnat_rm/the_gnat_library system-pool-local-s-pooloc-ads}@anchor{3fb}@anchor{gnat_rm/the_gnat_library id150}@anchor{3fc}
@section @code{System.Pool_Local} (@code{s-pooloc.ads})
@@ -25373,7 +25402,7 @@ a list of allocated blocks, so that all storage allocated for the pool can
be freed automatically when the pool is finalized.
@node System Restrictions s-restri ads,System Rident s-rident ads,System Pool_Local s-pooloc ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-restrictions-s-restri-ads}@anchor{3f9}@anchor{gnat_rm/the_gnat_library id151}@anchor{3fa}
+@anchor{gnat_rm/the_gnat_library system-restrictions-s-restri-ads}@anchor{3fd}@anchor{gnat_rm/the_gnat_library id151}@anchor{3fe}
@section @code{System.Restrictions} (@code{s-restri.ads})
@@ -25389,7 +25418,7 @@ compiler determined information on which restrictions
are violated by one or more packages in the partition.
@node System Rident s-rident ads,System Strings Stream_Ops s-ststop ads,System Restrictions s-restri ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-rident-s-rident-ads}@anchor{3fb}@anchor{gnat_rm/the_gnat_library id152}@anchor{3fc}
+@anchor{gnat_rm/the_gnat_library system-rident-s-rident-ads}@anchor{3ff}@anchor{gnat_rm/the_gnat_library id152}@anchor{400}
@section @code{System.Rident} (@code{s-rident.ads})
@@ -25405,7 +25434,7 @@ since the necessary instantiation is included in
package System.Restrictions.
@node System Strings Stream_Ops s-ststop ads,System Unsigned_Types s-unstyp ads,System Rident s-rident ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id153}@anchor{3fd}@anchor{gnat_rm/the_gnat_library system-strings-stream-ops-s-ststop-ads}@anchor{3fe}
+@anchor{gnat_rm/the_gnat_library id153}@anchor{401}@anchor{gnat_rm/the_gnat_library system-strings-stream-ops-s-ststop-ads}@anchor{402}
@section @code{System.Strings.Stream_Ops} (@code{s-ststop.ads})
@@ -25421,7 +25450,7 @@ stream attributes are applied to string types, but the subprograms in this
package can be used directly by application programs.
@node System Unsigned_Types s-unstyp ads,System Wch_Cnv s-wchcnv ads,System Strings Stream_Ops s-ststop ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-unsigned-types-s-unstyp-ads}@anchor{3ff}@anchor{gnat_rm/the_gnat_library id154}@anchor{400}
+@anchor{gnat_rm/the_gnat_library system-unsigned-types-s-unstyp-ads}@anchor{403}@anchor{gnat_rm/the_gnat_library id154}@anchor{404}
@section @code{System.Unsigned_Types} (@code{s-unstyp.ads})
@@ -25434,7 +25463,7 @@ also contains some related definitions for other specialized types
used by the compiler in connection with packed array types.
@node System Wch_Cnv s-wchcnv ads,System Wch_Con s-wchcon ads,System Unsigned_Types s-unstyp ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library system-wch-cnv-s-wchcnv-ads}@anchor{401}@anchor{gnat_rm/the_gnat_library id155}@anchor{402}
+@anchor{gnat_rm/the_gnat_library system-wch-cnv-s-wchcnv-ads}@anchor{405}@anchor{gnat_rm/the_gnat_library id155}@anchor{406}
@section @code{System.Wch_Cnv} (@code{s-wchcnv.ads})
@@ -25455,7 +25484,7 @@ encoding method. It uses definitions in
package @code{System.Wch_Con}.
@node System Wch_Con s-wchcon ads,,System Wch_Cnv s-wchcnv ads,The GNAT Library
-@anchor{gnat_rm/the_gnat_library id156}@anchor{403}@anchor{gnat_rm/the_gnat_library system-wch-con-s-wchcon-ads}@anchor{404}
+@anchor{gnat_rm/the_gnat_library id156}@anchor{407}@anchor{gnat_rm/the_gnat_library system-wch-con-s-wchcon-ads}@anchor{408}
@section @code{System.Wch_Con} (@code{s-wchcon.ads})
@@ -25467,7 +25496,7 @@ in ordinary strings. These definitions are used by
the package @code{System.Wch_Cnv}.
@node Interfacing to Other Languages,Specialized Needs Annexes,The GNAT Library,Top
-@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-other-languages}@anchor{11}@anchor{gnat_rm/interfacing_to_other_languages doc}@anchor{405}@anchor{gnat_rm/interfacing_to_other_languages id1}@anchor{406}
+@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-other-languages}@anchor{11}@anchor{gnat_rm/interfacing_to_other_languages doc}@anchor{409}@anchor{gnat_rm/interfacing_to_other_languages id1}@anchor{40a}
@chapter Interfacing to Other Languages
@@ -25485,7 +25514,7 @@ provided.
@end menu
@node Interfacing to C,Interfacing to C++,,Interfacing to Other Languages
-@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-c}@anchor{407}@anchor{gnat_rm/interfacing_to_other_languages id2}@anchor{408}
+@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-c}@anchor{40b}@anchor{gnat_rm/interfacing_to_other_languages id2}@anchor{40c}
@section Interfacing to C
@@ -25625,7 +25654,7 @@ of the length corresponding to the @code{type'Size} value in Ada.
@end itemize
@node Interfacing to C++,Interfacing to COBOL,Interfacing to C,Interfacing to Other Languages
-@anchor{gnat_rm/interfacing_to_other_languages id4}@anchor{409}@anchor{gnat_rm/interfacing_to_other_languages id3}@anchor{49}
+@anchor{gnat_rm/interfacing_to_other_languages id4}@anchor{40d}@anchor{gnat_rm/interfacing_to_other_languages id3}@anchor{49}
@section Interfacing to C++
@@ -25682,7 +25711,7 @@ The @code{External_Name} is the name of the C++ RTTI symbol. You can then
cover a specific C++ exception in an exception handler.
@node Interfacing to COBOL,Interfacing to Fortran,Interfacing to C++,Interfacing to Other Languages
-@anchor{gnat_rm/interfacing_to_other_languages id5}@anchor{40a}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-cobol}@anchor{40b}
+@anchor{gnat_rm/interfacing_to_other_languages id5}@anchor{40e}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-cobol}@anchor{40f}
@section Interfacing to COBOL
@@ -25690,7 +25719,7 @@ Interfacing to COBOL is achieved as described in section B.4 of
the Ada Reference Manual.
@node Interfacing to Fortran,Interfacing to non-GNAT Ada code,Interfacing to COBOL,Interfacing to Other Languages
-@anchor{gnat_rm/interfacing_to_other_languages id6}@anchor{40c}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-fortran}@anchor{40d}
+@anchor{gnat_rm/interfacing_to_other_languages id6}@anchor{410}@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-fortran}@anchor{411}
@section Interfacing to Fortran
@@ -25700,7 +25729,7 @@ multi-dimensional array causes the array to be stored in column-major
order as required for convenient interface to Fortran.
@node Interfacing to non-GNAT Ada code,,Interfacing to Fortran,Interfacing to Other Languages
-@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-non-gnat-ada-code}@anchor{40e}@anchor{gnat_rm/interfacing_to_other_languages id7}@anchor{40f}
+@anchor{gnat_rm/interfacing_to_other_languages interfacing-to-non-gnat-ada-code}@anchor{412}@anchor{gnat_rm/interfacing_to_other_languages id7}@anchor{413}
@section Interfacing to non-GNAT Ada code
@@ -25724,7 +25753,7 @@ values or simple record types without variants, or simple array
types with fixed bounds.
@node Specialized Needs Annexes,Implementation of Specific Ada Features,Interfacing to Other Languages,Top
-@anchor{gnat_rm/specialized_needs_annexes specialized-needs-annexes}@anchor{12}@anchor{gnat_rm/specialized_needs_annexes doc}@anchor{410}@anchor{gnat_rm/specialized_needs_annexes id1}@anchor{411}
+@anchor{gnat_rm/specialized_needs_annexes specialized-needs-annexes}@anchor{12}@anchor{gnat_rm/specialized_needs_annexes doc}@anchor{414}@anchor{gnat_rm/specialized_needs_annexes id1}@anchor{415}
@chapter Specialized Needs Annexes
@@ -25765,7 +25794,7 @@ in Ada 2005) is fully implemented.
@end table
@node Implementation of Specific Ada Features,Implementation of Ada 2012 Features,Specialized Needs Annexes,Top
-@anchor{gnat_rm/implementation_of_specific_ada_features implementation-of-specific-ada-features}@anchor{13}@anchor{gnat_rm/implementation_of_specific_ada_features doc}@anchor{412}@anchor{gnat_rm/implementation_of_specific_ada_features id1}@anchor{413}
+@anchor{gnat_rm/implementation_of_specific_ada_features implementation-of-specific-ada-features}@anchor{13}@anchor{gnat_rm/implementation_of_specific_ada_features doc}@anchor{416}@anchor{gnat_rm/implementation_of_specific_ada_features id1}@anchor{417}
@chapter Implementation of Specific Ada Features
@@ -25783,7 +25812,7 @@ facilities.
@end menu
@node Machine Code Insertions,GNAT Implementation of Tasking,,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features machine-code-insertions}@anchor{168}@anchor{gnat_rm/implementation_of_specific_ada_features id2}@anchor{414}
+@anchor{gnat_rm/implementation_of_specific_ada_features machine-code-insertions}@anchor{16c}@anchor{gnat_rm/implementation_of_specific_ada_features id2}@anchor{418}
@section Machine Code Insertions
@@ -25951,7 +25980,7 @@ according to normal visibility rules. In particular if there is no
qualification is required.
@node GNAT Implementation of Tasking,GNAT Implementation of Shared Passive Packages,Machine Code Insertions,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features id3}@anchor{415}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-tasking}@anchor{416}
+@anchor{gnat_rm/implementation_of_specific_ada_features id3}@anchor{419}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-tasking}@anchor{41a}
@section GNAT Implementation of Tasking
@@ -25967,7 +25996,7 @@ to compliance with the Real-Time Systems Annex.
@end menu
@node Mapping Ada Tasks onto the Underlying Kernel Threads,Ensuring Compliance with the Real-Time Annex,,GNAT Implementation of Tasking
-@anchor{gnat_rm/implementation_of_specific_ada_features mapping-ada-tasks-onto-the-underlying-kernel-threads}@anchor{417}@anchor{gnat_rm/implementation_of_specific_ada_features id4}@anchor{418}
+@anchor{gnat_rm/implementation_of_specific_ada_features mapping-ada-tasks-onto-the-underlying-kernel-threads}@anchor{41b}@anchor{gnat_rm/implementation_of_specific_ada_features id4}@anchor{41c}
@subsection Mapping Ada Tasks onto the Underlying Kernel Threads
@@ -26036,7 +26065,7 @@ support this functionality when the parent contains more than one task.
@geindex Forking a new process
@node Ensuring Compliance with the Real-Time Annex,Support for Locking Policies,Mapping Ada Tasks onto the Underlying Kernel Threads,GNAT Implementation of Tasking
-@anchor{gnat_rm/implementation_of_specific_ada_features id5}@anchor{419}@anchor{gnat_rm/implementation_of_specific_ada_features ensuring-compliance-with-the-real-time-annex}@anchor{41a}
+@anchor{gnat_rm/implementation_of_specific_ada_features id5}@anchor{41d}@anchor{gnat_rm/implementation_of_specific_ada_features ensuring-compliance-with-the-real-time-annex}@anchor{41e}
@subsection Ensuring Compliance with the Real-Time Annex
@@ -26087,7 +26116,7 @@ placed at the end.
@c Support_for_Locking_Policies
@node Support for Locking Policies,,Ensuring Compliance with the Real-Time Annex,GNAT Implementation of Tasking
-@anchor{gnat_rm/implementation_of_specific_ada_features support-for-locking-policies}@anchor{41b}
+@anchor{gnat_rm/implementation_of_specific_ada_features support-for-locking-policies}@anchor{41f}
@subsection Support for Locking Policies
@@ -26121,7 +26150,7 @@ then ceiling locking is used.
Otherwise, the @code{Ceiling_Locking} policy is ignored.
@node GNAT Implementation of Shared Passive Packages,Code Generation for Array Aggregates,GNAT Implementation of Tasking,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features id6}@anchor{41c}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-shared-passive-packages}@anchor{41d}
+@anchor{gnat_rm/implementation_of_specific_ada_features id6}@anchor{420}@anchor{gnat_rm/implementation_of_specific_ada_features gnat-implementation-of-shared-passive-packages}@anchor{421}
@section GNAT Implementation of Shared Passive Packages
@@ -26222,7 +26251,7 @@ GNAT supports shared passive packages on all platforms
except for OpenVMS.
@node Code Generation for Array Aggregates,The Size of Discriminated Records with Default Discriminants,GNAT Implementation of Shared Passive Packages,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features code-generation-for-array-aggregates}@anchor{41e}@anchor{gnat_rm/implementation_of_specific_ada_features id7}@anchor{41f}
+@anchor{gnat_rm/implementation_of_specific_ada_features code-generation-for-array-aggregates}@anchor{422}@anchor{gnat_rm/implementation_of_specific_ada_features id7}@anchor{423}
@section Code Generation for Array Aggregates
@@ -26253,7 +26282,7 @@ component values and static subtypes also lead to simpler code.
@end menu
@node Static constant aggregates with static bounds,Constant aggregates with unconstrained nominal types,,Code Generation for Array Aggregates
-@anchor{gnat_rm/implementation_of_specific_ada_features static-constant-aggregates-with-static-bounds}@anchor{420}@anchor{gnat_rm/implementation_of_specific_ada_features id8}@anchor{421}
+@anchor{gnat_rm/implementation_of_specific_ada_features static-constant-aggregates-with-static-bounds}@anchor{424}@anchor{gnat_rm/implementation_of_specific_ada_features id8}@anchor{425}
@subsection Static constant aggregates with static bounds
@@ -26300,7 +26329,7 @@ Zero2: constant two_dim := (others => (others => 0));
@end example
@node Constant aggregates with unconstrained nominal types,Aggregates with static bounds,Static constant aggregates with static bounds,Code Generation for Array Aggregates
-@anchor{gnat_rm/implementation_of_specific_ada_features constant-aggregates-with-unconstrained-nominal-types}@anchor{422}@anchor{gnat_rm/implementation_of_specific_ada_features id9}@anchor{423}
+@anchor{gnat_rm/implementation_of_specific_ada_features constant-aggregates-with-unconstrained-nominal-types}@anchor{426}@anchor{gnat_rm/implementation_of_specific_ada_features id9}@anchor{427}
@subsection Constant aggregates with unconstrained nominal types
@@ -26315,7 +26344,7 @@ Cr_Unc : constant One_Unc := (12,24,36);
@end example
@node Aggregates with static bounds,Aggregates with nonstatic bounds,Constant aggregates with unconstrained nominal types,Code Generation for Array Aggregates
-@anchor{gnat_rm/implementation_of_specific_ada_features id10}@anchor{424}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-static-bounds}@anchor{425}
+@anchor{gnat_rm/implementation_of_specific_ada_features id10}@anchor{428}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-static-bounds}@anchor{429}
@subsection Aggregates with static bounds
@@ -26343,7 +26372,7 @@ end loop;
@end example
@node Aggregates with nonstatic bounds,Aggregates in assignment statements,Aggregates with static bounds,Code Generation for Array Aggregates
-@anchor{gnat_rm/implementation_of_specific_ada_features id11}@anchor{426}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-nonstatic-bounds}@anchor{427}
+@anchor{gnat_rm/implementation_of_specific_ada_features id11}@anchor{42a}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-with-nonstatic-bounds}@anchor{42b}
@subsection Aggregates with nonstatic bounds
@@ -26354,7 +26383,7 @@ have to be applied to sub-arrays individually, if they do not have statically
compatible subtypes.
@node Aggregates in assignment statements,,Aggregates with nonstatic bounds,Code Generation for Array Aggregates
-@anchor{gnat_rm/implementation_of_specific_ada_features id12}@anchor{428}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-in-assignment-statements}@anchor{429}
+@anchor{gnat_rm/implementation_of_specific_ada_features id12}@anchor{42c}@anchor{gnat_rm/implementation_of_specific_ada_features aggregates-in-assignment-statements}@anchor{42d}
@subsection Aggregates in assignment statements
@@ -26396,7 +26425,7 @@ a temporary (created either by the front-end or the code generator) and then
that temporary will be copied onto the target.
@node The Size of Discriminated Records with Default Discriminants,Strict Conformance to the Ada Reference Manual,Code Generation for Array Aggregates,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features id13}@anchor{42a}@anchor{gnat_rm/implementation_of_specific_ada_features the-size-of-discriminated-records-with-default-discriminants}@anchor{42b}
+@anchor{gnat_rm/implementation_of_specific_ada_features id13}@anchor{42e}@anchor{gnat_rm/implementation_of_specific_ada_features the-size-of-discriminated-records-with-default-discriminants}@anchor{42f}
@section The Size of Discriminated Records with Default Discriminants
@@ -26476,7 +26505,7 @@ say) must be consistent, so it is imperative that the object, once created,
remain invariant.
@node Strict Conformance to the Ada Reference Manual,,The Size of Discriminated Records with Default Discriminants,Implementation of Specific Ada Features
-@anchor{gnat_rm/implementation_of_specific_ada_features strict-conformance-to-the-ada-reference-manual}@anchor{42c}@anchor{gnat_rm/implementation_of_specific_ada_features id14}@anchor{42d}
+@anchor{gnat_rm/implementation_of_specific_ada_features strict-conformance-to-the-ada-reference-manual}@anchor{430}@anchor{gnat_rm/implementation_of_specific_ada_features id14}@anchor{431}
@section Strict Conformance to the Ada Reference Manual
@@ -26503,7 +26532,7 @@ behavior (although at the cost of a significant performance penalty), so
infinite and NaN values are properly generated.
@node Implementation of Ada 2012 Features,Obsolescent Features,Implementation of Specific Ada Features,Top
-@anchor{gnat_rm/implementation_of_ada_2012_features doc}@anchor{42e}@anchor{gnat_rm/implementation_of_ada_2012_features implementation-of-ada-2012-features}@anchor{14}@anchor{gnat_rm/implementation_of_ada_2012_features id1}@anchor{42f}
+@anchor{gnat_rm/implementation_of_ada_2012_features doc}@anchor{432}@anchor{gnat_rm/implementation_of_ada_2012_features implementation-of-ada-2012-features}@anchor{14}@anchor{gnat_rm/implementation_of_ada_2012_features id1}@anchor{433}
@chapter Implementation of Ada 2012 Features
@@ -28669,7 +28698,7 @@ RM References: H.04 (8/1)
@end itemize
@node Obsolescent Features,Compatibility and Porting Guide,Implementation of Ada 2012 Features,Top
-@anchor{gnat_rm/obsolescent_features id1}@anchor{430}@anchor{gnat_rm/obsolescent_features doc}@anchor{431}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{15}
+@anchor{gnat_rm/obsolescent_features id1}@anchor{434}@anchor{gnat_rm/obsolescent_features doc}@anchor{435}@anchor{gnat_rm/obsolescent_features obsolescent-features}@anchor{15}
@chapter Obsolescent Features
@@ -28688,7 +28717,7 @@ compatibility purposes.
@end menu
@node pragma No_Run_Time,pragma Ravenscar,,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features id2}@anchor{432}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{433}
+@anchor{gnat_rm/obsolescent_features id2}@anchor{436}@anchor{gnat_rm/obsolescent_features pragma-no-run-time}@anchor{437}
@section pragma No_Run_Time
@@ -28701,7 +28730,7 @@ preferred usage is to use an appropriately configured run-time that
includes just those features that are to be made accessible.
@node pragma Ravenscar,pragma Restricted_Run_Time,pragma No_Run_Time,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features id3}@anchor{434}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{435}
+@anchor{gnat_rm/obsolescent_features id3}@anchor{438}@anchor{gnat_rm/obsolescent_features pragma-ravenscar}@anchor{439}
@section pragma Ravenscar
@@ -28710,7 +28739,7 @@ The pragma @code{Ravenscar} has exactly the same effect as pragma
is part of the new Ada 2005 standard.
@node pragma Restricted_Run_Time,pragma Task_Info,pragma Ravenscar,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{436}@anchor{gnat_rm/obsolescent_features id4}@anchor{437}
+@anchor{gnat_rm/obsolescent_features pragma-restricted-run-time}@anchor{43a}@anchor{gnat_rm/obsolescent_features id4}@anchor{43b}
@section pragma Restricted_Run_Time
@@ -28720,7 +28749,7 @@ preferred since the Ada 2005 pragma @code{Profile} is intended for
this kind of implementation dependent addition.
@node pragma Task_Info,package System Task_Info s-tasinf ads,pragma Restricted_Run_Time,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{438}@anchor{gnat_rm/obsolescent_features id5}@anchor{439}
+@anchor{gnat_rm/obsolescent_features pragma-task-info}@anchor{43c}@anchor{gnat_rm/obsolescent_features id5}@anchor{43d}
@section pragma Task_Info
@@ -28746,7 +28775,7 @@ in the spec of package System.Task_Info in the runtime
library.
@node package System Task_Info s-tasinf ads,,pragma Task_Info,Obsolescent Features
-@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{43a}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{43b}
+@anchor{gnat_rm/obsolescent_features package-system-task-info}@anchor{43e}@anchor{gnat_rm/obsolescent_features package-system-task-info-s-tasinf-ads}@anchor{43f}
@section package System.Task_Info (@code{s-tasinf.ads})
@@ -28756,7 +28785,7 @@ to support the @code{Task_Info} pragma. The predefined Ada package
standard replacement for GNAT's @code{Task_Info} functionality.
@node Compatibility and Porting Guide,GNU Free Documentation License,Obsolescent Features,Top
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{16}@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{43c}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{43d}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-and-porting-guide}@anchor{16}@anchor{gnat_rm/compatibility_and_porting_guide doc}@anchor{440}@anchor{gnat_rm/compatibility_and_porting_guide id1}@anchor{441}
@chapter Compatibility and Porting Guide
@@ -28778,7 +28807,7 @@ applications developed in other Ada environments.
@end menu
@node Writing Portable Fixed-Point Declarations,Compatibility with Ada 83,,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{43e}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{43f}
+@anchor{gnat_rm/compatibility_and_porting_guide id2}@anchor{442}@anchor{gnat_rm/compatibility_and_porting_guide writing-portable-fixed-point-declarations}@anchor{443}
@section Writing Portable Fixed-Point Declarations
@@ -28900,7 +28929,7 @@ If you follow this scheme you will be guaranteed that your fixed-point
types will be portable.
@node Compatibility with Ada 83,Compatibility between Ada 95 and Ada 2005,Writing Portable Fixed-Point Declarations,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{440}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{441}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-ada-83}@anchor{444}@anchor{gnat_rm/compatibility_and_porting_guide id3}@anchor{445}
@section Compatibility with Ada 83
@@ -28928,7 +28957,7 @@ following subsections treat the most likely issues to be encountered.
@end menu
@node Legal Ada 83 programs that are illegal in Ada 95,More deterministic semantics,,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{442}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{443}
+@anchor{gnat_rm/compatibility_and_porting_guide id4}@anchor{446}@anchor{gnat_rm/compatibility_and_porting_guide legal-ada-83-programs-that-are-illegal-in-ada-95}@anchor{447}
@subsection Legal Ada 83 programs that are illegal in Ada 95
@@ -29028,7 +29057,7 @@ the fix is usually simply to add the @code{(<>)} to the generic declaration.
@end itemize
@node More deterministic semantics,Changed semantics,Legal Ada 83 programs that are illegal in Ada 95,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{444}@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{445}
+@anchor{gnat_rm/compatibility_and_porting_guide more-deterministic-semantics}@anchor{448}@anchor{gnat_rm/compatibility_and_porting_guide id5}@anchor{449}
@subsection More deterministic semantics
@@ -29056,7 +29085,7 @@ which open select branches are executed.
@end itemize
@node Changed semantics,Other language compatibility issues,More deterministic semantics,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{446}@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{447}
+@anchor{gnat_rm/compatibility_and_porting_guide id6}@anchor{44a}@anchor{gnat_rm/compatibility_and_porting_guide changed-semantics}@anchor{44b}
@subsection Changed semantics
@@ -29098,7 +29127,7 @@ covers only the restricted range.
@end itemize
@node Other language compatibility issues,,Changed semantics,Compatibility with Ada 83
-@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{448}@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{449}
+@anchor{gnat_rm/compatibility_and_porting_guide other-language-compatibility-issues}@anchor{44c}@anchor{gnat_rm/compatibility_and_porting_guide id7}@anchor{44d}
@subsection Other language compatibility issues
@@ -29131,7 +29160,7 @@ include @code{pragma Interface} and the floating point type attributes
@end itemize
@node Compatibility between Ada 95 and Ada 2005,Implementation-dependent characteristics,Compatibility with Ada 83,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{44a}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{44b}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-between-ada-95-and-ada-2005}@anchor{44e}@anchor{gnat_rm/compatibility_and_porting_guide id8}@anchor{44f}
@section Compatibility between Ada 95 and Ada 2005
@@ -29203,7 +29232,7 @@ can declare a function returning a value from an anonymous access type.
@end itemize
@node Implementation-dependent characteristics,Compatibility with Other Ada Systems,Compatibility between Ada 95 and Ada 2005,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{44c}@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{44d}
+@anchor{gnat_rm/compatibility_and_porting_guide implementation-dependent-characteristics}@anchor{450}@anchor{gnat_rm/compatibility_and_porting_guide id9}@anchor{451}
@section Implementation-dependent characteristics
@@ -29226,7 +29255,7 @@ transition from certain Ada 83 compilers.
@end menu
@node Implementation-defined pragmas,Implementation-defined attributes,,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{44e}@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{44f}
+@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-pragmas}@anchor{452}@anchor{gnat_rm/compatibility_and_porting_guide id10}@anchor{453}
@subsection Implementation-defined pragmas
@@ -29248,7 +29277,7 @@ avoiding compiler rejection of units that contain such pragmas; they are not
relevant in a GNAT context and hence are not otherwise implemented.
@node Implementation-defined attributes,Libraries,Implementation-defined pragmas,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{450}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{451}
+@anchor{gnat_rm/compatibility_and_porting_guide id11}@anchor{454}@anchor{gnat_rm/compatibility_and_porting_guide implementation-defined-attributes}@anchor{455}
@subsection Implementation-defined attributes
@@ -29262,7 +29291,7 @@ Ada 83, GNAT supplies the attributes @code{Bit}, @code{Machine_Size} and
@code{Type_Class}.
@node Libraries,Elaboration order,Implementation-defined attributes,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{452}@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{453}
+@anchor{gnat_rm/compatibility_and_porting_guide libraries}@anchor{456}@anchor{gnat_rm/compatibility_and_porting_guide id12}@anchor{457}
@subsection Libraries
@@ -29291,7 +29320,7 @@ be preferable to retrofit the application using modular types.
@end itemize
@node Elaboration order,Target-specific aspects,Libraries,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{454}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{455}
+@anchor{gnat_rm/compatibility_and_porting_guide elaboration-order}@anchor{458}@anchor{gnat_rm/compatibility_and_porting_guide id13}@anchor{459}
@subsection Elaboration order
@@ -29327,7 +29356,7 @@ pragmas either globally (as an effect of the @emph{-gnatE} switch) or locally
@end itemize
@node Target-specific aspects,,Elaboration order,Implementation-dependent characteristics
-@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{456}@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{457}
+@anchor{gnat_rm/compatibility_and_porting_guide target-specific-aspects}@anchor{45a}@anchor{gnat_rm/compatibility_and_porting_guide id14}@anchor{45b}
@subsection Target-specific aspects
@@ -29340,10 +29369,10 @@ on the robustness of the original design. Moreover, Ada 95 (and thus
Ada 2005 and Ada 2012) are sometimes
incompatible with typical Ada 83 compiler practices regarding implicit
packing, the meaning of the Size attribute, and the size of access values.
-GNAT's approach to these issues is described in @ref{458,,Representation Clauses}.
+GNAT's approach to these issues is described in @ref{45c,,Representation Clauses}.
@node Compatibility with Other Ada Systems,Representation Clauses,Implementation-dependent characteristics,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{459}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{45a}
+@anchor{gnat_rm/compatibility_and_porting_guide id15}@anchor{45d}@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-other-ada-systems}@anchor{45e}
@section Compatibility with Other Ada Systems
@@ -29386,7 +29415,7 @@ far beyond this minimal set, as described in the next section.
@end itemize
@node Representation Clauses,Compatibility with HP Ada 83,Compatibility with Other Ada Systems,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{458}@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{45b}
+@anchor{gnat_rm/compatibility_and_porting_guide representation-clauses}@anchor{45c}@anchor{gnat_rm/compatibility_and_porting_guide id16}@anchor{45f}
@section Representation Clauses
@@ -29479,7 +29508,7 @@ with thin pointers.
@end itemize
@node Compatibility with HP Ada 83,,Representation Clauses,Compatibility and Porting Guide
-@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{45c}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{45d}
+@anchor{gnat_rm/compatibility_and_porting_guide compatibility-with-hp-ada-83}@anchor{460}@anchor{gnat_rm/compatibility_and_porting_guide id17}@anchor{461}
@section Compatibility with HP Ada 83
@@ -29509,7 +29538,7 @@ extension of package System.
@end itemize
@node GNU Free Documentation License,Index,Compatibility and Porting Guide,Top
-@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license doc}@anchor{45e}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{45f}
+@anchor{share/gnu_free_documentation_license gnu-fdl}@anchor{1}@anchor{share/gnu_free_documentation_license doc}@anchor{462}@anchor{share/gnu_free_documentation_license gnu-free-documentation-license}@anchor{463}
@chapter GNU Free Documentation License
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index e3d6a3a..3e0c857 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -21,7 +21,7 @@
@copying
@quotation
-GNAT User's Guide for Native Platforms , Jun 21, 2019
+GNAT User's Guide for Native Platforms , Aug 01, 2019
AdaCore
@@ -9452,11 +9452,13 @@ GCC macro @code{BITS_PER_UNIT} documented as follows: @cite{Define this macro to
@code{Bits_Per_Word} is the number of bits in a machine word, the equivalent of
GCC macro @code{BITS_PER_WORD} documented as follows: @cite{Number of bits in a word; normally 32.}
-@code{Double_Scalar_Alignment} is the alignment for a scalar whose size is two
-machine words. It should be the same as the alignment for C @code{long_long} on
-most targets.
+@code{Double_Float_Alignment}, if not zero, is the maximum alignment that the
+compiler can choose by default for a 64-bit floating-point type or object.
-@code{Maximum_Alignment} is the maximum alignment that the compiler might choose
+@code{Double_Scalar_Alignment}, if not zero, is the maximum alignment that the
+compiler can choose by default for a 64-bit or larger scalar type or object.
+
+@code{Maximum_Alignment} is the maximum alignment that the compiler can choose
by default for a type or object, which is also the maximum alignment that can
be specified in GNAT. It is computed for GCC backends as @code{BIGGEST_ALIGNMENT
/ BITS_PER_UNIT} where GCC macro @code{BIGGEST_ALIGNMENT} is documented as
@@ -11206,7 +11208,7 @@ majority, but not all, of the components. A warning is given for each
component for which no component clause is present.
@end table
-@geindex -gnatwC (gcc)
+@geindex -gnatw.C (gcc)
@table @asis
@@ -11219,6 +11221,39 @@ This switch suppresses warnings for record components that are
missing a component clause in the situation described above.
@end table
+@geindex -gnatw_c (gcc)
+
+
+@table @asis
+
+@item @code{-gnatw_c}
+
+@emph{Activate warnings on unknown condition in Compile_Time_Warning.}
+
+@geindex Compile_Time_Warning
+
+@geindex Compile_Time_Error
+
+This switch activates warnings on a pragma Compile_Time_Warning
+or Compile_Time_Error whose condition has a value that is not
+known at compile time.
+The default is that such warnings are generated.
+@end table
+
+@geindex -gnatw_C (gcc)
+
+
+@table @asis
+
+@item @code{-gnatw_C}
+
+@emph{Suppress warnings on missing component clauses.}
+
+This switch supresses warnings on a pragma Compile_Time_Warning
+or Compile_Time_Error whose condition has a value that is not
+known at compile time.
+@end table
+
@geindex -gnatwd (gcc)
@@ -20917,7 +20952,6 @@ This section presents several topics related to program performance.
It first describes some of the tradeoffs that need to be considered
and some of the techniques for making your program run faster.
-
It then documents the unused subprogram/data elimination feature,
which can reduce the size of program executables.
@@ -22272,9 +22306,8 @@ appropriate options.
@geindex Checks (overflow)
-
@node Overflow Check Handling in GNAT,Performing Dimensionality Analysis in GNAT,Improving Performance,GNAT and Program Execution
-@anchor{gnat_ugn/gnat_and_program_execution id50}@anchor{169}@anchor{gnat_ugn/gnat_and_program_execution overflow-check-handling-in-gnat}@anchor{27}
+@anchor{gnat_ugn/gnat_and_program_execution id45}@anchor{169}@anchor{gnat_ugn/gnat_and_program_execution overflow-check-handling-in-gnat}@anchor{27}
@section Overflow Check Handling in GNAT
@@ -22290,7 +22323,7 @@ This section explains how to control the handling of overflow checks.
@end menu
@node Background,Management of Overflows in GNAT,,Overflow Check Handling in GNAT
-@anchor{gnat_ugn/gnat_and_program_execution id51}@anchor{1bb}@anchor{gnat_ugn/gnat_and_program_execution background}@anchor{1bc}
+@anchor{gnat_ugn/gnat_and_program_execution id46}@anchor{1bb}@anchor{gnat_ugn/gnat_and_program_execution background}@anchor{1bc}
@subsection Background
@@ -22416,7 +22449,7 @@ exception raised because of the intermediate overflow (and we really
would prefer this precondition to be considered True at run time).
@node Management of Overflows in GNAT,Specifying the Desired Mode,Background,Overflow Check Handling in GNAT
-@anchor{gnat_ugn/gnat_and_program_execution management-of-overflows-in-gnat}@anchor{1bd}@anchor{gnat_ugn/gnat_and_program_execution id52}@anchor{1be}
+@anchor{gnat_ugn/gnat_and_program_execution id47}@anchor{1bd}@anchor{gnat_ugn/gnat_and_program_execution management-of-overflows-in-gnat}@anchor{1be}
@subsection Management of Overflows in GNAT
@@ -22530,7 +22563,7 @@ out in the normal manner (with infinite values always failing all
range checks).
@node Specifying the Desired Mode,Default Settings,Management of Overflows in GNAT,Overflow Check Handling in GNAT
-@anchor{gnat_ugn/gnat_and_program_execution specifying-the-desired-mode}@anchor{f8}@anchor{gnat_ugn/gnat_and_program_execution id53}@anchor{1bf}
+@anchor{gnat_ugn/gnat_and_program_execution specifying-the-desired-mode}@anchor{f8}@anchor{gnat_ugn/gnat_and_program_execution id48}@anchor{1bf}
@subsection Specifying the Desired Mode
@@ -22654,7 +22687,7 @@ causing all intermediate operations to be computed using the base
type (@code{STRICT} mode).
@node Default Settings,Implementation Notes,Specifying the Desired Mode,Overflow Check Handling in GNAT
-@anchor{gnat_ugn/gnat_and_program_execution id54}@anchor{1c0}@anchor{gnat_ugn/gnat_and_program_execution default-settings}@anchor{1c1}
+@anchor{gnat_ugn/gnat_and_program_execution id49}@anchor{1c0}@anchor{gnat_ugn/gnat_and_program_execution default-settings}@anchor{1c1}
@subsection Default Settings
@@ -22701,7 +22734,7 @@ checking, but it has no effect on the method used for computing
intermediate results.
@node Implementation Notes,,Default Settings,Overflow Check Handling in GNAT
-@anchor{gnat_ugn/gnat_and_program_execution id55}@anchor{1c2}@anchor{gnat_ugn/gnat_and_program_execution implementation-notes}@anchor{1c3}
+@anchor{gnat_ugn/gnat_and_program_execution implementation-notes}@anchor{1c2}@anchor{gnat_ugn/gnat_and_program_execution id50}@anchor{1c3}
@subsection Implementation Notes
@@ -22749,7 +22782,7 @@ platforms for which @code{Long_Long_Integer} is 64-bits (nearly all GNAT
platforms).
@node Performing Dimensionality Analysis in GNAT,Stack Related Facilities,Overflow Check Handling in GNAT,GNAT and Program Execution
-@anchor{gnat_ugn/gnat_and_program_execution id56}@anchor{16a}@anchor{gnat_ugn/gnat_and_program_execution performing-dimensionality-analysis-in-gnat}@anchor{28}
+@anchor{gnat_ugn/gnat_and_program_execution performing-dimensionality-analysis-in-gnat}@anchor{28}@anchor{gnat_ugn/gnat_and_program_execution id51}@anchor{16a}
@section Performing Dimensionality Analysis in GNAT
@@ -23136,7 +23169,7 @@ passing (the dimension vector for the actual parameter must be equal to the
dimension vector for the formal parameter).
@node Stack Related Facilities,Memory Management Issues,Performing Dimensionality Analysis in GNAT,GNAT and Program Execution
-@anchor{gnat_ugn/gnat_and_program_execution id57}@anchor{16b}@anchor{gnat_ugn/gnat_and_program_execution stack-related-facilities}@anchor{29}
+@anchor{gnat_ugn/gnat_and_program_execution stack-related-facilities}@anchor{29}@anchor{gnat_ugn/gnat_and_program_execution id52}@anchor{16b}
@section Stack Related Facilities
@@ -23152,7 +23185,7 @@ particular, it deals with dynamic and static stack usage measurements.
@end menu
@node Stack Overflow Checking,Static Stack Usage Analysis,,Stack Related Facilities
-@anchor{gnat_ugn/gnat_and_program_execution id58}@anchor{1c4}@anchor{gnat_ugn/gnat_and_program_execution stack-overflow-checking}@anchor{f4}
+@anchor{gnat_ugn/gnat_and_program_execution id53}@anchor{1c4}@anchor{gnat_ugn/gnat_and_program_execution stack-overflow-checking}@anchor{f4}
@subsection Stack Overflow Checking
@@ -23197,7 +23230,7 @@ Consequently, to modify the size of the environment task please refer to your
operating system documentation.
@node Static Stack Usage Analysis,Dynamic Stack Usage Analysis,Stack Overflow Checking,Stack Related Facilities
-@anchor{gnat_ugn/gnat_and_program_execution static-stack-usage-analysis}@anchor{f5}@anchor{gnat_ugn/gnat_and_program_execution id59}@anchor{1c5}
+@anchor{gnat_ugn/gnat_and_program_execution id54}@anchor{1c5}@anchor{gnat_ugn/gnat_and_program_execution static-stack-usage-analysis}@anchor{f5}
@subsection Static Stack Usage Analysis
@@ -23246,7 +23279,7 @@ subprogram whose stack usage might be larger than the specified amount of
bytes. The wording is in keeping with the qualifier documented above.
@node Dynamic Stack Usage Analysis,,Static Stack Usage Analysis,Stack Related Facilities
-@anchor{gnat_ugn/gnat_and_program_execution dynamic-stack-usage-analysis}@anchor{122}@anchor{gnat_ugn/gnat_and_program_execution id60}@anchor{1c6}
+@anchor{gnat_ugn/gnat_and_program_execution id55}@anchor{1c6}@anchor{gnat_ugn/gnat_and_program_execution dynamic-stack-usage-analysis}@anchor{122}
@subsection Dynamic Stack Usage Analysis
@@ -23325,7 +23358,7 @@ The package @code{GNAT.Task_Stack_Usage} provides facilities to get
stack-usage reports at run time. See its body for the details.
@node Memory Management Issues,,Stack Related Facilities,GNAT and Program Execution
-@anchor{gnat_ugn/gnat_and_program_execution id61}@anchor{16c}@anchor{gnat_ugn/gnat_and_program_execution memory-management-issues}@anchor{2a}
+@anchor{gnat_ugn/gnat_and_program_execution id56}@anchor{16c}@anchor{gnat_ugn/gnat_and_program_execution memory-management-issues}@anchor{2a}
@section Memory Management Issues
@@ -23341,7 +23374,7 @@ incorrect uses of access values (including 'dangling references').
@end menu
@node Some Useful Memory Pools,The GNAT Debug Pool Facility,,Memory Management Issues
-@anchor{gnat_ugn/gnat_and_program_execution id62}@anchor{1c7}@anchor{gnat_ugn/gnat_and_program_execution some-useful-memory-pools}@anchor{1c8}
+@anchor{gnat_ugn/gnat_and_program_execution id57}@anchor{1c7}@anchor{gnat_ugn/gnat_and_program_execution some-useful-memory-pools}@anchor{1c8}
@subsection Some Useful Memory Pools
@@ -23422,7 +23455,7 @@ for T1'Storage_Size use 10_000;
@end quotation
@node The GNAT Debug Pool Facility,,Some Useful Memory Pools,Memory Management Issues
-@anchor{gnat_ugn/gnat_and_program_execution id63}@anchor{1c9}@anchor{gnat_ugn/gnat_and_program_execution the-gnat-debug-pool-facility}@anchor{1ca}
+@anchor{gnat_ugn/gnat_and_program_execution id58}@anchor{1c9}@anchor{gnat_ugn/gnat_and_program_execution the-gnat-debug-pool-facility}@anchor{1ca}
@subsection The GNAT Debug Pool Facility
diff --git a/gcc/ada/gnatcmd.adb b/gcc/ada/gnatcmd.adb
index 271e899..f83b0f2 100644
--- a/gcc/ada/gnatcmd.adb
+++ b/gcc/ada/gnatcmd.adb
@@ -30,6 +30,7 @@ with Osint; use Osint;
with Output; use Output;
with Switch; use Switch;
with Table;
+with Usage;
with Ada.Characters.Handling; use Ada.Characters.Handling;
with Ada.Command_Line; use Ada.Command_Line;
@@ -43,6 +44,9 @@ procedure GNATCmd is
Gprname : constant String := "gprname";
Gprls : constant String := "gprls";
+ Ada_Help_Switch : constant String := "--help-ada";
+ -- Flag to display available build switches
+
Error_Exit : exception;
-- Raise this exception if error detected
@@ -229,7 +233,7 @@ procedure GNATCmd is
procedure Output_Version;
-- Output the version of this program
- procedure Usage;
+ procedure GNATCmd_Usage;
-- Display usage
--------------------
@@ -244,14 +248,16 @@ procedure GNATCmd is
& ", Free Software Foundation, Inc.");
end Output_Version;
- -----------
- -- Usage --
- -----------
+ -------------------
+ -- GNATCmd_Usage --
+ -------------------
- procedure Usage is
+ procedure GNATCmd_Usage is
begin
Output_Version;
New_Line;
+ Put_Line ("To list Ada build switches use " & Ada_Help_Switch);
+ New_Line;
Put_Line ("List of available commands");
New_Line;
@@ -276,9 +282,10 @@ procedure GNATCmd is
end loop;
New_Line;
- end Usage;
+ end GNATCmd_Usage;
- procedure Check_Version_And_Help is new Check_Version_And_Help_G (Usage);
+ procedure Check_Version_And_Help
+ is new Check_Version_And_Help_G (GNATCmd_Usage);
-- Start of processing for GNATCmd
@@ -351,6 +358,12 @@ begin
Keep_Temporary_Files := True;
Command_Arg := Command_Arg + 1;
+ elsif Command_Arg <= Argument_Count
+ and then Argument (Command_Arg) = Ada_Help_Switch
+ then
+ Usage;
+ Exit_Program (E_Success);
+
else
exit;
end if;
@@ -359,7 +372,12 @@ begin
-- If there is no command, just output the usage
if Command_Arg > Argument_Count then
- Usage;
+ GNATCmd_Usage;
+
+ -- Add the following so that output is consistent with or without the
+ -- --help flag.
+ Write_Eol;
+ Write_Line ("Report bugs to report@adacore.com");
return;
end if;
@@ -379,7 +397,7 @@ begin
exception
when Constraint_Error =>
- Usage;
+ GNATCmd_Usage;
Fail ("unknown command: " & Argument (Command_Arg));
end;
end;
diff --git a/gcc/ada/impunit.adb b/gcc/ada/impunit.adb
index 80857b3..4cf8535 100644
--- a/gcc/ada/impunit.adb
+++ b/gcc/ada/impunit.adb
@@ -241,6 +241,7 @@ package body Impunit is
("g-binenv", F), -- GNAT.Bind_Environment
("g-boubuf", F), -- GNAT.Bounded_Buffers
("g-boumai", F), -- GNAT.Bounded_Mailboxes
+ ("g-brapre", F), -- GNAT.Branch_Prediction
("g-bubsor", F), -- GNAT.Bubble_Sort
("g-busora", F), -- GNAT.Bubble_Sort_A
("g-busorg", F), -- GNAT.Bubble_Sort_G
diff --git a/gcc/ada/inline.adb b/gcc/ada/inline.adb
index 5b7fefc..46daa48 100644
--- a/gcc/ada/inline.adb
+++ b/gcc/ada/inline.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Alloc;
with Aspects; use Aspects;
with Atree; use Atree;
with Debug; use Debug;
@@ -51,8 +52,12 @@ with Sinfo; use Sinfo;
with Sinput; use Sinput;
with Snames; use Snames;
with Stand; use Stand;
-with Uname; use Uname;
+with Table;
with Tbuild; use Tbuild;
+with Uintp; use Uintp;
+with Uname; use Uname;
+
+with GNAT.HTable;
package body Inline is
@@ -82,12 +87,83 @@ package body Inline is
Backend_Calls : Elist_Id;
-- List of inline calls passed to the backend
+ Backend_Instances : Elist_Id;
+ -- List of instances inlined for the backend
+
Backend_Inlined_Subps : Elist_Id;
-- List of subprograms inlined by the backend
Backend_Not_Inlined_Subps : Elist_Id;
-- List of subprograms that cannot be inlined by the backend
+ -----------------------------
+ -- Pending_Instantiations --
+ -----------------------------
+
+ -- We make entries in this table for the pending instantiations of generic
+ -- bodies that are created during semantic analysis. After the analysis is
+ -- complete, calling Instantiate_Bodies performs the actual instantiations.
+
+ package Pending_Instantiations is new Table.Table (
+ Table_Component_Type => Pending_Body_Info,
+ Table_Index_Type => Int,
+ Table_Low_Bound => 0,
+ Table_Initial => Alloc.Pending_Instantiations_Initial,
+ Table_Increment => Alloc.Pending_Instantiations_Increment,
+ Table_Name => "Pending_Instantiations");
+
+ -------------------------------------
+ -- Called_Pending_Instantiations --
+ -------------------------------------
+
+ -- With back-end inlining, the pending instantiations that are not in the
+ -- main unit or subunit are performed only after a call to the subprogram
+ -- instance, or to a subprogram within the package instance, is inlined.
+ -- Since such a call can be within a subsequent pending instantiation,
+ -- we make entries in this table that stores the index of these "called"
+ -- pending instantiations and perform them when the table is populated.
+
+ package Called_Pending_Instantiations is new Table.Table (
+ Table_Component_Type => Int,
+ Table_Index_Type => Int,
+ Table_Low_Bound => 0,
+ Table_Initial => Alloc.Pending_Instantiations_Initial,
+ Table_Increment => Alloc.Pending_Instantiations_Increment,
+ Table_Name => "Called_Pending_Instantiations");
+
+ ---------------------------------
+ -- To_Pending_Instantiations --
+ ---------------------------------
+
+ -- With back-end inlining, we also need to have a map from the pending
+ -- instantiations to their index in the Pending_Instantiations table.
+
+ Node_Table_Size : constant := 257;
+ -- Number of headers in hash table
+
+ subtype Node_Header_Num is Integer range 0 .. Node_Table_Size - 1;
+ -- Range of headers in hash table
+
+ function Node_Hash (Id : Node_Id) return Node_Header_Num;
+ -- Simple hash function for Node_Ids
+
+ package To_Pending_Instantiations is new GNAT.Htable.Simple_HTable
+ (Header_Num => Node_Header_Num,
+ Element => Int,
+ No_Element => -1,
+ Key => Node_Id,
+ Hash => Node_Hash,
+ Equal => "=");
+
+ -----------------
+ -- Node_Hash --
+ -----------------
+
+ function Node_Hash (Id : Node_Id) return Node_Header_Num is
+ begin
+ return Node_Header_Num (Id mod Node_Table_Size);
+ end Node_Hash;
+
--------------------
-- Inlined Bodies --
--------------------
@@ -179,8 +255,11 @@ package body Inline is
-- called, and for the inlined subprogram that contains the call. If
-- the call is in the main compilation unit, Caller is Empty.
+ procedure Add_Inlined_Instance (E : Entity_Id);
+ -- Add instance E to the list of of inlined instances for the unit
+
procedure Add_Inlined_Subprogram (E : Entity_Id);
- -- Add subprogram E to the list of inlined subprogram for the unit
+ -- Add subprogram E to the list of inlined subprograms for the unit
function Add_Subp (E : Entity_Id) return Subp_Index;
-- Make entry in Inlined table for subprogram E, or return table index
@@ -429,17 +508,21 @@ package body Inline is
return Dont_Inline;
end Must_Inline;
- Level : Inline_Level_Type;
+ Inst : Entity_Id;
+ Inst_Decl : Node_Id;
+ Level : Inline_Level_Type;
-- Start of processing for Add_Inlined_Body
begin
Append_New_Elmt (N, To => Backend_Calls);
- -- Skip subprograms that cannot be inlined outside their unit
+ -- Skip subprograms that cannot or need not be inlined outside their
+ -- unit or parent subprogram.
if Is_Abstract_Subprogram (E)
or else Convention (E) = Convention_Protected
+ or else In_Main_Unit_Or_Subunit (E)
or else Is_Nested (E)
then
return;
@@ -456,6 +539,22 @@ package body Inline is
return;
end if;
+ -- If a previous call to the subprogram has been inlined, nothing to do
+
+ if Is_Called (E) then
+ return;
+ end if;
+
+ -- If the subprogram is an instance, then inline the instance
+
+ if Is_Generic_Instance (E) then
+ Add_Inlined_Instance (E);
+ end if;
+
+ -- Mark the subprogram as called
+
+ Set_Is_Called (E);
+
-- If the call was generated by the compiler and is to a subprogram in
-- a run-time unit, we need to suppress debugging information for it,
-- so that the code that is eventually inlined will not affect the
@@ -476,19 +575,10 @@ package body Inline is
-- in the spec.
if Is_Non_Loading_Expression_Function (E) then
- Set_Is_Called (E);
return;
end if;
-- Find unit containing E, and add to list of inlined bodies if needed.
- -- If the body is already present, no need to load any other unit. This
- -- is the case for an initialization procedure, which appears in the
- -- package declaration that contains the type. It is also the case if
- -- the body has already been analyzed. Finally, if the unit enclosing
- -- E is an instance, the instance body will be analyzed in any case,
- -- and there is no need to add the enclosing unit (whose body might not
- -- be available).
-
-- Library-level functions must be handled specially, because there is
-- no enclosing package to retrieve. In this case, it is the body of
-- the function that will have to be loaded.
@@ -498,12 +588,43 @@ package body Inline is
begin
if Pack = E then
- Set_Is_Called (E);
Inlined_Bodies.Increment_Last;
Inlined_Bodies.Table (Inlined_Bodies.Last) := E;
- elsif Ekind (Pack) = E_Package then
- Set_Is_Called (E);
+ else
+ pragma Assert (Ekind (Pack) = E_Package);
+
+ -- If the subprogram is within an instance, inline the instance
+
+ if Comes_From_Source (E) then
+ Inst := Scope (E);
+
+ while Present (Inst) and then Inst /= Standard_Standard loop
+ exit when Is_Generic_Instance (Inst);
+ Inst := Scope (Inst);
+ end loop;
+
+ if Present (Inst)
+ and then Is_Generic_Instance (Inst)
+ and then not Is_Called (Inst)
+ then
+ Inst_Decl := Unit_Declaration_Node (Inst);
+
+ -- Do not inline the instance if the body already exists,
+ -- or the instance node is simply missing.
+
+ if Present (Corresponding_Body (Inst_Decl))
+ or else (Nkind (Parent (Inst_Decl)) /= N_Compilation_Unit
+ and then No (Next (Inst_Decl)))
+ then
+ Set_Is_Called (Inst);
+ else
+ Add_Inlined_Instance (Inst);
+ end if;
+ end if;
+ end if;
+
+ -- If the unit containing E is an instance, nothing more to do
if Is_Generic_Instance (Pack) then
null;
@@ -515,7 +636,7 @@ package body Inline is
-- Do not inline it either if it is in the main unit.
-- Extend the -gnatn2 processing to -gnatn1 for Inline_Always
-- calls if the back-end takes care of inlining the call.
- -- Note that Level in Inline_Package | Inline_Call here.
+ -- Note that Level is in Inline_Call | Inline_Packag here.
elsif ((Level = Inline_Call
and then Has_Pragma_Inline_Always (E)
@@ -538,6 +659,39 @@ package body Inline is
end;
end Add_Inlined_Body;
+ --------------------------
+ -- Add_Inlined_Instance --
+ --------------------------
+
+ procedure Add_Inlined_Instance (E : Entity_Id) is
+ Decl_Node : constant Node_Id := Unit_Declaration_Node (E);
+ Index : Int;
+
+ begin
+ -- This machinery is only used with back-end inlining
+
+ if not Back_End_Inlining then
+ return;
+ end if;
+
+ -- Register the instance in the list
+
+ Append_New_Elmt (Decl_Node, To => Backend_Instances);
+
+ -- Retrieve the index of its corresponding pending instantiation
+ -- and mark this corresponding pending instantiation as needed.
+
+ Index := To_Pending_Instantiations.Get (Decl_Node);
+ if Index >= 0 then
+ Called_Pending_Instantiations.Append (Index);
+ else
+ pragma Assert (False);
+ null;
+ end if;
+
+ Set_Is_Called (E);
+ end Add_Inlined_Instance;
+
----------------------------
-- Add_Inlined_Subprogram --
----------------------------
@@ -574,21 +728,17 @@ package body Inline is
-- Start of processing for Add_Inlined_Subprogram
begin
- -- If the subprogram is to be inlined, and if its unit is known to be
- -- inlined or is an instance whose body will be analyzed anyway or the
- -- subprogram was generated as a body by the compiler (for example an
- -- initialization procedure) or its declaration was provided along with
- -- the body (for example an expression function), and if it is declared
- -- at the library level not in the main unit, and if it can be inlined
- -- by the back-end, then insert it in the list of inlined subprograms.
-
- if Is_Inlined (E)
- and then (Is_Inlined (Pack)
- or else Is_Generic_Instance (Pack)
- or else Nkind (Decl) = N_Subprogram_Body
- or else Present (Corresponding_Body (Decl)))
- and then not In_Main_Unit_Or_Subunit (E)
- and then not Is_Nested (E)
+ -- We can inline the subprogram if its unit is known to be inlined or is
+ -- an instance whose body will be analyzed anyway or the subprogram was
+ -- generated as a body by the compiler (for example an initialization
+ -- procedure) or its declaration was provided along with the body (for
+ -- example an expression function) and it does not declare types with
+ -- nontrivial initialization procedures.
+
+ if (Is_Inlined (Pack)
+ or else Is_Generic_Instance (Pack)
+ or else Nkind (Decl) = N_Subprogram_Body
+ or else Present (Corresponding_Body (Decl)))
and then not Has_Initialized_Type (E)
then
Register_Backend_Inlined_Subprogram (E);
@@ -606,6 +756,61 @@ package body Inline is
end if;
end Add_Inlined_Subprogram;
+ --------------------------------
+ -- Add_Pending_Instantiation --
+ --------------------------------
+
+ procedure Add_Pending_Instantiation (Inst : Node_Id; Act_Decl : Node_Id) is
+ Act_Decl_Id : Entity_Id;
+ Index : Int;
+
+ begin
+ -- Here is a defense against a ludicrous number of instantiations
+ -- caused by a circular set of instantiation attempts.
+
+ if Pending_Instantiations.Last + 1 >= Maximum_Instantiations then
+ Error_Msg_Uint_1 := UI_From_Int (Maximum_Instantiations);
+ Error_Msg_N ("too many instantiations, exceeds max of^", Inst);
+ Error_Msg_N ("\limit can be changed using -gnateinn switch", Inst);
+ raise Unrecoverable_Error;
+ end if;
+
+ -- Capture the body of the generic instantiation along with its context
+ -- for later processing by Instantiate_Bodies.
+
+ Pending_Instantiations.Append
+ ((Act_Decl => Act_Decl,
+ Config_Switches => Save_Config_Switches,
+ Current_Sem_Unit => Current_Sem_Unit,
+ Expander_Status => Expander_Active,
+ Inst_Node => Inst,
+ Local_Suppress_Stack_Top => Local_Suppress_Stack_Top,
+ Scope_Suppress => Scope_Suppress,
+ Warnings => Save_Warnings));
+
+ -- With back-end inlining, also associate the index to the instantiation
+
+ if Back_End_Inlining then
+ Act_Decl_Id := Defining_Entity (Act_Decl);
+ Index := Pending_Instantiations.Last;
+
+ To_Pending_Instantiations.Set (Act_Decl, Index);
+
+ -- If an instantiation is in the main unit or subunit, or is a nested
+ -- subprogram, then its body is needed as per the analysis done in
+ -- Analyze_Package_Instantiation & Analyze_Subprogram_Instantiation.
+
+ if In_Main_Unit_Or_Subunit (Act_Decl_Id)
+ or else (Is_Subprogram (Act_Decl_Id)
+ and then Is_Nested (Act_Decl_Id))
+ then
+ Called_Pending_Instantiations.Append (Index);
+
+ Set_Is_Called (Act_Decl_Id);
+ end if;
+ end if;
+ end Add_Pending_Instantiation;
+
------------------------
-- Add_Scope_To_Clean --
------------------------
@@ -1808,6 +2013,8 @@ package body Inline is
Original_Body : Node_Id;
Body_To_Analyze : Node_Id;
+ -- Start of processing for Build_Body_To_Inline
+
begin
pragma Assert (Current_Scope = Spec_Id);
@@ -2215,6 +2422,18 @@ package body Inline is
elsif Present (Body_To_Inline (Decl)) then
return;
+ -- Do not generate a body to inline for protected functions, because the
+ -- transformation generates a call to a protected procedure, causing
+ -- spurious errors. We don't inline protected operations anyway, so
+ -- this is no loss. We might as well ignore intrinsics and foreign
+ -- conventions as well -- just allow Ada conventions.
+
+ elsif not (Convention (Spec_Id) = Convention_Ada
+ or else Convention (Spec_Id) = Convention_Ada_Pass_By_Copy
+ or else Convention (Spec_Id) = Convention_Ada_Pass_By_Reference)
+ then
+ return;
+
-- Check excluded declarations
elsif Present (Declarations (N))
@@ -4193,8 +4412,8 @@ package body Inline is
procedure Initialize is
begin
- Pending_Descriptor.Init;
Pending_Instantiations.Init;
+ Called_Pending_Instantiations.Init;
Inlined_Bodies.Init;
Successors.Init;
Inlined.Init;
@@ -4205,6 +4424,7 @@ package body Inline is
Inlined_Calls := No_Elist;
Backend_Calls := No_Elist;
+ Backend_Instances := No_Elist;
Backend_Inlined_Subps := No_Elist;
Backend_Not_Inlined_Subps := No_Elist;
end Initialize;
@@ -4221,9 +4441,43 @@ package body Inline is
-- the body is an internal error.
procedure Instantiate_Bodies is
- J : Nat;
+
+ procedure Instantiate_Body (Info : Pending_Body_Info);
+ -- Instantiate a pending body
+
+ ------------------------
+ -- Instantiate_Body --
+ ------------------------
+
+ procedure Instantiate_Body (Info : Pending_Body_Info) is
+ begin
+ -- If the instantiation node is absent, it has been removed as part
+ -- of unreachable code.
+
+ if No (Info.Inst_Node) then
+ null;
+
+ -- If the instantiation node is a package body, this means that the
+ -- instance is a compilation unit and the instantiation has already
+ -- been performed by Build_Instance_Compilation_Unit_Nodes.
+
+ elsif Nkind (Info.Inst_Node) = N_Package_Body then
+ null;
+
+ elsif Nkind (Info.Act_Decl) = N_Package_Declaration then
+ Instantiate_Package_Body (Info);
+ Add_Scope_To_Clean (Defining_Entity (Info.Act_Decl));
+
+ else
+ Instantiate_Subprogram_Body (Info);
+ end if;
+ end Instantiate_Body;
+
+ J, K : Nat;
Info : Pending_Body_Info;
+ -- Start of processing for Instantiate_Bodies
+
begin
if Serious_Errors_Detected = 0 then
Expander_Active := (Operating_Mode = Opt.Generate_Code);
@@ -4236,36 +4490,41 @@ package body Inline is
-- A body instantiation may generate additional instantiations, so
-- the following loop must scan to the end of a possibly expanding
- -- set (that's why we can't simply use a FOR loop here).
+ -- set (that's why we cannot simply use a FOR loop here). We must
+ -- also capture the element lest the set be entirely reallocated.
J := 0;
- while J <= Pending_Instantiations.Last
- and then Serious_Errors_Detected = 0
- loop
- Info := Pending_Instantiations.Table (J);
-
- -- If the instantiation node is absent, it has been removed
- -- as part of unreachable code.
-
- if No (Info.Inst_Node) then
- null;
+ if Back_End_Inlining then
+ while J <= Called_Pending_Instantiations.Last
+ and then Serious_Errors_Detected = 0
+ loop
+ K := Called_Pending_Instantiations.Table (J);
+ Info := Pending_Instantiations.Table (K);
+ Instantiate_Body (Info);
- elsif Nkind (Info.Act_Decl) = N_Package_Declaration then
- Instantiate_Package_Body (Info);
- Add_Scope_To_Clean (Defining_Entity (Info.Act_Decl));
+ J := J + 1;
+ end loop;
- else
- Instantiate_Subprogram_Body (Info);
- end if;
+ else
+ while J <= Pending_Instantiations.Last
+ and then Serious_Errors_Detected = 0
+ loop
+ Info := Pending_Instantiations.Table (J);
+ Instantiate_Body (Info);
- J := J + 1;
- end loop;
+ J := J + 1;
+ end loop;
+ end if;
-- Reset the table of instantiations. Additional instantiations
-- may be added through inlining, when additional bodies are
-- analyzed.
- Pending_Instantiations.Init;
+ if Back_End_Inlining then
+ Called_Pending_Instantiations.Init;
+ else
+ Pending_Instantiations.Init;
+ end if;
-- We can now complete the cleanup actions of scopes that contain
-- pending instantiations (skipped for generic units, since we
@@ -4293,7 +4552,7 @@ package body Inline is
begin
Scop := Scope (E);
while Scop /= Standard_Standard loop
- if Ekind (Scop) in Subprogram_Kind then
+ if Is_Subprogram (Scop) then
return True;
elsif Ekind (Scop) = E_Task_Type
@@ -4331,7 +4590,7 @@ package body Inline is
while Present (Elmt) loop
Nod := Node (Elmt);
- if In_Extended_Main_Code_Unit (Nod) then
+ if not In_Internal_Unit (Nod) then
Count := Count + 1;
if Count = 1 then
@@ -4360,7 +4619,7 @@ package body Inline is
while Present (Elmt) loop
Nod := Node (Elmt);
- if In_Extended_Main_Code_Unit (Nod) then
+ if not In_Internal_Unit (Nod) then
Count := Count + 1;
if Count = 1 then
@@ -4379,6 +4638,34 @@ package body Inline is
end loop;
end if;
+ -- Generate listing of instances inlined for the backend
+
+ if Present (Backend_Instances) then
+ Count := 0;
+
+ Elmt := First_Elmt (Backend_Instances);
+ while Present (Elmt) loop
+ Nod := Node (Elmt);
+
+ if not In_Internal_Unit (Nod) then
+ Count := Count + 1;
+
+ if Count = 1 then
+ Write_Str ("List of instances inlined for the backend");
+ Write_Eol;
+ end if;
+
+ Write_Str (" ");
+ Write_Int (Count);
+ Write_Str (":");
+ Write_Location (Sloc (Nod));
+ Output.Write_Eol;
+ end if;
+
+ Next_Elmt (Elmt);
+ end loop;
+ end if;
+
-- Generate listing of subprograms passed to the backend
if Present (Backend_Inlined_Subps) and then Back_End_Inlining then
@@ -4388,22 +4675,24 @@ package body Inline is
while Present (Elmt) loop
Nod := Node (Elmt);
- Count := Count + 1;
+ if not In_Internal_Unit (Nod) then
+ Count := Count + 1;
- if Count = 1 then
- Write_Str
- ("List of inlined subprograms passed to the backend");
- Write_Eol;
- end if;
+ if Count = 1 then
+ Write_Str
+ ("List of inlined subprograms passed to the backend");
+ Write_Eol;
+ end if;
- Write_Str (" ");
- Write_Int (Count);
- Write_Str (":");
- Write_Name (Chars (Nod));
- Write_Str (" (");
- Write_Location (Sloc (Nod));
- Write_Str (")");
- Output.Write_Eol;
+ Write_Str (" ");
+ Write_Int (Count);
+ Write_Str (":");
+ Write_Name (Chars (Nod));
+ Write_Str (" (");
+ Write_Location (Sloc (Nod));
+ Write_Str (")");
+ Output.Write_Eol;
+ end if;
Next_Elmt (Elmt);
end loop;
@@ -4418,22 +4707,24 @@ package body Inline is
while Present (Elmt) loop
Nod := Node (Elmt);
- Count := Count + 1;
+ if not In_Internal_Unit (Nod) then
+ Count := Count + 1;
- if Count = 1 then
- Write_Str
- ("List of subprograms that cannot be inlined by the backend");
- Write_Eol;
- end if;
+ if Count = 1 then
+ Write_Str
+ ("List of subprograms that cannot be inlined by backend");
+ Write_Eol;
+ end if;
- Write_Str (" ");
- Write_Int (Count);
- Write_Str (":");
- Write_Name (Chars (Nod));
- Write_Str (" (");
- Write_Location (Sloc (Nod));
- Write_Str (")");
- Output.Write_Eol;
+ Write_Str (" ");
+ Write_Int (Count);
+ Write_Str (":");
+ Write_Name (Chars (Nod));
+ Write_Str (" (");
+ Write_Location (Sloc (Nod));
+ Write_Str (")");
+ Output.Write_Eol;
+ end if;
Next_Elmt (Elmt);
end loop;
@@ -4448,6 +4739,8 @@ package body Inline is
begin
Pending_Instantiations.Release;
Pending_Instantiations.Locked := True;
+ Called_Pending_Instantiations.Release;
+ Called_Pending_Instantiations.Locked := True;
Inlined_Bodies.Release;
Inlined_Bodies.Locked := True;
Successors.Release;
diff --git a/gcc/ada/inline.ads b/gcc/ada/inline.ads
index 0e5a47e..ed342f5 100644
--- a/gcc/ada/inline.ads
+++ b/gcc/ada/inline.ads
@@ -42,10 +42,8 @@
-- Inline_Always subprograms, but there are fewer restrictions on the source
-- of subprograms.
-with Alloc;
with Opt; use Opt;
with Sem; use Sem;
-with Table;
with Types; use Types;
with Warnsw; use Warnsw;
@@ -100,28 +98,6 @@ package Inline is
-- Capture values of warning flags
end record;
- package Pending_Instantiations is new Table.Table (
- Table_Component_Type => Pending_Body_Info,
- Table_Index_Type => Int,
- Table_Low_Bound => 0,
- Table_Initial => Alloc.Pending_Instantiations_Initial,
- Table_Increment => Alloc.Pending_Instantiations_Increment,
- Table_Name => "Pending_Instantiations");
-
- -- The following table records subprograms and packages for which
- -- generation of subprogram descriptors must be delayed.
-
- package Pending_Descriptor is new Table.Table (
- Table_Component_Type => Entity_Id,
- Table_Index_Type => Int,
- Table_Low_Bound => 0,
- Table_Initial => Alloc.Pending_Instantiations_Initial,
- Table_Increment => Alloc.Pending_Instantiations_Increment,
- Table_Name => "Pending_Descriptor");
-
- -- The following should be initialized in an init call in Frontend, we
- -- have thoughts of making the frontend reusable in future ???
-
-----------------
-- Subprograms --
-----------------
@@ -143,6 +119,9 @@ package Inline is
-- Add E's enclosing unit to Inlined_Bodies so that E can be subsequently
-- retrieved and analyzed. N is the node giving rise to the call to E.
+ procedure Add_Pending_Instantiation (Inst : Node_Id; Act_Decl : Node_Id);
+ -- Add an entry in the table of generic bodies to be instantiated.
+
procedure Analyze_Inlined_Bodies;
-- At end of compilation, analyze the bodies of all units that contain
-- inlined subprograms that are actually called.
diff --git a/gcc/ada/libgnarl/s-taprop__vxworks.adb b/gcc/ada/libgnarl/s-taprop__vxworks.adb
index 80a7290..6ef0a9b 100644
--- a/gcc/ada/libgnarl/s-taprop__vxworks.adb
+++ b/gcc/ada/libgnarl/s-taprop__vxworks.adb
@@ -192,7 +192,10 @@ package body System.Task_Primitives.Operations is
procedure Abort_Handler (signo : Signal) is
pragma Unreferenced (signo);
- Self_ID : constant Task_Id := Self;
+ -- Do not call Self at this point as we're in a signal handler
+ -- and it may not be available, in particular on targets where we
+ -- support ZCX and where we don't do anything here anyway.
+ Self_ID : Task_Id;
Old_Set : aliased sigset_t;
Unblocked_Mask : aliased sigset_t;
Result : int;
@@ -208,6 +211,8 @@ package body System.Task_Primitives.Operations is
return;
end if;
+ Self_ID := Self;
+
if Self_ID.Deferral_Level = 0
and then Self_ID.Pending_ATC_Level < Self_ID.ATC_Nesting_Level
and then not Self_ID.Aborting
diff --git a/gcc/ada/libgnat/a-cbmutr.adb b/gcc/ada/libgnat/a-cbmutr.adb
index cdc2629..fb8585a 100644
--- a/gcc/ada/libgnat/a-cbmutr.adb
+++ b/gcc/ada/libgnat/a-cbmutr.adb
@@ -1767,10 +1767,8 @@ package body Ada.Containers.Bounded_Multiway_Trees is
(Container : Tree;
From, To : Count_Type) return Boolean
is
- Idx : Count_Type;
-
+ Idx : Count_Type'Base := From;
begin
- Idx := From;
while Idx >= 0 loop
if Idx = To then
return True;
diff --git a/gcc/ada/libgnat/a-cfdlli.ads b/gcc/ada/libgnat/a-cfdlli.ads
index f6bf8c9..b8df023 100644
--- a/gcc/ada/libgnat/a-cfdlli.ads
+++ b/gcc/ada/libgnat/a-cfdlli.ads
@@ -34,6 +34,7 @@ with Ada.Containers.Functional_Maps;
generic
type Element_Type is private;
+ with function "=" (Left, Right : Element_Type) return Boolean is <>;
package Ada.Containers.Formal_Doubly_Linked_Lists with
SPARK_Mode
diff --git a/gcc/ada/libgnat/a-cfhama.ads b/gcc/ada/libgnat/a-cfhama.ads
index 643a949..c4e8221 100644
--- a/gcc/ada/libgnat/a-cfhama.ads
+++ b/gcc/ada/libgnat/a-cfhama.ads
@@ -59,6 +59,7 @@ generic
with function Equivalent_Keys
(Left : Key_Type;
Right : Key_Type) return Boolean is "=";
+ with function "=" (Left, Right : Element_Type) return Boolean is <>;
package Ada.Containers.Formal_Hashed_Maps with
SPARK_Mode
diff --git a/gcc/ada/libgnat/a-cfinve.adb b/gcc/ada/libgnat/a-cfinve.adb
index 36df8e6..a187128 100644
--- a/gcc/ada/libgnat/a-cfinve.adb
+++ b/gcc/ada/libgnat/a-cfinve.adb
@@ -457,7 +457,7 @@ is
Item : Element_Type;
Index : Index_Type := Index_Type'First) return Extended_Index
is
- K : Capacity_Range;
+ K : Count_Type;
Last : constant Index_Type := Last_Index (Container);
begin
@@ -1277,7 +1277,7 @@ is
Index : Index_Type := Index_Type'Last) return Extended_Index
is
Last : Index_Type'Base;
- K : Capacity_Range;
+ K : Count_Type'Base;
begin
if Index > Last_Index (Container) then
diff --git a/gcc/ada/libgnat/a-cfinve.ads b/gcc/ada/libgnat/a-cfinve.ads
index e359f8d..87940d2 100644
--- a/gcc/ada/libgnat/a-cfinve.ads
+++ b/gcc/ada/libgnat/a-cfinve.ads
@@ -38,6 +38,7 @@ with Ada.Containers.Functional_Vectors;
generic
type Index_Type is range <>;
type Element_Type (<>) is private;
+ with function "=" (Left, Right : Element_Type) return Boolean is <>;
Max_Size_In_Storage_Elements : Natural;
-- Maximum size of Vector elements in bytes. This has the same meaning as
-- in Ada.Containers.Bounded_Holders, with the same restrictions. Note that
diff --git a/gcc/ada/libgnat/a-cforma.ads b/gcc/ada/libgnat/a-cforma.ads
index d76cc76..a13bce4 100644
--- a/gcc/ada/libgnat/a-cforma.ads
+++ b/gcc/ada/libgnat/a-cforma.ads
@@ -58,6 +58,7 @@ generic
type Element_Type is private;
with function "<" (Left, Right : Key_Type) return Boolean is <>;
+ with function "=" (Left, Right : Element_Type) return Boolean is <>;
package Ada.Containers.Formal_Ordered_Maps with
SPARK_Mode
diff --git a/gcc/ada/libgnat/a-cgaaso.ads b/gcc/ada/libgnat/a-cgaaso.ads
index 60bfd22..3622702 100644
--- a/gcc/ada/libgnat/a-cgaaso.ads
+++ b/gcc/ada/libgnat/a-cgaaso.ads
@@ -39,3 +39,16 @@ generic
procedure Ada.Containers.Generic_Anonymous_Array_Sort
(First, Last : Index_Type'Base);
pragma Pure (Ada.Containers.Generic_Anonymous_Array_Sort);
+-- Reorders the elements of Container such that the elements are sorted
+-- smallest first as determined by the generic formal "<" operator provided.
+-- Any exception raised during evaluation of "<" is propagated.
+--
+-- The actual function for the generic formal function "<" is expected to
+-- return the same value each time it is called with a particular pair of
+-- element values. It should not modify Container and it should define a
+-- strict weak ordering relationship: irreflexive, asymmetric, transitive, and
+-- in addition, if x < y for any values x and y, then for all other values z,
+-- (x < z) or (z < y). If the actual for "<" behaves in some other manner,
+-- the behavior of the instance of Generic_Anonymous_Array_Sort is
+-- unspecified. The number of times Generic_Anonymous_Array_Sort calls "<" is
+-- unspecified.
diff --git a/gcc/ada/libgnat/a-cgarso.ads b/gcc/ada/libgnat/a-cgarso.ads
index 77281b5..1a64673 100644
--- a/gcc/ada/libgnat/a-cgarso.ads
+++ b/gcc/ada/libgnat/a-cgarso.ads
@@ -18,9 +18,19 @@ generic
type Element_Type is private;
type Array_Type is array (Index_Type range <>) of Element_Type;
- with function "<" (Left, Right : Element_Type)
- return Boolean is <>;
+ with function "<" (Left, Right : Element_Type) return Boolean is <>;
procedure Ada.Containers.Generic_Array_Sort (Container : in out Array_Type);
-
pragma Pure (Ada.Containers.Generic_Array_Sort);
+-- Reorders the elements of Container such that the elements are sorted
+-- smallest first as determined by the generic formal "<" operator provided.
+-- Any exception raised during evaluation of "<" is propagated.
+--
+-- The actual function for the generic formal function "<" is expected to
+-- return the same value each time it is called with a particular pair of
+-- element values. It should not modify Container and it should define a
+-- strict weak ordering relationship: irreflexive, asymmetric, transitive, and
+-- in addition, if x < y for any values x and y, then for all other values z,
+-- (x < z) or (z < y). If the actual for "<" behaves in some other manner,
+-- the behavior of the instance of Generic_Array_Sort is unspecified. The
+-- number of times Generic_Array_Sort calls "<" is unspecified.
diff --git a/gcc/ada/libgnat/a-cofove.adb b/gcc/ada/libgnat/a-cofove.adb
index c848ad8..3a10d32 100644
--- a/gcc/ada/libgnat/a-cofove.adb
+++ b/gcc/ada/libgnat/a-cofove.adb
@@ -378,7 +378,7 @@ is
Item : Element_Type;
Index : Index_Type := Index_Type'First) return Extended_Index
is
- K : Capacity_Range;
+ K : Count_Type;
Last : constant Index_Type := Last_Index (Container);
begin
@@ -1147,7 +1147,7 @@ is
Index : Index_Type := Index_Type'Last) return Extended_Index
is
Last : Index_Type'Base;
- K : Capacity_Range;
+ K : Count_Type'Base;
begin
if Index > Last_Index (Container) then
diff --git a/gcc/ada/libgnat/a-cofove.ads b/gcc/ada/libgnat/a-cofove.ads
index 5b62664..b23c661 100644
--- a/gcc/ada/libgnat/a-cofove.ads
+++ b/gcc/ada/libgnat/a-cofove.ads
@@ -40,6 +40,8 @@ with Ada.Containers.Functional_Vectors;
generic
type Index_Type is range <>;
type Element_Type is private;
+ with function "=" (Left, Right : Element_Type) return Boolean is <>;
+
package Ada.Containers.Formal_Vectors with
SPARK_Mode
is
diff --git a/gcc/ada/libgnat/a-cofuba.adb b/gcc/ada/libgnat/a-cofuba.adb
index bfd2a9e..5c5f488 100644
--- a/gcc/ada/libgnat/a-cofuba.adb
+++ b/gcc/ada/libgnat/a-cofuba.adb
@@ -30,6 +30,7 @@
------------------------------------------------------------------------------
pragma Ada_2012;
+with Ada.Unchecked_Deallocation;
package body Ada.Containers.Functional_Base with SPARK_Mode => Off is
@@ -47,18 +48,22 @@ package body Ada.Containers.Functional_Base with SPARK_Mode => Off is
-- Search a container C for an element equal to E.all, returning the
-- position in the underlying array.
+ procedure Resize (Base : Array_Base_Access);
+ -- Resize the underlying array if needed so that it can contain one more
+ -- element.
+
---------
-- "=" --
---------
function "=" (C1 : Container; C2 : Container) return Boolean is
begin
- if C1.Elements'Length /= C2.Elements'Length then
+ if C1.Length /= C2.Length then
return False;
end if;
- for I in C1.Elements'Range loop
- if C1.Elements (I).all /= C2.Elements (I).all then
+ for I in 1 .. C1.Length loop
+ if C1.Base.Elements (I).all /= C2.Base.Elements (I).all then
return False;
end if;
end loop;
@@ -72,8 +77,8 @@ package body Ada.Containers.Functional_Base with SPARK_Mode => Off is
function "<=" (C1 : Container; C2 : Container) return Boolean is
begin
- for I in C1.Elements'Range loop
- if Find (C2, C1.Elements (I)) = 0 then
+ for I in 1 .. C1.Length loop
+ if Find (C2, C1.Base.Elements (I)) = 0 then
return False;
end if;
end loop;
@@ -90,31 +95,58 @@ package body Ada.Containers.Functional_Base with SPARK_Mode => Off is
I : Index_Type;
E : Element_Type) return Container
is
- A : constant Element_Array_Access :=
- new Element_Array'(1 .. C.Elements'Last + 1 => <>);
- P : Count_Type := 0;
-
begin
- for J in 1 .. C.Elements'Last + 1 loop
- if J /= To_Count (I) then
- P := P + 1;
- A (J) := C.Elements (P);
- else
- A (J) := new Element_Type'(E);
- end if;
- end loop;
-
- return Container'(Elements => A);
+ if To_Count (I) = C.Length + 1 and then C.Length = C.Base.Max_Length then
+ Resize (C.Base);
+ C.Base.Max_Length := C.Base.Max_Length + 1;
+ C.Base.Elements (C.Base.Max_Length) := new Element_Type'(E);
+
+ return Container'(Length => C.Base.Max_Length, Base => C.Base);
+ else
+ declare
+ A : constant Array_Base_Access := Content_Init (C.Length);
+ P : Count_Type := 0;
+ begin
+ A.Max_Length := C.Length + 1;
+ for J in 1 .. C.Length + 1 loop
+ if J /= To_Count (I) then
+ P := P + 1;
+ A.Elements (J) := C.Base.Elements (P);
+ else
+ A.Elements (J) := new Element_Type'(E);
+ end if;
+ end loop;
+
+ return Container'(Length => A.Max_Length,
+ Base => A);
+ end;
+ end if;
end Add;
+ ------------------
+ -- Content_Init --
+ ------------------
+
+ function Content_Init (L : Count_Type := 0) return Array_Base_Access
+ is
+ Max_Init : constant Count_Type := 100;
+ Size : constant Count_Type :=
+ (if L < Count_Type'Last - Max_Init then L + Max_Init
+ else Count_Type'Last);
+ Elements : constant Element_Array_Access :=
+ new Element_Array'(1 .. Size => <>);
+ begin
+ return new Array_Base'(Max_Length => 0, Elements => Elements);
+ end Content_Init;
+
----------
-- Find --
----------
function Find (C : Container; E : access Element_Type) return Count_Type is
begin
- for I in C.Elements'Range loop
- if C.Elements (I).all = E.all then
+ for I in 1 .. C.Length loop
+ if C.Base.Elements (I).all = E.all then
return I;
end if;
end loop;
@@ -130,34 +162,34 @@ package body Ada.Containers.Functional_Base with SPARK_Mode => Off is
---------
function Get (C : Container; I : Index_Type) return Element_Type is
- (C.Elements (To_Count (I)).all);
+ (C.Base.Elements (To_Count (I)).all);
------------------
-- Intersection --
------------------
function Intersection (C1 : Container; C2 : Container) return Container is
- A : constant Element_Array_Access :=
- new Element_Array'(1 .. Num_Overlaps (C1, C2) => <>);
+ L : constant Count_Type := Num_Overlaps (C1, C2);
+ A : constant Array_Base_Access := Content_Init (L);
P : Count_Type := 0;
begin
- for I in C1.Elements'Range loop
- if Find (C2, C1.Elements (I)) > 0 then
+ A.Max_Length := L;
+ for I in 1 .. C1.Length loop
+ if Find (C2, C1.Base.Elements (I)) > 0 then
P := P + 1;
- A (P) := C1.Elements (I);
+ A.Elements (P) := C1.Base.Elements (I);
end if;
end loop;
- return Container'(Elements => A);
+ return Container'(Length => P, Base => A);
end Intersection;
------------
-- Length --
------------
- function Length (C : Container) return Count_Type is (C.Elements'Length);
-
+ function Length (C : Container) return Count_Type is (C.Length);
---------------------
-- Num_Overlaps --
---------------------
@@ -166,8 +198,8 @@ package body Ada.Containers.Functional_Base with SPARK_Mode => Off is
P : Count_Type := 0;
begin
- for I in C1.Elements'Range loop
- if Find (C2, C1.Elements (I)) > 0 then
+ for I in 1 .. C1.Length loop
+ if Find (C2, C1.Base.Elements (I)) > 0 then
P := P + 1;
end if;
end loop;
@@ -180,20 +212,60 @@ package body Ada.Containers.Functional_Base with SPARK_Mode => Off is
------------
function Remove (C : Container; I : Index_Type) return Container is
- A : constant Element_Array_Access :=
- new Element_Array'(1 .. C.Elements'Last - 1 => <>);
- P : Count_Type := 0;
+ begin
+ if To_Count (I) = C.Length then
+ return Container'(Length => C.Length - 1, Base => C.Base);
+ else
+ declare
+ A : constant Array_Base_Access := Content_Init (C.Length - 1);
+ P : Count_Type := 0;
+ begin
+ A.Max_Length := C.Length - 1;
+ for J in 1 .. C.Length loop
+ if J /= To_Count (I) then
+ P := P + 1;
+ A.Elements (P) := C.Base.Elements (J);
+ end if;
+ end loop;
+
+ return Container'(Length => C.Length - 1, Base => A);
+ end;
+ end if;
+ end Remove;
+
+ ------------
+ -- Resize --
+ ------------
+ procedure Resize (Base : Array_Base_Access) is
begin
- for J in C.Elements'Range loop
- if J /= To_Count (I) then
- P := P + 1;
- A (P) := C.Elements (J);
- end if;
- end loop;
+ if Base.Max_Length < Base.Elements'Length then
+ return;
+ end if;
- return Container'(Elements => A);
- end Remove;
+ pragma Assert (Base.Max_Length = Base.Elements'Length);
+
+ if Base.Max_Length = Count_Type'Last then
+ raise Constraint_Error;
+ end if;
+
+ declare
+ procedure Finalize is new Ada.Unchecked_Deallocation
+ (Object => Element_Array,
+ Name => Element_Array_Access_Base);
+
+ New_Length : constant Positive_Count_Type :=
+ (if Base.Max_Length > Count_Type'Last / 2 then Count_Type'Last
+ else 2 * Base.Max_Length);
+ Elements : constant Element_Array_Access :=
+ new Element_Array (1 .. New_Length);
+ Old_Elmts : Element_Array_Access_Base := Base.Elements;
+ begin
+ Elements (1 .. Base.Max_Length) := Base.Elements.all;
+ Base.Elements := Elements;
+ Finalize (Old_Elmts);
+ end;
+ end Resize;
---------
-- Set --
@@ -205,10 +277,13 @@ package body Ada.Containers.Functional_Base with SPARK_Mode => Off is
E : Element_Type) return Container
is
Result : constant Container :=
- Container'(Elements => new Element_Array'(C.Elements.all));
+ Container'(Length => C.Length,
+ Base => Content_Init (C.Length));
begin
- Result.Elements (To_Count (I)) := new Element_Type'(E);
+ Result.Base.Max_Length := C.Length;
+ Result.Base.Elements (1 .. C.Length) := C.Base.Elements (1 .. C.Length);
+ Result.Base.Elements (To_Count (I)) := new Element_Type'(E);
return Result;
end Set;
@@ -230,20 +305,20 @@ package body Ada.Containers.Functional_Base with SPARK_Mode => Off is
declare
L : constant Count_Type := Length (C1) - N + Length (C2);
- A : constant Element_Array_Access :=
- new Element_Array'
- (C1.Elements.all & (Length (C1) + 1 .. L => <>));
+ A : constant Array_Base_Access := Content_Init (L);
P : Count_Type := Length (C1);
begin
- for I in C2.Elements'Range loop
- if Find (C1, C2.Elements (I)) = 0 then
+ A.Max_Length := L;
+ A.Elements (1 .. C1.Length) := C1.Base.Elements (1 .. C1.Length);
+ for I in 1 .. C2.Length loop
+ if Find (C1, C2.Base.Elements (I)) = 0 then
P := P + 1;
- A (P) := C2.Elements (I);
+ A.Elements (P) := C2.Base.Elements (I);
end if;
end loop;
- return Container'(Elements => A);
+ return Container'(Length => L, Base => A);
end;
end Union;
diff --git a/gcc/ada/libgnat/a-cofuba.ads b/gcc/ada/libgnat/a-cofuba.ads
index 3010782..b693baa 100644
--- a/gcc/ada/libgnat/a-cofuba.ads
+++ b/gcc/ada/libgnat/a-cofuba.ads
@@ -105,13 +105,26 @@ private
type Element_Array is
array (Positive_Count_Type range <>) of Element_Access;
- type Element_Array_Access is not null access Element_Array;
+ type Element_Array_Access_Base is access Element_Array;
+
+ subtype Element_Array_Access is not null Element_Array_Access_Base;
Empty_Element_Array_Access : constant Element_Array_Access :=
new Element_Array'(1 .. 0 => null);
+ type Array_Base is record
+ Max_Length : Count_Type;
+ Elements : Element_Array_Access;
+ end record;
+
+ type Array_Base_Access is not null access Array_Base;
+
+ function Content_Init (L : Count_Type := 0) return Array_Base_Access;
+ -- Used to initialize the content of an array base with length L
+
type Container is record
- Elements : Element_Array_Access := Empty_Element_Array_Access;
+ Length : Count_Type := 0;
+ Base : Array_Base_Access := Content_Init;
end record;
end Ada.Containers.Functional_Base;
diff --git a/gcc/ada/libgnat/a-cofuma.ads b/gcc/ada/libgnat/a-cofuma.ads
index 8a71cb7..bf6e5a8 100644
--- a/gcc/ada/libgnat/a-cofuma.ads
+++ b/gcc/ada/libgnat/a-cofuma.ads
@@ -39,6 +39,7 @@ generic
with function Equivalent_Keys
(Left : Key_Type;
Right : Key_Type) return Boolean is "=";
+ with function "=" (Left, Right : Element_Type) return Boolean is <>;
Enable_Handling_Of_Equivalence : Boolean := True;
-- This constant should only be set to False when no particular handling
diff --git a/gcc/ada/libgnat/a-cofuve.ads b/gcc/ada/libgnat/a-cofuve.ads
index 4f80450..804d7b0 100644
--- a/gcc/ada/libgnat/a-cofuve.ads
+++ b/gcc/ada/libgnat/a-cofuve.ads
@@ -38,6 +38,7 @@ generic
-- should have at least one more element at the low end than Index_Type.
type Element_Type (<>) is private;
+ with function "=" (Left, Right : Element_Type) return Boolean is <>;
package Ada.Containers.Functional_Vectors with SPARK_Mode is
diff --git a/gcc/ada/libgnat/a-cogeso.ads b/gcc/ada/libgnat/a-cogeso.ads
index a707072..e77558f 100644
--- a/gcc/ada/libgnat/a-cogeso.ads
+++ b/gcc/ada/libgnat/a-cogeso.ads
@@ -38,3 +38,19 @@ generic
procedure Ada.Containers.Generic_Sort (First, Last : Index_Type'Base);
pragma Pure (Ada.Containers.Generic_Sort);
+-- Reorders the elements of an indexable structure, over the range
+-- First .. Last, such that the elements are sorted in the ordering determined
+-- by the generic formal function Before; Before should return True if Left is
+-- to be sorted before Right. The generic formal Before compares the elements
+-- having the given indices, and the generic formal Swap exchanges the values
+-- of the indicated elements. Any exception raised during evaluation of Before
+-- or Swap is propagated.
+--
+-- The actual function for the generic formal function "<" is expected to
+-- return the same value each time it is called with a particular pair of
+-- element values. It should not modify Container and it should define a
+-- strict weak ordering relationship: irreflexive, asymmetric, transitive, and
+-- in addition, if x < y for any values x and y, then for all other values z,
+-- (x < z) or (z < y). If the actual for "<" behaves in some other manner,
+-- the behavior of the instance of Generic_Sort is unspecified. The number of
+-- times Generic_Sort calls "<" is unspecified.
diff --git a/gcc/ada/libgnat/a-contai.ads b/gcc/ada/libgnat/a-contai.ads
index be8a808..d6189a3 100644
--- a/gcc/ada/libgnat/a-contai.ads
+++ b/gcc/ada/libgnat/a-contai.ads
@@ -17,8 +17,12 @@ package Ada.Containers is
pragma Pure;
type Hash_Type is mod 2**32;
+ -- Represents the range of the result of a hash function
+
type Count_Type is range 0 .. 2**31 - 1;
+ -- Represents the (potential or actual) number of elements of a container
Capacity_Error : exception;
+ -- Raised when the capacity of a container is exceeded
end Ada.Containers;
diff --git a/gcc/ada/libgnat/a-dhfina.adb b/gcc/ada/libgnat/a-dhfina.adb
new file mode 100644
index 0000000..df7c345
--- /dev/null
+++ b/gcc/ada/libgnat/a-dhfina.adb
@@ -0,0 +1,332 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME COMPONENTS --
+-- --
+-- ADA.DIRECTORIES.HIERARCHICAL_FILE_NAMES --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2004-2019, Free Software Foundation, Inc. --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- In particular, you can freely distribute your programs built with the --
+-- GNAT Pro compiler, including any required library run-time units, using --
+-- any licensing terms of your choosing. See the AdaCore Software License --
+-- for full details. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+with Ada.Characters.Handling; use Ada.Characters.Handling;
+with Ada.Directories.Validity; use Ada.Directories.Validity;
+with Ada.Strings.Fixed; use Ada.Strings.Fixed;
+with System; use System;
+
+package body Ada.Directories.Hierarchical_File_Names is
+
+ Dir_Separator : constant Character;
+ pragma Import (C, Dir_Separator, "__gnat_dir_separator");
+ -- Running system default directory separator
+
+ -----------------
+ -- Subprograms --
+ -----------------
+
+ function Equivalent_File_Names
+ (Left : String;
+ Right : String)
+ return Boolean;
+ -- Perform an OS-independent comparison between two file paths
+
+ function Is_Absolute_Path (Name : String) return Boolean;
+ -- Returns True if Name is an absolute path name, i.e. it designates a
+ -- file or directory absolutely rather than relative to another directory.
+
+ ---------------------------
+ -- Equivalent_File_Names --
+ ---------------------------
+
+ function Equivalent_File_Names
+ (Left : String;
+ Right : String)
+ return Boolean
+ is
+ begin
+ -- Check the validity of the input paths
+
+ if not Is_Valid_Path_Name (Left)
+ or else not Is_Valid_Path_Name (Right)
+ then
+ return False;
+ end if;
+
+ -- Normalize the paths by removing any trailing directory separators and
+ -- perform the comparison.
+
+ declare
+ Normal_Left : constant String :=
+ (if Index (Left, Dir_Separator & "", Strings.Backward) = Left'Last
+ and then not Is_Root_Directory_Name (Left)
+ then
+ Left (Left'First .. Left'Last - 1)
+ else
+ Left);
+
+ Normal_Right : constant String :=
+ (if Index (Right, Dir_Separator & "", Strings.Backward) = Right'Last
+ and then not Is_Root_Directory_Name (Right)
+ then
+ Right (Right'First .. Right'Last - 1)
+ else
+ Right);
+ begin
+ -- Within Windows we assume case insensitivity
+
+ if not Windows then
+ return Normal_Left = Normal_Right;
+ end if;
+
+ -- Otherwise do a straight comparison
+
+ return To_Lower (Normal_Left) = To_Lower (Normal_Right);
+ end;
+ end Equivalent_File_Names;
+
+ ----------------------
+ -- Is_Absolute_Path --
+ ----------------------
+
+ function Is_Absolute_Path (Name : String) return Boolean is
+ function Is_Absolute_Path
+ (Name : Address;
+ Length : Integer) return Integer;
+ pragma Import (C, Is_Absolute_Path, "__gnat_is_absolute_path");
+ begin
+ return Is_Absolute_Path (Name'Address, Name'Length) /= 0;
+ end Is_Absolute_Path;
+
+ --------------------
+ -- Is_Simple_Name --
+ --------------------
+
+ function Is_Simple_Name (Name : String) return Boolean is
+ begin
+ -- Verify the file path name is valid and that it is not a root
+
+ if not Is_Valid_Path_Name (Name)
+ or else Is_Root_Directory_Name (Name)
+ then
+ return False;
+ end if;
+
+ -- Check for the special paths "." and "..", which are considered simple
+
+ if Is_Parent_Directory_Name (Name)
+ or else Is_Current_Directory_Name (Name)
+ then
+ return True;
+ end if;
+
+ -- Perform a comparison with the calculated simple path name
+
+ return Equivalent_File_Names (Simple_Name (Name), Name);
+ end Is_Simple_Name;
+
+ ----------------------------
+ -- Is_Root_Directory_Name --
+ ----------------------------
+
+ function Is_Root_Directory_Name (Name : String) return Boolean is
+ begin
+ -- Check if the path name is a root directory by looking for a slash in
+ -- the general case, and a drive letter in the case of Windows.
+
+ return Name = "/"
+ or else
+ (Windows
+ and then
+ (Name = "\"
+ or else
+ (Name'Length = 3
+ and then Name (Name'Last - 1) = ':'
+ and then Name (Name'Last) in '/' | '\'
+ and then (Name (Name'First) in 'a' .. 'z'
+ or else
+ Name (Name'First) in 'A' .. 'Z'))
+ or else
+ (Name'Length = 2
+ and then Name (Name'Last) = ':'
+ and then (Name (Name'First) in 'a' .. 'z'
+ or else
+ Name (Name'First) in 'A' .. 'Z'))));
+ end Is_Root_Directory_Name;
+
+ ------------------------------
+ -- Is_Parent_Directory_Name --
+ ------------------------------
+
+ function Is_Parent_Directory_Name (Name : String) return Boolean is
+ begin
+ return Name = "..";
+ end Is_Parent_Directory_Name;
+
+ -------------------------------
+ -- Is_Current_Directory_Name --
+ -------------------------------
+
+ function Is_Current_Directory_Name (Name : String) return Boolean is
+ begin
+ return Name = ".";
+ end Is_Current_Directory_Name;
+
+ ------------------
+ -- Is_Full_Name --
+ ------------------
+
+ function Is_Full_Name (Name : String) return Boolean is
+ begin
+ return Equivalent_File_Names (Full_Name (Name), Name);
+ end Is_Full_Name;
+
+ ----------------------
+ -- Is_Relative_Name --
+ ----------------------
+
+ function Is_Relative_Name (Name : String) return Boolean is
+ begin
+ return not Is_Absolute_Path (Name)
+ and then Is_Valid_Path_Name (Name);
+ end Is_Relative_Name;
+
+ -----------------------
+ -- Initial_Directory --
+ -----------------------
+
+ function Initial_Directory (Name : String) return String is
+ Start : constant Integer := Index (Name, Dir_Separator & "");
+ begin
+ -- Verify path name
+
+ if not Is_Valid_Path_Name (Name) then
+ raise Name_Error with "invalid path name """ & Name & '"';
+ end if;
+
+ -- When there is no starting directory separator or the path name is a
+ -- root directory then the path name is already simple - so return it.
+
+ if Is_Root_Directory_Name (Name) or else Start = 0 then
+ return Name;
+ end if;
+
+ -- When the initial directory of the path name is a root directory then
+ -- the starting directory separator is part of the result so we must
+ -- return it in the slice.
+
+ if Is_Root_Directory_Name (Name (Name'First .. Start)) then
+ return Name (Name'First .. Start);
+ end if;
+
+ -- Otherwise we grab a slice up to the starting directory separator
+
+ return Name (Name'First .. Start - 1);
+ end Initial_Directory;
+
+ -------------------
+ -- Relative_Name --
+ -------------------
+
+ function Relative_Name (Name : String) return String is
+ begin
+ -- We cannot derive a relative name if Name does not exist
+
+ if not Is_Relative_Name (Name)
+ and then not Is_Valid_Path_Name (Name)
+ then
+ raise Name_Error with "invalid relative path name """ & Name & '"';
+ end if;
+
+ -- Name only has a single part and thus cannot be made relative
+
+ if Is_Simple_Name (Name)
+ or else Is_Root_Directory_Name (Name)
+ then
+ raise Name_Error with
+ "relative path name """ & Name & """ is composed of a single part";
+ end if;
+
+ -- Trim the input according to the initial directory and maintain proper
+ -- directory separation due to the fact that root directories may
+ -- contain separators.
+
+ declare
+ Init_Dir : constant String := Initial_Directory (Name);
+ begin
+ if Init_Dir (Init_Dir'Last) = Dir_Separator then
+ return Name (Name'First + Init_Dir'Length .. Name'Last);
+ end if;
+
+ return Name (Name'First + Init_Dir'Length + 1 .. Name'Last);
+ end;
+ end Relative_Name;
+
+ -------------
+ -- Compose --
+ -------------
+
+ function Compose
+ (Directory : String := "";
+ Relative_Name : String;
+ Extension : String := "") return String
+ is
+ -- Append a directory separator if none is present
+
+ Separated_Dir : constant String :=
+ (if Directory = "" then ""
+ elsif Directory (Directory'Last) = Dir_Separator then Directory
+ else Directory & Dir_Separator);
+ begin
+ -- Check that relative name is valid
+
+ if not Is_Relative_Name (Relative_Name) then
+ raise Name_Error with
+ "invalid relative path name """ & Relative_Name & '"';
+ end if;
+
+ -- Check that directory is valid
+
+ if Separated_Dir /= ""
+ and then (not Is_Valid_Path_Name (Separated_Dir & Relative_Name))
+ then
+ raise Name_Error with
+ "invalid path composition """ & Separated_Dir & Relative_Name & '"';
+ end if;
+
+ -- Check that the extension is valid
+
+ if Extension /= ""
+ and then not Is_Valid_Path_Name
+ (Separated_Dir & Relative_Name & Extension)
+ then
+ raise Name_Error with
+ "invalid path composition """
+ & Separated_Dir & Relative_Name & Extension & '"';
+ end if;
+
+ -- Concatenate the result
+
+ return Separated_Dir & Relative_Name & Extension;
+ end Compose;
+
+end Ada.Directories.Hierarchical_File_Names;
diff --git a/gcc/ada/libgnat/a-dhfina.ads b/gcc/ada/libgnat/a-dhfina.ads
index e34c664..fe32d01 100644
--- a/gcc/ada/libgnat/a-dhfina.ads
+++ b/gcc/ada/libgnat/a-dhfina.ads
@@ -6,41 +6,101 @@
-- --
-- S p e c --
-- --
--- This specification is derived from the Ada Reference Manual for use with --
--- GNAT. In accordance with the copyright of that document, you can freely --
--- copy and modify this specification, provided that if you redistribute a --
--- modified version, any changes that you have made are clearly indicated. --
+-- Copyright (C) 2004-2019, Free Software Foundation, Inc. --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- In particular, you can freely distribute your programs built with the --
+-- GNAT Pro compiler, including any required library run-time units, using --
+-- any licensing terms of your choosing. See the AdaCore Software License --
+-- for full details. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- --
------------------------------------------------------------------------------
package Ada.Directories.Hierarchical_File_Names is
- pragma Unimplemented_Unit;
function Is_Simple_Name (Name : String) return Boolean;
+ -- Returns True if Name is a simple name, and returns False otherwise.
function Is_Root_Directory_Name (Name : String) return Boolean;
+ -- Returns True if Name is syntactically a root (a directory that cannot
+ -- be decomposed further), and returns False otherwise.
function Is_Parent_Directory_Name (Name : String) return Boolean;
+ -- Returns True if Name can be used to indicate symbolically the parent
+ -- directory of any directory, and returns False otherwise.
function Is_Current_Directory_Name (Name : String) return Boolean;
+ -- Returns True if Name can be used to indicate symbolically the directory
+ -- itself for any directory, and returns False otherwise.
function Is_Full_Name (Name : String) return Boolean;
+ -- Returns True if the leftmost directory part of Name is a root, and
+ -- returns False otherwise.
function Is_Relative_Name (Name : String) return Boolean;
+ -- Returns True if Name allows the identification of an external file
+ -- (including directories and special files) but is not a full name, and
+ -- returns False otherwise.
function Simple_Name (Name : String) return String
renames Ada.Directories.Simple_Name;
+ -- Returns the simple name portion of the file name specified by Name. The
+ -- exception Name_Error is propagated if the string given as Name does not
+ -- allow the identification of an external file (including directories and
+ -- special files).
function Containing_Directory (Name : String) return String
renames Ada.Directories.Containing_Directory;
+ -- Returns the name of the containing directory of the external file
+ -- (including directories) identified by Name. If more than one directory
+ -- can contain Name, the directory name returned is implementation-defined.
+ -- The exception Name_Error is propagated if the string given as Name does
+ -- not allow the identification of an external file. The exception
+ -- Use_Error is propagated if the external file does not have a containing
+ -- directory.
function Initial_Directory (Name : String) return String;
+ -- Returns the leftmost directory part in Name. That is, it returns a root
+ -- directory name (for a full name), or one of a parent directory name, a
+ -- current directory name, or a simple name (for a relative name). The
+ -- exception Name_Error is propagated if the string given as Name does not
+ -- allow the identification of an external file (including directories and
+ -- special files).
function Relative_Name (Name : String) return String;
+ -- Returns the entire file name except the Initial_Directory portion. The
+ -- exception Name_Error is propagated if the string given as Name does not
+ -- allow the identification of an external file (including directories and
+ -- special files), or if Name has a single part (this includes if any of
+ -- Is_Simple_Name, Is_Root_Directory_Name, Is_Parent_Directory_Name, or
+ -- Is_Current_Directory_Name are True).
function Compose
(Directory : String := "";
Relative_Name : String;
Extension : String := "") return String;
+ -- Returns the name of the external file with the specified Directory,
+ -- Relative_Name, and Extension. The exception Name_Error is propagated if
+ -- the string given as Directory is not the null string and does not allow
+ -- the identification of a directory, or if Is_Relative_Name
+ -- (Relative_Name) is False, or if the string given as Extension is not
+ -- the null string and is not a possible extension, or if Extension is not
+ -- the null string and Simple_Name (Relative_Name) is not a base name.
+ --
+ -- The result of Compose is a full name if Is_Full_Name (Directory) is
+ -- True; result is a relative name otherwise.
end Ada.Directories.Hierarchical_File_Names;
diff --git a/gcc/ada/libgnat/a-direct.adb b/gcc/ada/libgnat/a-direct.adb
index bc489ca..1a1b708 100644
--- a/gcc/ada/libgnat/a-direct.adb
+++ b/gcc/ada/libgnat/a-direct.adb
@@ -33,6 +33,8 @@ with Ada.Calendar; use Ada.Calendar;
with Ada.Calendar.Formatting; use Ada.Calendar.Formatting;
with Ada.Characters.Handling; use Ada.Characters.Handling;
with Ada.Directories.Validity; use Ada.Directories.Validity;
+with Ada.Directories.Hierarchical_File_Names;
+use Ada.Directories.Hierarchical_File_Names;
with Ada.Strings.Fixed;
with Ada.Strings.Maps; use Ada.Strings.Maps;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
@@ -224,31 +226,22 @@ package body Ada.Directories is
Strings.Fixed.Index (Name, Dir_Seps, Going => Strings.Backward);
begin
- if Last_DS = 0 then
-
- -- There is no directory separator, returns "." representing
- -- the current working directory.
-
- return ".";
-
-- If Name indicates a root directory, raise Use_Error, because
-- it has no containing directory.
- elsif Name = "/"
- or else
- (Windows
- and then
- (Name = "\"
- or else
- (Name'Length = 3
- and then Name (Name'Last - 1 .. Name'Last) = ":\"
- and then (Name (Name'First) in 'a' .. 'z'
- or else
- Name (Name'First) in 'A' .. 'Z'))))
+ if Is_Parent_Directory_Name (Name)
+ or else Is_Current_Directory_Name (Name)
+ or else Is_Root_Directory_Name (Name)
then
raise Use_Error with
"directory """ & Name & """ has no containing directory";
+ elsif Last_DS = 0 then
+ -- There is no directory separator, so return ".", representing
+ -- the current working directory.
+
+ return ".";
+
else
declare
Last : Positive := Last_DS - Name'First + 1;
@@ -262,31 +255,14 @@ package body Ada.Directories is
-- number on Windows.
while Last > 1 loop
- exit when
- Result (Last) /= '/'
- and then
- Result (Last) /= Directory_Separator;
-
- exit when Windows
- and then Last = 3
- and then Result (2) = ':'
- and then
- (Result (1) in 'A' .. 'Z'
- or else
- Result (1) in 'a' .. 'z');
+ exit when Is_Root_Directory_Name (Result (1 .. Last))
+ or else (Result (Last) /= Directory_Separator
+ and then Result (Last) /= '/');
Last := Last - 1;
end loop;
- -- Special case of "..": the current directory may be a root
- -- directory.
-
- if Last = 2 and then Result (1 .. 2) = ".." then
- return Containing_Directory (Current_Directory);
-
- else
- return Result (1 .. Last);
- end if;
+ return Result (1 .. Last);
end;
end if;
end;
@@ -806,6 +782,20 @@ package body Ada.Directories is
end if;
if Exists = 1 then
+ -- Ignore special directories "." and ".."
+
+ if (Full_Name'Length > 1
+ and then
+ Full_Name
+ (Full_Name'Last - 1 .. Full_Name'Last) = "\.")
+ or else
+ (Full_Name'Length > 2
+ and then
+ Full_Name
+ (Full_Name'Last - 2 .. Full_Name'Last) = "\..")
+ then
+ Exists := 0;
+ end if;
-- Now check if the file kind matches the filter
@@ -1280,16 +1270,30 @@ package body Ada.Directories is
function Simple_Name_Internal (Path : String) return String is
Cut_Start : Natural :=
Strings.Fixed.Index (Path, Dir_Seps, Going => Strings.Backward);
- Cut_End : Natural;
+
+ -- Cut_End points to the last simple name character
+
+ Cut_End : Natural := Path'Last;
begin
- -- Cut_Start pointS to the first simple name character
+ -- Root directories are considered simple
- Cut_Start := (if Cut_Start = 0 then Path'First else Cut_Start + 1);
+ if Is_Root_Directory_Name (Path) then
+ return Path;
+ end if;
+
+ -- Handle trailing directory separators
+
+ if Cut_Start = Path'Last then
+ Cut_End := Path'Last - 1;
+ Cut_Start := Strings.Fixed.Index
+ (Path (Path'First .. Path'Last - 1),
+ Dir_Seps, Going => Strings.Backward);
+ end if;
- -- Cut_End point to the last simple name character
+ -- Cut_Start points to the first simple name character
- Cut_End := Path'Last;
+ Cut_Start := (if Cut_Start = 0 then Path'First else Cut_Start + 1);
Check_For_Standard_Dirs : declare
BN : constant String := Path (Cut_Start .. Cut_End);
@@ -1301,7 +1305,7 @@ package body Ada.Directories is
begin
if BN = "." or else BN = ".." then
- return "";
+ return BN;
elsif Has_Drive_Letter
and then BN'Length > 2
diff --git a/gcc/ada/libgnat/a-einuoc.adb b/gcc/ada/libgnat/a-einuoc.adb
index a949a16..77d6b8d 100644
--- a/gcc/ada/libgnat/a-einuoc.adb
+++ b/gcc/ada/libgnat/a-einuoc.adb
@@ -40,9 +40,5 @@ begin
-- The null exception is uniquely identified by the fact that the Id value
-- is null. No other exception occurrence can have a null Id.
- if X.Id = Null_Id then
- return True;
- else
- return False;
- end if;
+ return X.Id = Null_Id;
end Ada.Exceptions.Is_Null_Occurrence;
diff --git a/gcc/ada/libgnat/a-except.adb b/gcc/ada/libgnat/a-except.adb
index ebb76a7..8b0a31c 100644
--- a/gcc/ada/libgnat/a-except.adb
+++ b/gcc/ada/libgnat/a-except.adb
@@ -1624,6 +1624,7 @@ package body Ada.Exceptions is
Target.Machine_Occurrence := System.Null_Address;
Target.Msg_Length := Source.Msg_Length;
Target.Num_Tracebacks := Source.Num_Tracebacks;
+ Target.Exception_Raised := Source.Exception_Raised;
Target.Pid := Source.Pid;
Target.Msg (1 .. Target.Msg_Length) :=
diff --git a/gcc/ada/libgnat/a-except.ads b/gcc/ada/libgnat/a-except.ads
index 60ff5db..4f70769 100644
--- a/gcc/ada/libgnat/a-except.ads
+++ b/gcc/ada/libgnat/a-except.ads
@@ -33,14 +33,8 @@
-- --
------------------------------------------------------------------------------
--- This version of Ada.Exceptions fully supports Ada 95 and later language
--- versions. It is used in all situations except for the build of the
--- compiler and other basic tools. For these latter builds, we use an
--- Ada 95-only version.
-
--- The reason for this splitting off of a separate version is to support
--- older bootstrap compilers that do not support Ada 2005 features, and
--- Ada.Exceptions is part of the compiler sources.
+-- This is the default version of this package. We also have cert and zfp
+-- versions.
pragma Polling (Off);
-- We must turn polling off for this unit, because otherwise we get
@@ -284,7 +278,7 @@ private
-- Traceback array stored in exception occurrence
type Exception_Occurrence is record
- Id : Exception_Id;
+ Id : Exception_Id := Null_Id;
-- Exception_Identity for this exception occurrence
Machine_Occurrence : System.Address;
@@ -336,14 +330,6 @@ private
pragma Stream_Convert (Exception_Occurrence, String_To_EO, EO_To_String);
-- Functions for implementing Exception_Occurrence stream attributes
- Null_Occurrence : constant Exception_Occurrence := (
- Id => null,
- Machine_Occurrence => System.Null_Address,
- Msg_Length => 0,
- Msg => (others => ' '),
- Exception_Raised => False,
- Pid => 0,
- Num_Tracebacks => 0,
- Tracebacks => (others => TBE.Null_TB_Entry));
+ Null_Occurrence : constant Exception_Occurrence := (others => <>);
end Ada.Exceptions;
diff --git a/gcc/ada/libgnat/a-exexpr.adb b/gcc/ada/libgnat/a-exexpr.adb
index b1aa1c6..5e72fd6 100644
--- a/gcc/ada/libgnat/a-exexpr.adb
+++ b/gcc/ada/libgnat/a-exexpr.adb
@@ -197,15 +197,75 @@ package body Exception_Propagation is
-- whose machine occurrence is Mo. The message is empty, the backtrace
-- is empty too and the exception identity is Foreign_Exception.
- -- Hooks called when entering/leaving an exception handler for a given
- -- occurrence, aimed at handling the stack of active occurrences. The
- -- calls are generated by gigi in tree_transform/N_Exception_Handler.
+ -- Hooks called when entering/leaving an exception handler for a
+ -- given occurrence. The calls are generated by gigi in
+ -- Exception_Handler_to_gnu_gcc.
+
+ -- Begin_Handler_v1, called when entering an exception handler,
+ -- claims responsibility for the handler to release the
+ -- GCC_Exception occurrence. End_Handler_v1, called when
+ -- leaving the handler, releases the occurrence, unless the
+ -- occurrence is propagating further up, or the handler is
+ -- dynamically nested in the context of another handler that
+ -- claimed responsibility for releasing that occurrence.
+
+ -- Responsibility is claimed by changing the Cleanup field to
+ -- Claimed_Cleanup, which enables claimed exceptions to be
+ -- recognized, and avoids accidental releases even by foreign
+ -- handlers.
+
+ function Begin_Handler_v1
+ (GCC_Exception : not null GCC_Exception_Access)
+ return System.Address;
+ pragma Export (C, Begin_Handler_v1, "__gnat_begin_handler_v1");
+ -- Called when entering an exception handler. Claim
+ -- responsibility for releasing GCC_Exception, by setting the
+ -- cleanup/release function to Claimed_Cleanup, and return the
+ -- address of the previous cleanup/release function.
+
+ procedure End_Handler_v1
+ (GCC_Exception : not null GCC_Exception_Access;
+ Saved_Cleanup : System.Address;
+ Propagating_Exception : GCC_Exception_Access);
+ pragma Export (C, End_Handler_v1, "__gnat_end_handler_v1");
+ -- Called when leaving an exception handler. Restore the
+ -- Saved_Cleanup in the GCC_Exception occurrence, and then release
+ -- it, unless it remains claimed by an enclosing handler, or
+ -- GCC_Exception and Propagating_Exception are the same
+ -- occurrence. Propagating_Exception could be either an
+ -- occurrence (re)raised within the handler of GCC_Exception, when
+ -- we're executing as an exceptional cleanup, or null, if we're
+ -- completing the handler of GCC_Exception normally.
+
+ procedure Claimed_Cleanup
+ (Reason : Unwind_Reason_Code;
+ GCC_Exception : not null GCC_Exception_Access);
+ pragma Export (C, Claimed_Cleanup, "__gnat_claimed_cleanup");
+ -- A do-nothing placeholder installed as GCC_Exception.Cleanup
+ -- while handling GCC_Exception, to claim responsibility for
+ -- releasing it, and to stop it from being accidentally released.
+
+ -- The following are version 0 implementations of the version 1
+ -- hooks above. They remain in place for compatibility with the
+ -- output of compilers that still use version 0, such as those
+ -- used during bootstrap. They are interoperable with the v1
+ -- hooks, except that the older versions may malfunction when
+ -- handling foreign exceptions passed to Reraise_Occurrence.
procedure Begin_Handler (GCC_Exception : not null GCC_Exception_Access);
pragma Export (C, Begin_Handler, "__gnat_begin_handler");
+ -- Called when entering an exception handler translated by an old
+ -- compiler. It does nothing.
procedure End_Handler (GCC_Exception : GCC_Exception_Access);
pragma Export (C, End_Handler, "__gnat_end_handler");
+ -- Called when leaving an exception handler translated by an old
+ -- compiler. It releases GCC_Exception, unless it is null. It is
+ -- only ever null when the handler has a 'raise;' translated by a
+ -- v0-using compiler. The artificial handler variable passed to
+ -- End_Handler was set to null to tell End_Handler to refrain from
+ -- releasing the reraised exception. In v1 safer ways are used to
+ -- accomplish that.
--------------------------------------------------------------------
-- Accessors to Basic Components of a GNAT Exception Data Pointer --
@@ -352,6 +412,128 @@ package body Exception_Propagation is
end if;
end Setup_Current_Excep;
+ ----------------------
+ -- Begin_Handler_v1 --
+ ----------------------
+
+ function Begin_Handler_v1
+ (GCC_Exception : not null GCC_Exception_Access)
+ return System.Address is
+ Saved_Cleanup : constant System.Address := GCC_Exception.Cleanup;
+ begin
+ -- Claim responsibility for releasing this exception, and stop
+ -- others from releasing it.
+ GCC_Exception.Cleanup := Claimed_Cleanup'Address;
+ return Saved_Cleanup;
+ end Begin_Handler_v1;
+
+ --------------------
+ -- End_Handler_v1 --
+ --------------------
+
+ procedure End_Handler_v1
+ (GCC_Exception : not null GCC_Exception_Access;
+ Saved_Cleanup : System.Address;
+ Propagating_Exception : GCC_Exception_Access) is
+ begin
+ GCC_Exception.Cleanup := Saved_Cleanup;
+ -- Restore the Saved_Cleanup, so that it is either used to
+ -- release GCC_Exception below, or transferred to the next
+ -- handler of the Propagating_Exception occurrence. The
+ -- following test ensures that an occurrence is only released
+ -- once, even after reraises.
+ --
+ -- The idea is that the GCC_Exception is not to be released
+ -- unless it had an unclaimed Cleanup when the handler started
+ -- (see Begin_Handler_v1 above), but if we propagate across its
+ -- handler a reraise of the same exception, we transfer to the
+ -- Propagating_Exception the responsibility for running the
+ -- Saved_Cleanup when its handler completes.
+ --
+ -- This ownership transfer mechanism ensures safety, as in
+ -- single release and no dangling pointers, because there is no
+ -- way to hold on to the Machine_Occurrence of an
+ -- Exception_Occurrence: the only situations in which another
+ -- Exception_Occurrence gets the same Machine_Occurrence are
+ -- through Reraise_Occurrence, and plain reraise, and so we
+ -- have the following possibilities:
+ --
+ -- - Reraise_Occurrence is handled within the running handler,
+ -- and so when completing the dynamically nested handler, we
+ -- must NOT release the exception. A Claimed_Cleanup upon
+ -- entry of the nested handler, installed when entering the
+ -- enclosing handler, ensures the exception will not be
+ -- released by the nested handler, but rather by the enclosing
+ -- handler.
+ --
+ -- - Reraise_Occurrence/reraise escapes the running handler,
+ -- and we run as an exceptional cleanup for GCC_Exception. The
+ -- Saved_Cleanup was reinstalled, but since we're propagating
+ -- the same machine occurrence, we do not release it. Instead,
+ -- we transfer responsibility for releasing it to the eventual
+ -- handler of the propagating exception.
+ --
+ -- - An unrelated exception propagates through the running
+ -- handler. We restored GCC_Exception.Saved_Cleanup above.
+ -- Since we're propagating a different exception, we proceed to
+ -- release GCC_Exception, unless Saved_Cleanup was
+ -- Claimed_Cleanup, because then we know we're not in the
+ -- outermost handler for GCC_Exception.
+ --
+ -- - The handler completes normally, so it reinstalls the
+ -- Saved_Cleanup and runs it, unless it was Claimed_Cleanup.
+ -- If Saved_Cleanup is null, Unwind_DeleteException (currently)
+ -- has no effect, so we could skip it, but if it is ever
+ -- changed to do more in this case, we're ready for that,
+ -- calling it exactly once.
+ if Saved_Cleanup /= Claimed_Cleanup'Address
+ and then
+ Propagating_Exception /= GCC_Exception
+ then
+ declare
+ Current : constant EOA := Get_Current_Excep.all;
+ Cur_Occ : constant GCC_Exception_Access
+ := To_GCC_Exception (Current.Machine_Occurrence);
+ begin
+ -- If we are releasing the Machine_Occurrence of the current
+ -- exception, reset the access to it, so that it is no
+ -- longer accessible.
+ if Cur_Occ = GCC_Exception then
+ Current.Machine_Occurrence := System.Null_Address;
+ end if;
+ end;
+ Unwind_DeleteException (GCC_Exception);
+ end if;
+ end End_Handler_v1;
+
+ ---------------------
+ -- Claimed_Cleanup --
+ ---------------------
+
+ procedure Claimed_Cleanup
+ (Reason : Unwind_Reason_Code;
+ GCC_Exception : not null GCC_Exception_Access) is
+ pragma Unreferenced (Reason);
+ pragma Unreferenced (GCC_Exception);
+ begin
+ -- This procedure should never run. If it does, it's either a
+ -- version 0 handler or a foreign handler, attempting to
+ -- release an exception while a version 1 handler that claimed
+ -- responsibility for releasing the exception remains still
+ -- active. This placeholder stops GCC_Exception from being
+ -- released by them.
+
+ -- We could get away with just Null_Address instead, with
+ -- nearly the same effect, but with this placeholder we can
+ -- detect and report unexpected releases, and we can tell apart
+ -- a GCC_Exception without a Cleanup, from one with another
+ -- active handler, so as to still call Unwind_DeleteException
+ -- exactly once: currently, Unwind_DeleteException does nothing
+ -- when the Cleanup is null, but should it ever be changed to
+ -- do more, we'll still be safe.
+ null;
+ end Claimed_Cleanup;
+
-------------------
-- Begin_Handler --
-------------------
diff --git a/gcc/ada/libgnat/a-locale.ads b/gcc/ada/libgnat/a-locale.ads
index 43ba5bf..314001a 100644
--- a/gcc/ada/libgnat/a-locale.ads
+++ b/gcc/ada/libgnat/a-locale.ads
@@ -19,18 +19,34 @@ package Ada.Locales is
pragma Preelaborate (Locales);
pragma Remote_Types (Locales);
+ -- A locale identifies a geopolitical place or region and its associated
+ -- language, which can be used to determine other
+ -- internationalization-related characteristics. The active locale is the
+ -- locale associated with the partition of the current task.
+
type Language_Code is new String (1 .. 3)
with Dynamic_Predicate =>
(for all E of Language_Code => E in 'a' .. 'z');
+ -- Lower-case string representation of an ISO 639-3 alpha-3 code that
+ -- identifies a language.
type Country_Code is new String (1 .. 2)
with Dynamic_Predicate =>
(for all E of Country_Code => E in 'A' .. 'Z');
+ -- Upper-case string representation of an ISO 3166-1 alpha-2 code that
+ -- identifies a country.
Language_Unknown : constant Language_Code := "und";
Country_Unknown : constant Country_Code := "ZZ";
function Language return Language_Code;
+ -- Returns the code of the language associated with the active locale. If
+ -- the Language_Code associated with the active locale cannot be determined
+ -- from the environment, then Language returns Language_Unknown.
+
function Country return Country_Code;
+ -- Returns the code of the country associated with the active locale. If
+ -- the Country_Code associated with the active locale cannot be determined
+ -- from the environment, then Country returns Country_Unknown.
end Ada.Locales;
diff --git a/gcc/ada/libgnat/a-tifiio.adb b/gcc/ada/libgnat/a-tifiio.adb
index 1c817ea8..d048646 100644
--- a/gcc/ada/libgnat/a-tifiio.adb
+++ b/gcc/ada/libgnat/a-tifiio.adb
@@ -560,7 +560,7 @@ package body Ada.Text_IO.Fixed_IO is
E : Integer)
is
pragma Assert (E >= -Max_Digits);
- AA : constant Field := E + A;
+ AA : constant Field := Integer'Max (E + A, 0);
N : constant Natural := (AA + Max_Digits - 1) / Max_Digits + 1;
Q : array (0 .. N - 1) of Int64 := (others => 0);
diff --git a/gcc/ada/libgnat/g-comlin.adb b/gcc/ada/libgnat/g-comlin.adb
index 29100af..e3fac5b 100644
--- a/gcc/ada/libgnat/g-comlin.adb
+++ b/gcc/ada/libgnat/g-comlin.adb
@@ -753,7 +753,8 @@ package body GNAT.Command_Line is
Parser.Current_Index := End_Index + 1;
- raise Invalid_Switch;
+ raise Invalid_Switch with
+ "Unrecognized option '" & Full_Switch (Parser) & ''';
end if;
End_Index := Parser.Current_Index + Max_Length - 1;
@@ -883,7 +884,8 @@ package body GNAT.Command_Line is
Last => Arg'Last,
Extra => Parser.Switch_Character);
Parser.Current_Index := Arg'Last + 1;
- raise Invalid_Switch;
+ raise Invalid_Switch with
+ "Unrecognized option '" & Full_Switch (Parser) & ''';
end if;
end case;
@@ -3365,7 +3367,8 @@ package body GNAT.Command_Line is
(Config : Command_Line_Configuration;
Callback : Switch_Handler := null;
Parser : Opt_Parser := Command_Line_Parser;
- Concatenate : Boolean := True)
+ Concatenate : Boolean := True;
+ Quiet : Boolean := False)
is
Local_Config : Command_Line_Configuration := Config;
Getopt_Switches : String_Access;
@@ -3575,12 +3578,14 @@ package body GNAT.Command_Line is
-- Message inspired by "ls" on Unix
- Put_Line (Standard_Error,
- Base_Name (Ada.Command_Line.Command_Name)
- & ": unrecognized option '"
- & Full_Switch (Parser)
- & "'");
- Try_Help;
+ if not Quiet then
+ Put_Line (Standard_Error,
+ Base_Name (Ada.Command_Line.Command_Name)
+ & ": unrecognized option '"
+ & Full_Switch (Parser)
+ & "'");
+ Try_Help;
+ end if;
raise;
diff --git a/gcc/ada/libgnat/g-comlin.ads b/gcc/ada/libgnat/g-comlin.ads
index f1251b6..3708c37 100644
--- a/gcc/ada/libgnat/g-comlin.ads
+++ b/gcc/ada/libgnat/g-comlin.ads
@@ -738,7 +738,8 @@ package GNAT.Command_Line is
(Config : Command_Line_Configuration;
Callback : Switch_Handler := null;
Parser : Opt_Parser := Command_Line_Parser;
- Concatenate : Boolean := True);
+ Concatenate : Boolean := True;
+ Quiet : Boolean := False);
-- Similar to the standard Getopt function. For each switch found on the
-- command line, this calls Callback, if the switch is not handled
-- automatically.
@@ -756,6 +757,7 @@ package GNAT.Command_Line is
-- to display the help message and raises Exit_From_Command_Line.
-- If an invalid switch is specified on the command line, this procedure
-- will display an error message and raises Invalid_Switch again.
+ -- If the Quiet parameter is True then the error message is not displayed.
--
-- This function automatically expands switches:
--
diff --git a/gcc/ada/libgnat/g-sercom__mingw.adb b/gcc/ada/libgnat/g-sercom__mingw.adb
index c13e7b3..d5e2344 100644
--- a/gcc/ada/libgnat/g-sercom__mingw.adb
+++ b/gcc/ada/libgnat/g-sercom__mingw.adb
@@ -167,7 +167,7 @@ package body GNAT.Serial_Communications is
Raise_Error ("read error");
end if;
- Last := Last_Index (Buffer'First, size_t (Read_Last));
+ Last := Last_Index (Buffer'First, CRTL.size_t (Read_Last));
end Read;
---------
diff --git a/gcc/ada/libgnat/g-socket.adb b/gcc/ada/libgnat/g-socket.adb
index ceb2cb0..51817ea 100644
--- a/gcc/ada/libgnat/g-socket.adb
+++ b/gcc/ada/libgnat/g-socket.adb
@@ -1797,7 +1797,7 @@ package body GNAT.Sockets is
end if;
end loop;
- return Colons <= 8;
+ return Colons in 2 .. 8;
end Is_IPv6_Address;
---------------------
diff --git a/gcc/ada/libgnat/s-os_lib.adb b/gcc/ada/libgnat/s-os_lib.adb
index c3c1979..258cd64 100644
--- a/gcc/ada/libgnat/s-os_lib.adb
+++ b/gcc/ada/libgnat/s-os_lib.adb
@@ -2979,6 +2979,15 @@ package body System.OS_Lib is
end loop;
end Spawn_Internal;
+ ------------
+ -- To_Ada --
+ ------------
+
+ function To_Ada (Time : time_t) return OS_Time is
+ begin
+ return OS_Time (Time);
+ end To_Ada;
+
---------------------------
-- To_Path_String_Access --
---------------------------
@@ -3008,6 +3017,15 @@ package body System.OS_Lib is
return Return_Val;
end To_Path_String_Access;
+ ----------
+ -- To_C --
+ ----------
+
+ function To_C (Time : OS_Time) return time_t is
+ begin
+ return time_t (Time);
+ end To_C;
+
------------------
-- Wait_Process --
------------------
diff --git a/gcc/ada/libgnat/s-os_lib.ads b/gcc/ada/libgnat/s-os_lib.ads
index 3e8c21d..99406e9 100644
--- a/gcc/ada/libgnat/s-os_lib.ads
+++ b/gcc/ada/libgnat/s-os_lib.ads
@@ -164,6 +164,15 @@ package System.OS_Lib is
-- component parts to be interpreted in the local time zone, and returns
-- an OS_Time. Returns Invalid_Time if the creation fails.
+ subtype time_t is Long_Integer;
+ -- C time_t type of the time representation
+
+ function To_C (Time : OS_Time) return time_t;
+ -- Convert OS_Time to C time_t type
+
+ function To_Ada (Time : time_t) return OS_Time;
+ -- Convert C time_t type to OS_Time
+
----------------
-- File Stuff --
----------------
@@ -1107,6 +1116,8 @@ private
pragma Inline (">");
pragma Inline ("<=");
pragma Inline (">=");
+ pragma Inline (To_C);
+ pragma Inline (To_Ada);
type Process_Id is new Integer;
Invalid_Pid : constant Process_Id := -1;
diff --git a/gcc/ada/libgnat/s-win32.ads b/gcc/ada/libgnat/s-win32.ads
index d09c4b3..ab832cd 100644
--- a/gcc/ada/libgnat/s-win32.ads
+++ b/gcc/ada/libgnat/s-win32.ads
@@ -63,6 +63,7 @@ package System.Win32 is
type BYTE is new Interfaces.C.unsigned_char;
type LONG is new Interfaces.C.long;
type CHAR is new Interfaces.C.char;
+ type SIZE_T is new Interfaces.C.size_t;
type BOOL is new Interfaces.C.int;
for BOOL'Size use Interfaces.C.int'Size;
@@ -238,7 +239,7 @@ package System.Win32 is
dwDesiredAccess : DWORD;
dwFileOffsetHigh : DWORD;
dwFileOffsetLow : DWORD;
- dwNumberOfBytesToMap : DWORD) return System.Address;
+ dwNumberOfBytesToMap : SIZE_T) return System.Address;
pragma Import (Stdcall, MapViewOfFile, "MapViewOfFile");
function UnmapViewOfFile (lpBaseAddress : System.Address) return BOOL;
diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads
index 4d3e87e..3158899 100644
--- a/gcc/ada/opt.ads
+++ b/gcc/ada/opt.ads
@@ -501,7 +501,7 @@ package Opt is
type Distribution_Stub_Mode_Type is
-- GNAT
(No_Stubs,
- -- Normal mode, no generation/compilation of distribution stubs
+ -- Normal mode, no generation of distribution stubs
Generate_Receiver_Stub_Body,
-- The unit being compiled is the RCI body, and the compiler will
@@ -513,8 +513,8 @@ package Opt is
Distribution_Stub_Mode : Distribution_Stub_Mode_Type := No_Stubs;
-- GNAT
- -- This enumeration variable indicates the five states of distribution
- -- annex stub generation/compilation.
+ -- This enumeration variable indicates the three states of distribution
+ -- annex stub generation.
Do_Not_Execute : Boolean := False;
-- GNATMAKE
diff --git a/gcc/ada/par-prag.adb b/gcc/ada/par-prag.adb
index ea4b06b..bed22e1 100644
--- a/gcc/ada/par-prag.adb
+++ b/gcc/ada/par-prag.adb
@@ -1415,9 +1415,11 @@ begin
| Pragma_Main
| Pragma_Main_Storage
| Pragma_Max_Entry_Queue_Depth
+ | Pragma_Max_Entry_Queue_Length
| Pragma_Max_Queue_Length
| Pragma_Memory_Size
| Pragma_No_Body
+ | Pragma_No_Caching
| Pragma_No_Component_Reordering
| Pragma_No_Elaboration_Code_All
| Pragma_No_Heap_Finalization
diff --git a/gcc/ada/repinfo.adb b/gcc/ada/repinfo.adb
index 77b5c21..6f531b2 100644
--- a/gcc/ada/repinfo.adb
+++ b/gcc/ada/repinfo.adb
@@ -479,6 +479,7 @@ package body Repinfo is
if Present (Ent)
and then Nkind (Declaration_Node (Ent)) not in N_Renaming_Declaration
+ and then not Is_Ignored_Ghost_Entity (Ent)
then
-- If entity is a subprogram and we are listing mechanisms,
-- then we need to list mechanisms for this entity. We skip this
@@ -1816,8 +1817,15 @@ package body Repinfo is
begin
-- For record types, list Bit_Order if not default, or if SSO is shown
+ -- Also, when -gnatR4 is in effect always list bit order and scalar
+ -- storage order explicitly, so that you don't need to know the native
+ -- endianness of the target for which the output was produced in order
+ -- to interpret it.
+
if Is_Record_Type (Ent)
- and then (List_SSO or else Reverse_Bit_Order (Ent))
+ and then (List_SSO
+ or else Reverse_Bit_Order (Ent)
+ or else List_Representation_Info = 4)
then
List_Attr ("Bit_Order", Reverse_Bit_Order (Ent));
end if;
@@ -1825,7 +1833,7 @@ package body Repinfo is
-- List SSO if required. If not, then storage is supposed to be in
-- native order.
- if List_SSO then
+ if List_SSO or else List_Representation_Info = 4 then
List_Attr ("Scalar_Storage_Order", Reverse_Storage_Order (Ent));
else
pragma Assert (not Reverse_Storage_Order (Ent));
diff --git a/gcc/ada/sem.adb b/gcc/ada/sem.adb
index 2f8f6a4..2e99531 100644
--- a/gcc/ada/sem.adb
+++ b/gcc/ada/sem.adb
@@ -1395,6 +1395,7 @@ package body Sem is
Restore_Scope_Stack (List);
Restore_Ghost_Region (Saved_GM, Saved_IGR);
Style_Max_Line_Length := Saved_ML;
+ Style_Check_Max_Line_Length := Style_Max_Line_Length /= 0;
end Do_Analyze;
-- Local variables
@@ -1728,16 +1729,14 @@ package body Sem is
MCU : constant Node_Id := Unit (Main_CU);
begin
- CL := First (Context_Items (CU));
-
-- Problem does not arise with main subprograms
- if
- not Nkind_In (MCU, N_Package_Body, N_Package_Declaration)
- then
+ if not Nkind_In (MCU, N_Package_Body, N_Package_Declaration) then
return False;
end if;
+ CL := First (Context_Items (CU));
+
while Present (CL) loop
if Nkind (CL) = N_With_Clause
and then Library_Unit (CL) = Main_CU
diff --git a/gcc/ada/sem.ads b/gcc/ada/sem.ads
index 9fbe86a..0c3e6c2 100644
--- a/gcc/ada/sem.ads
+++ b/gcc/ada/sem.ads
@@ -275,7 +275,6 @@ package Sem is
-- flag is False to disable any code expansion (see package Expander). Only
-- the generic processing can modify the status of this flag, any other
-- client should regard it as read-only.
- -- Probably should be called Inside_A_Generic_Template ???
Inside_Freezing_Actions : Nat := 0;
-- Flag indicating whether we are within a call to Expand_N_Freeze_Actions.
diff --git a/gcc/ada/sem_aux.adb b/gcc/ada/sem_aux.adb
index 71a3873..e5bd68a 100644
--- a/gcc/ada/sem_aux.adb
+++ b/gcc/ada/sem_aux.adb
@@ -569,6 +569,12 @@ package body Sem_Aux is
elsif Entity (N) = E then
return N;
end if;
+
+ -- A Ghost-related aspect, if disabled, may have been replaced by a
+ -- null statement.
+
+ elsif Nkind (N) = N_Null_Statement then
+ N := Original_Node (N);
end if;
Next_Rep_Item (N);
diff --git a/gcc/ada/sem_ch12.adb b/gcc/ada/sem_ch12.adb
index 3aa4975..17de328 100644
--- a/gcc/ada/sem_ch12.adb
+++ b/gcc/ada/sem_ch12.adb
@@ -240,6 +240,10 @@ package body Sem_Ch12 is
-- circularity is detected, and used to abandon compilation after the
-- messages have been posted.
+ Circularity_Detected : Boolean := False;
+ -- It should really be reset upon encountering a new main unit, but in
+ -- practice we do not use multiple main units so this is not critical.
+
-----------------------------------------
-- Implementation of Generic Contracts --
-----------------------------------------
@@ -352,10 +356,6 @@ package body Sem_Ch12 is
-- Instantiate_Subprogram_Contract
- Circularity_Detected : Boolean := False;
- -- This should really be reset on encountering a new main unit, but in
- -- practice we are not using multiple main units so it is not critical.
-
--------------------------------------------------
-- Formal packages and partial parameterization --
--------------------------------------------------
@@ -380,23 +380,23 @@ package body Sem_Ch12 is
-- the generic package, and a set of declarations that map the actuals
-- into local renamings, just as we do for bona fide instantiations. For
-- defaulted parameters and formals with a box, we copy directly the
- -- declarations of the formal into this local package. The result is a
- -- a package whose visible declarations may include generic formals. This
+ -- declarations of the formals into this local package. The result is a
+ -- package whose visible declarations may include generic formals. This
-- package is only used for type checking and visibility analysis, and
- -- never reaches the back-end, so it can freely violate the placement
+ -- never reaches the back end, so it can freely violate the placement
-- rules for generic formal declarations.
-- The list of declarations (renamings and copies of formals) is built
-- by Analyze_Associations, just as for regular instantiations.
-- At the point of instantiation, conformance checking must be applied only
- -- to those parameters that were specified in the formal. We perform this
+ -- to those parameters that were specified in the formals. We perform this
-- checking by creating another internal instantiation, this one including
-- only the renamings and the formals (the rest of the package spec is not
-- relevant to conformance checking). We can then traverse two lists: the
-- list of actuals in the instance that corresponds to the formal package,
-- and the list of actuals produced for this bogus instantiation. We apply
- -- the conformance rules to those actuals that are not defaulted (i.e.
+ -- the conformance rules to those actuals that are not defaulted, i.e.
-- which still appear as generic formals.
-- When we compile an instance body we must make the right parameters
@@ -1025,26 +1025,6 @@ package body Sem_Ch12 is
raise Instantiation_Error;
end Abandon_Instantiation;
- --------------------------------
- -- Add_Pending_Instantiation --
- --------------------------------
-
- procedure Add_Pending_Instantiation (Inst : Node_Id; Act_Decl : Node_Id) is
- begin
- -- Capture the body of the generic instantiation along with its context
- -- for later processing by Instantiate_Bodies.
-
- Pending_Instantiations.Append
- ((Act_Decl => Act_Decl,
- Config_Switches => Save_Config_Switches,
- Current_Sem_Unit => Current_Sem_Unit,
- Expander_Status => Expander_Active,
- Inst_Node => Inst,
- Local_Suppress_Stack_Top => Local_Suppress_Stack_Top,
- Scope_Suppress => Scope_Suppress,
- Warnings => Save_Warnings));
- end Add_Pending_Instantiation;
-
----------------------------------
-- Adjust_Inherited_Pragma_Sloc --
----------------------------------
@@ -3865,27 +3845,21 @@ package body Sem_Ch12 is
procedure Analyze_Package_Instantiation (N : Node_Id) is
Has_Inline_Always : Boolean := False;
-
- procedure Delay_Descriptors (E : Entity_Id);
- -- Delay generation of subprogram descriptors for given entity
+ -- Set if the generic unit contains any subprograms with Inline_Always.
+ -- Only relevant when back-end inlining is not enabled.
function Might_Inline_Subp (Gen_Unit : Entity_Id) return Boolean;
- -- If inlining is active and the generic contains inlined subprograms,
- -- we instantiate the body. This may cause superfluous instantiations,
- -- but it is simpler than detecting the need for the body at the point
- -- of inlining, when the context of the instance is not available.
-
- -----------------------
- -- Delay_Descriptors --
- -----------------------
-
- procedure Delay_Descriptors (E : Entity_Id) is
- begin
- if not Delay_Subprogram_Descriptors (E) then
- Set_Delay_Subprogram_Descriptors (E);
- Pending_Descriptor.Append (E);
- end if;
- end Delay_Descriptors;
+ -- Return True if inlining is active and Gen_Unit contains inlined
+ -- subprograms. In this case, we may either instantiate the body when
+ -- front-end inlining is enabled, or add a pending instantiation when
+ -- back-end inlining is enabled. In the former case, this may cause
+ -- superfluous instantiations, but in either case we need to perform
+ -- the instantiation of the body in the context of the instance and
+ -- not in that of the point of inlining.
+
+ function Needs_Body_Instantiated (Gen_Unit : Entity_Id) return Boolean;
+ -- Return True if Gen_Unit needs to have its body instantiated in the
+ -- context of N. This in particular excludes generic contexts.
-----------------------
-- Might_Inline_Subp --
@@ -3895,10 +3869,14 @@ package body Sem_Ch12 is
E : Entity_Id;
begin
- if not Inline_Processing_Required then
- return False;
+ if Inline_Processing_Required then
+ -- No need to recompute the answer if we know it is positive
+ -- and back-end inlining is enabled.
+
+ if Is_Inlined (Gen_Unit) and then Back_End_Inlining then
+ return True;
+ end if;
- else
E := First_Entity (Gen_Unit);
while Present (E) loop
if Is_Subprogram (E) and then Is_Inlined (E) then
@@ -3908,6 +3886,7 @@ package body Sem_Ch12 is
Has_Inline_Always := True;
end if;
+ Set_Is_Inlined (Gen_Unit);
return True;
end if;
@@ -3918,6 +3897,48 @@ package body Sem_Ch12 is
return False;
end Might_Inline_Subp;
+ -------------------------------
+ -- Needs_Body_Instantiated --
+ -------------------------------
+
+ function Needs_Body_Instantiated (Gen_Unit : Entity_Id) return Boolean is
+ begin
+ -- No need to instantiate bodies in generic units
+
+ if Is_Generic_Unit (Cunit_Entity (Main_Unit)) then
+ return False;
+ end if;
+
+ -- If the instantiation is in the main unit, then the body is needed
+
+ if Is_In_Main_Unit (N) then
+ return True;
+ end if;
+
+ -- If not, then again no need to instantiate bodies in generic units
+
+ if Is_Generic_Unit (Cunit_Entity (Get_Code_Unit (N))) then
+ return False;
+ end if;
+
+ -- Here we have a special handling for back-end inlining: if inline
+ -- processing is required, then we unconditionally want to have the
+ -- body instantiated. The reason is that Might_Inline_Subp does not
+ -- catch all the cases (as it does not recurse into nested packages)
+ -- so this avoids the need to patch things up afterwards. Moreover,
+ -- these instantiations are only performed on demand when back-end
+ -- inlining is enabled, so this causes very little extra work.
+
+ if Inline_Processing_Required and then Back_End_Inlining then
+ return True;
+ end if;
+
+ -- We want to have the bodies instantiated in non-main units if
+ -- they might contribute inlined subprograms.
+
+ return Might_Inline_Subp (Gen_Unit);
+ end Needs_Body_Instantiated;
+
-- Local declarations
Gen_Id : constant Node_Id := Name (N);
@@ -4281,12 +4302,11 @@ package body Sem_Ch12 is
end if;
end if;
- -- Save the instantiation node, for subsequent instantiation of the
- -- body, if there is one and we are generating code for the current
- -- unit. Mark unit as having a body (avoids premature error message).
+ -- Save the instantiation node for a subsequent instantiation of the
+ -- body if there is one and it needs to be instantiated here.
- -- We instantiate the body if we are generating code, if we are
- -- generating cross-reference information, or if we are building
+ -- We instantiate the body only if we are generating code, or if we
+ -- are generating cross-reference information, or if we are building
-- trees for ASIS use or GNATprove use.
declare
@@ -4379,14 +4399,10 @@ package body Sem_Ch12 is
(Unit_Requires_Body (Gen_Unit)
or else Enclosing_Body_Present
or else Present (Corresponding_Body (Gen_Decl)))
- and then (Is_In_Main_Unit (N)
- or else Might_Inline_Subp (Gen_Unit))
+ and then Needs_Body_Instantiated (Gen_Unit)
and then not Is_Actual_Pack
and then not Inline_Now
and then (Operating_Mode = Generate_Code
-
- -- Need comment for this check ???
-
or else (Operating_Mode = Check_Semantics
and then (ASIS_Mode or GNATprove_Mode)));
@@ -4394,9 +4410,9 @@ package body Sem_Ch12 is
-- marked with Inline_Always, do not instantiate body when within
-- a generic context.
- if ((Front_End_Inlining or else Has_Inline_Always)
- and then not Expander_Active)
- or else Is_Generic_Unit (Cunit_Entity (Main_Unit))
+ if not Back_End_Inlining
+ and then (Front_End_Inlining or else Has_Inline_Always)
+ and then not Expander_Active
then
Needs_Body := False;
end if;
@@ -4461,17 +4477,6 @@ package body Sem_Ch12 is
end if;
if Needs_Body then
-
- -- Here is a defence against a ludicrous number of instantiations
- -- caused by a circular set of instantiation attempts.
-
- if Pending_Instantiations.Last > Maximum_Instantiations then
- Error_Msg_Uint_1 := UI_From_Int (Maximum_Instantiations);
- Error_Msg_N ("too many instantiations, exceeds max of^", N);
- Error_Msg_N ("\limit can be changed using -gnateinn switch", N);
- raise Unrecoverable_Error;
- end if;
-
-- Indicate that the enclosing scopes contain an instantiation,
-- and that cleanup actions should be delayed until after the
-- instance body is expanded.
@@ -4489,10 +4494,10 @@ package body Sem_Ch12 is
if Ekind (Enclosing_Master) = E_Package then
if Is_Compilation_Unit (Enclosing_Master) then
if In_Package_Body (Enclosing_Master) then
- Delay_Descriptors
+ Set_Delay_Subprogram_Descriptors
(Body_Entity (Enclosing_Master));
else
- Delay_Descriptors
+ Set_Delay_Subprogram_Descriptors
(Enclosing_Master);
end if;
@@ -4532,7 +4537,7 @@ package body Sem_Ch12 is
end loop;
if Is_Subprogram (Enclosing_Master) then
- Delay_Descriptors (Enclosing_Master);
+ Set_Delay_Subprogram_Descriptors (Enclosing_Master);
elsif Is_Task_Type (Enclosing_Master) then
declare
@@ -4541,7 +4546,7 @@ package body Sem_Ch12 is
(Enclosing_Master);
begin
if Present (TBP) then
- Delay_Descriptors (TBP);
+ Set_Delay_Subprogram_Descriptors (TBP);
Set_Delay_Cleanups (TBP);
end if;
end;
@@ -4669,11 +4674,10 @@ package body Sem_Ch12 is
-- The instantiation results in a guaranteed ABE
if Is_Known_Guaranteed_ABE (N) and then Needs_Body then
-
-- Do not instantiate the corresponding body because gigi cannot
-- handle certain types of premature instantiations.
- Pending_Instantiations.Decrement_Last;
+ Remove_Dead_Instance (N);
-- Create completing bodies for all subprogram declarations since
-- their real bodies will not be instantiated.
@@ -5285,10 +5289,6 @@ package body Sem_Ch12 is
Analyze (Pack_Decl);
Check_Formal_Packages (Pack_Id);
- Set_Is_Generic_Instance (Pack_Id, False);
-
- -- Why do we clear Is_Generic_Instance??? We set it 20 lines
- -- above???
-- Body of the enclosing package is supplied when instantiating the
-- subprogram body, after semantic analysis is completed.
@@ -6825,7 +6825,12 @@ package body Sem_Ch12 is
Check_Private_View (Subtype_Indication (Parent (E)));
end if;
- Set_Is_Generic_Actual_Type (E, True);
+ Set_Is_Generic_Actual_Type (E);
+
+ if Is_Private_Type (E) and then Present (Full_View (E)) then
+ Set_Is_Generic_Actual_Type (Full_View (E));
+ end if;
+
Set_Is_Hidden (E, False);
Set_Is_Potentially_Use_Visible (E, In_Use (Instance));
@@ -8944,10 +8949,7 @@ package body Sem_Ch12 is
Decl := Unit_Declaration_Node (Corresponding_Body (Decl));
end if;
- if Nkind_In (Original_Node (Decl), N_Function_Instantiation,
- N_Package_Instantiation,
- N_Procedure_Instantiation)
- then
+ if Nkind (Original_Node (Decl)) in N_Generic_Instantiation then
return Original_Node (Decl);
else
return Unit (Parent (Decl));
@@ -11601,25 +11603,7 @@ package body Sem_Ch12 is
-- indicate that the body instance is to be delayed.
Install_Body (Act_Body, Inst_Node, Gen_Body, Gen_Decl);
-
- -- Now analyze the body. We turn off all checks if this is an
- -- internal unit, since there is no reason to have checks on for
- -- any predefined run-time library code. All such code is designed
- -- to be compiled with checks off.
-
- -- Note that we do NOT apply this criterion to children of GNAT
- -- The latter units must suppress checks explicitly if needed.
-
- -- We also do not suppress checks in CodePeer mode where we are
- -- interested in finding possible runtime errors.
-
- if not CodePeer_Mode
- and then In_Predefined_Unit (Gen_Decl)
- then
- Analyze (Act_Body, Suppress => All_Checks);
- else
- Analyze (Act_Body);
- end if;
+ Analyze (Act_Body);
end if;
Inherit_Context (Gen_Body, Inst_Node);
@@ -13711,15 +13695,26 @@ package body Sem_Ch12 is
and then
Nkind (Original_Node (True_Parent)) = N_Package_Instantiation
then
- -- Parent is a compilation unit that is an instantiation.
- -- Instantiation node has been replaced with package decl.
+ -- Parent is a compilation unit that is an instantiation, and
+ -- instantiation node has been replaced with package decl.
Inst_Node := Original_Node (True_Parent);
exit;
elsif Nkind (True_Parent) = N_Package_Declaration
- and then Present (Generic_Parent (Specification (True_Parent)))
+ and then Nkind (Parent (True_Parent)) = N_Compilation_Unit
+ and then
+ Nkind (Unit (Parent (True_Parent))) = N_Package_Instantiation
+ then
+ -- Parent is a compilation unit that is an instantiation, but
+ -- instantiation node has not been replaced with package decl.
+
+ Inst_Node := Unit (Parent (True_Parent));
+ exit;
+
+ elsif Nkind (True_Parent) = N_Package_Declaration
and then Nkind (Parent (True_Parent)) /= N_Compilation_Unit
+ and then Present (Generic_Parent (Specification (True_Parent)))
then
-- Parent is an instantiation within another specification.
-- Declaration for instance has been inserted before original
@@ -14642,6 +14637,10 @@ package body Sem_Ch12 is
null;
else
Set_Is_Generic_Actual_Type (E, False);
+
+ if Is_Private_Type (E) and then Present (Full_View (E)) then
+ Set_Is_Generic_Actual_Type (Full_View (E), False);
+ end if;
end if;
-- An unusual case of aliasing: the actual may also be directly
diff --git a/gcc/ada/sem_ch12.ads b/gcc/ada/sem_ch12.ads
index 9c71368..f0b72f4 100644
--- a/gcc/ada/sem_ch12.ads
+++ b/gcc/ada/sem_ch12.ads
@@ -37,10 +37,6 @@ package Sem_Ch12 is
procedure Analyze_Formal_Subprogram_Declaration (N : Node_Id);
procedure Analyze_Formal_Package_Declaration (N : Node_Id);
- procedure Add_Pending_Instantiation (Inst : Node_Id; Act_Decl : Node_Id);
- -- Add an entry in the table of instance bodies that must be analyzed
- -- when inlining requires its body or the body of a nested instance.
-
function Build_Function_Wrapper
(Formal_Subp : Entity_Id;
Actual_Subp : Entity_Id) return Node_Id;
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index bf80200..a3a7be7 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -2824,7 +2824,7 @@ package body Sem_Ch13 is
Insert_Pragma (Aitem);
goto Continue;
- -- Aspect Effecitve_Reads is never delayed because it is
+ -- Aspect Effective_Reads is never delayed because it is
-- equivalent to a source pragma which appears after the
-- related object declaration.
@@ -3014,6 +3014,19 @@ package body Sem_Ch13 is
Insert_Pragma (Aitem);
goto Continue;
+ -- Max_Entry_Queue_Length
+
+ when Aspect_Max_Entry_Queue_Length =>
+ Make_Aitem_Pragma
+ (Pragma_Argument_Associations => New_List (
+ Make_Pragma_Argument_Association (Loc,
+ Expression => Relocate_Node (Expr))),
+ Pragma_Name => Name_Max_Entry_Queue_Length);
+
+ Decorate (Aspect, Aitem);
+ Insert_Pragma (Aitem);
+ goto Continue;
+
-- Max_Queue_Length
when Aspect_Max_Queue_Length =>
@@ -3027,6 +3040,21 @@ package body Sem_Ch13 is
Insert_Pragma (Aitem);
goto Continue;
+ -- Aspect No_Caching is never delayed because it is equivalent
+ -- to a source pragma which appears after the related object
+ -- declaration.
+
+ when Aspect_No_Caching =>
+ Make_Aitem_Pragma
+ (Pragma_Argument_Associations => New_List (
+ Make_Pragma_Argument_Association (Loc,
+ Expression => Relocate_Node (Expr))),
+ Pragma_Name => Name_No_Caching);
+
+ Decorate (Aspect, Aitem);
+ Insert_Pragma (Aitem);
+ goto Continue;
+
-- Obsolescent
when Aspect_Obsolescent => declare
@@ -4625,10 +4653,12 @@ package body Sem_Ch13 is
end if;
if not Is_Overloaded (Expr) then
- if not Check_Primitive_Function (Entity (Expr)) then
+ if Entity (Expr) /= Any_Id
+ and then not Check_Primitive_Function (Entity (Expr))
+ then
Error_Msg_NE
("aspect Indexing requires a function that applies to type&",
- Entity (Expr), Ent);
+ Entity (Expr), Ent);
end if;
-- Flag the default_iterator as well as the denoted function.
@@ -9636,7 +9666,9 @@ package body Sem_Ch13 is
| Aspect_Initial_Condition
| Aspect_Initializes
| Aspect_Max_Entry_Queue_Depth
+ | Aspect_Max_Entry_Queue_Length
| Aspect_Max_Queue_Length
+ | Aspect_No_Caching
| Aspect_Obsolescent
| Aspect_Part_Of
| Aspect_Post
@@ -10090,6 +10122,14 @@ package body Sem_Ch13 is
-- issued, since the message was already given. Comp is also set to
-- Empty if the current "component clause" is in fact a pragma.
+ procedure Record_Hole_Check
+ (Rectype : Entity_Id; After_Last : out Uint; Warn : Boolean);
+ -- Checks for gaps in the given Rectype. Compute After_Last, the bit
+ -- number after the last component. Warn is True on the initial call,
+ -- and warnings are given for gaps. For a type extension, this is called
+ -- recursively to compute After_Last for the parent type; in this case
+ -- Warn is False and the warnings are suppressed.
+
-----------------------------
-- Check_Component_Overlap --
-----------------------------
@@ -10201,6 +10241,225 @@ package body Sem_Ch13 is
end if;
end Find_Component;
+ -----------------------
+ -- Record_Hole_Check --
+ -----------------------
+
+ procedure Record_Hole_Check
+ (Rectype : Entity_Id; After_Last : out Uint; Warn : Boolean)
+ is
+ Decl : constant Node_Id := Declaration_Node (Base_Type (Rectype));
+ -- Full declaration of record type
+
+ procedure Check_Component_List
+ (DS : List_Id;
+ CL : Node_Id;
+ Sbit : Uint;
+ Abit : out Uint);
+ -- Check component list CL for holes. DS is a list of discriminant
+ -- specifications to be included in the consideration of components.
+ -- Sbit is the starting bit, which is zero if there are no preceding
+ -- components (before a variant part, or a parent type, or a tag
+ -- field). If there are preceding components, Sbit is the bit just
+ -- after the last such component. Abit is set to the bit just after
+ -- the last component of DS and CL.
+
+ --------------------------
+ -- Check_Component_List --
+ --------------------------
+
+ procedure Check_Component_List
+ (DS : List_Id;
+ CL : Node_Id;
+ Sbit : Uint;
+ Abit : out Uint)
+ is
+ Compl : Integer;
+
+ begin
+ Compl := Integer (List_Length (Component_Items (CL)));
+
+ if DS /= No_List then
+ Compl := Compl + Integer (List_Length (DS));
+ end if;
+
+ declare
+ Comps : array (Natural range 0 .. Compl) of Entity_Id;
+ -- Gather components (zero entry is for sort routine)
+
+ Ncomps : Natural := 0;
+ -- Number of entries stored in Comps (starting at Comps (1))
+
+ Citem : Node_Id;
+ -- One component item or discriminant specification
+
+ Nbit : Uint;
+ -- Starting bit for next component
+
+ CEnt : Entity_Id;
+ -- Component entity
+
+ Variant : Node_Id;
+ -- One variant
+
+ function Lt (Op1, Op2 : Natural) return Boolean;
+ -- Compare routine for Sort
+
+ procedure Move (From : Natural; To : Natural);
+ -- Move routine for Sort
+
+ package Sorting is new GNAT.Heap_Sort_G (Move, Lt);
+
+ --------
+ -- Lt --
+ --------
+
+ function Lt (Op1, Op2 : Natural) return Boolean is
+ begin
+ return Component_Bit_Offset (Comps (Op1))
+ < Component_Bit_Offset (Comps (Op2));
+ end Lt;
+
+ ----------
+ -- Move --
+ ----------
+
+ procedure Move (From : Natural; To : Natural) is
+ begin
+ Comps (To) := Comps (From);
+ end Move;
+
+ begin
+ -- Gather discriminants into Comp
+
+ if DS /= No_List then
+ Citem := First (DS);
+ while Present (Citem) loop
+ if Nkind (Citem) = N_Discriminant_Specification then
+ declare
+ Ent : constant Entity_Id :=
+ Defining_Identifier (Citem);
+ begin
+ if Ekind (Ent) = E_Discriminant then
+ Ncomps := Ncomps + 1;
+ Comps (Ncomps) := Ent;
+ end if;
+ end;
+ end if;
+
+ Next (Citem);
+ end loop;
+ end if;
+
+ -- Gather component entities into Comp
+
+ Citem := First (Component_Items (CL));
+ while Present (Citem) loop
+ if Nkind (Citem) = N_Component_Declaration then
+ Ncomps := Ncomps + 1;
+ Comps (Ncomps) := Defining_Identifier (Citem);
+ end if;
+
+ Next (Citem);
+ end loop;
+
+ -- Now sort the component entities based on the first bit.
+ -- Note we already know there are no overlapping components.
+
+ Sorting.Sort (Ncomps);
+
+ -- Loop through entries checking for holes
+
+ Nbit := Sbit;
+ for J in 1 .. Ncomps loop
+ CEnt := Comps (J);
+
+ declare
+ CBO : constant Uint := Component_Bit_Offset (CEnt);
+
+ begin
+ -- Skip components with unknown offsets
+
+ if CBO /= No_Uint and then CBO >= 0 then
+ Error_Msg_Uint_1 := CBO - Nbit;
+
+ if Warn and then Error_Msg_Uint_1 > 0 then
+ Error_Msg_NE
+ ("?H?^-bit gap before component&",
+ Component_Name (Component_Clause (CEnt)),
+ CEnt);
+ end if;
+
+ Nbit := CBO + Esize (CEnt);
+ end if;
+ end;
+ end loop;
+
+ -- Set Abit to just after the last nonvariant component
+
+ Abit := Nbit;
+
+ -- Process variant parts recursively if present. Set Abit to
+ -- the maximum for all variant parts.
+
+ if Present (Variant_Part (CL)) then
+ declare
+ Var_Start : constant Uint := Nbit;
+ begin
+ Variant := First (Variants (Variant_Part (CL)));
+ while Present (Variant) loop
+ Check_Component_List
+ (No_List, Component_List (Variant), Var_Start, Nbit);
+ Next (Variant);
+ if Nbit > Abit then
+ Abit := Nbit;
+ end if;
+ end loop;
+ end;
+ end if;
+ end;
+ end Check_Component_List;
+
+ Sbit : Uint;
+ -- Starting bit for call to Check_Component_List. Zero for an
+ -- untagged type. The size of the Tag for a nonderived tagged
+ -- type. Parent size for a type extension.
+
+ Record_Definition : Node_Id;
+ -- Record_Definition containing Component_List to pass to
+ -- Check_Component_List.
+
+ -- Start of processing for Record_Hole_Check
+
+ begin
+ if Is_Tagged_Type (Rectype) then
+ Sbit := UI_From_Int (System_Address_Size);
+ else
+ Sbit := Uint_0;
+ end if;
+
+ if Nkind (Decl) = N_Full_Type_Declaration then
+ Record_Definition := Type_Definition (Decl);
+
+ -- If we have a record extension, set Sbit to point after the last
+ -- component of the parent type, by calling Record_Hole_Check
+ -- recursively.
+
+ if Nkind (Record_Definition) = N_Derived_Type_Definition then
+ Record_Definition := Record_Extension_Part (Record_Definition);
+ Record_Hole_Check (Underlying_Type (Parent_Subtype (Rectype)),
+ After_Last => Sbit, Warn => False);
+ end if;
+
+ if Nkind (Record_Definition) = N_Record_Definition then
+ Check_Component_List
+ (Discriminant_Specifications (Decl),
+ Component_List (Record_Definition),
+ Sbit, After_Last);
+ end if;
+ end if;
+ end Record_Hole_Check;
+
-- Start of processing for Check_Record_Representation_Clause
begin
@@ -10557,192 +10816,16 @@ package body Sem_Ch13 is
end Overlap_Check2;
end if;
- -- The following circuit deals with warning on record holes (gaps). We
- -- skip this check if overlap was detected, since it makes sense for the
- -- programmer to fix this illegality before worrying about warnings.
-
- if not Overlap_Detected and Warn_On_Record_Holes then
- Record_Hole_Check : declare
- Decl : constant Node_Id := Declaration_Node (Base_Type (Rectype));
- -- Full declaration of record type
-
- procedure Check_Component_List
- (CL : Node_Id;
- Sbit : Uint;
- DS : List_Id);
- -- Check component list CL for holes. The starting bit should be
- -- Sbit. which is zero for the main record component list and set
- -- appropriately for recursive calls for variants. DS is set to
- -- a list of discriminant specifications to be included in the
- -- consideration of components. It is No_List if none to consider.
-
- --------------------------
- -- Check_Component_List --
- --------------------------
-
- procedure Check_Component_List
- (CL : Node_Id;
- Sbit : Uint;
- DS : List_Id)
- is
- Compl : Integer;
-
- begin
- Compl := Integer (List_Length (Component_Items (CL)));
-
- if DS /= No_List then
- Compl := Compl + Integer (List_Length (DS));
- end if;
-
- declare
- Comps : array (Natural range 0 .. Compl) of Entity_Id;
- -- Gather components (zero entry is for sort routine)
-
- Ncomps : Natural := 0;
- -- Number of entries stored in Comps (starting at Comps (1))
-
- Citem : Node_Id;
- -- One component item or discriminant specification
-
- Nbit : Uint;
- -- Starting bit for next component
-
- CEnt : Entity_Id;
- -- Component entity
-
- Variant : Node_Id;
- -- One variant
-
- function Lt (Op1, Op2 : Natural) return Boolean;
- -- Compare routine for Sort
-
- procedure Move (From : Natural; To : Natural);
- -- Move routine for Sort
-
- package Sorting is new GNAT.Heap_Sort_G (Move, Lt);
-
- --------
- -- Lt --
- --------
-
- function Lt (Op1, Op2 : Natural) return Boolean is
- begin
- return Component_Bit_Offset (Comps (Op1))
- <
- Component_Bit_Offset (Comps (Op2));
- end Lt;
-
- ----------
- -- Move --
- ----------
-
- procedure Move (From : Natural; To : Natural) is
- begin
- Comps (To) := Comps (From);
- end Move;
-
- begin
- -- Gather discriminants into Comp
-
- if DS /= No_List then
- Citem := First (DS);
- while Present (Citem) loop
- if Nkind (Citem) = N_Discriminant_Specification then
- declare
- Ent : constant Entity_Id :=
- Defining_Identifier (Citem);
- begin
- if Ekind (Ent) = E_Discriminant then
- Ncomps := Ncomps + 1;
- Comps (Ncomps) := Ent;
- end if;
- end;
- end if;
-
- Next (Citem);
- end loop;
- end if;
-
- -- Gather component entities into Comp
-
- Citem := First (Component_Items (CL));
- while Present (Citem) loop
- if Nkind (Citem) = N_Component_Declaration then
- Ncomps := Ncomps + 1;
- Comps (Ncomps) := Defining_Identifier (Citem);
- end if;
-
- Next (Citem);
- end loop;
-
- -- Now sort the component entities based on the first bit.
- -- Note we already know there are no overlapping components.
-
- Sorting.Sort (Ncomps);
-
- -- Loop through entries checking for holes
-
- Nbit := Sbit;
- for J in 1 .. Ncomps loop
- CEnt := Comps (J);
-
- declare
- CBO : constant Uint := Component_Bit_Offset (CEnt);
-
- begin
- -- Skip components with unknown offsets
-
- if CBO /= No_Uint and then CBO >= 0 then
- Error_Msg_Uint_1 := CBO - Nbit;
-
- if Error_Msg_Uint_1 > 0 then
- Error_Msg_NE
- ("?H?^-bit gap before component&",
- Component_Name (Component_Clause (CEnt)),
- CEnt);
- end if;
-
- Nbit := CBO + Esize (CEnt);
- end if;
- end;
- end loop;
-
- -- Process variant parts recursively if present
-
- if Present (Variant_Part (CL)) then
- Variant := First (Variants (Variant_Part (CL)));
- while Present (Variant) loop
- Check_Component_List
- (Component_List (Variant), Nbit, No_List);
- Next (Variant);
- end loop;
- end if;
- end;
- end Check_Component_List;
-
- -- Start of processing for Record_Hole_Check
+ -- Check for record holes (gaps). We skip this check if overlap was
+ -- detected, since it makes sense for the programmer to fix this
+ -- error before worrying about warnings.
+ if Warn_On_Record_Holes and not Overlap_Detected then
+ declare
+ Ignore : Uint;
begin
- declare
- Sbit : Uint;
-
- begin
- if Is_Tagged_Type (Rectype) then
- Sbit := UI_From_Int (System_Address_Size);
- else
- Sbit := Uint_0;
- end if;
-
- if Nkind (Decl) = N_Full_Type_Declaration
- and then Nkind (Type_Definition (Decl)) = N_Record_Definition
- then
- Check_Component_List
- (Component_List (Type_Definition (Decl)),
- Sbit,
- Discriminant_Specifications (Decl));
- end if;
- end;
- end Record_Hole_Check;
+ Record_Hole_Check (Rectype, After_Last => Ignore, Warn => True);
+ end;
end if;
-- For records that have component clauses for all components, and whose
@@ -10803,7 +10886,7 @@ package body Sem_Ch13 is
if not ASIS_Mode then
Error_Msg_Uint_1 := Min_Siz;
- Error_Msg_NE ("size for& too small, minimum allowed is ^", N, T);
+ Error_Msg_NE (Size_Too_Small_Message, N, T);
end if;
end Size_Too_Small_Error;
@@ -11477,7 +11560,7 @@ package body Sem_Ch13 is
if Align = No_Uint then
return No_Uint;
- elsif Align <= 0 then
+ elsif Align < 0 then
-- This error is suppressed in ASIS mode to allow for different ASIS
-- back ends or ASIS-based tools to query the illegal clause.
@@ -11488,6 +11571,11 @@ package body Sem_Ch13 is
return No_Uint;
+ -- If Alignment is specified to be 0, we treat it the same as 1
+
+ elsif Align = 0 then
+ return Uint_1;
+
else
for J in Int range 0 .. 64 loop
declare
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index 645a024..1b4c42d 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -232,18 +232,6 @@ package body Sem_Ch3 is
-- Needs a more complete spec--what are the parameters exactly, and what
-- exactly is the returned value, and how is Bound affected???
- procedure Build_Underlying_Full_View
- (N : Node_Id;
- Typ : Entity_Id;
- Par : Entity_Id);
- -- If the completion of a private type is itself derived from a private
- -- type, or if the full view of a private subtype is itself private, the
- -- back-end has no way to compute the actual size of this type. We build
- -- an internal subtype declaration of the proper parent type to convey
- -- this information. This extra mechanism is needed because a full
- -- view cannot itself have a full view (it would get clobbered during
- -- view exchanges).
-
procedure Check_Access_Discriminant_Requires_Limited
(D : Node_Id;
Loc : Node_Id);
@@ -6843,7 +6831,9 @@ package body Sem_Ch3 is
Parent_Type : Entity_Id;
Derived_Type : Entity_Id)
is
- Loc : constant Source_Ptr := Sloc (N);
+ Loc : constant Source_Ptr := Sloc (N);
+ Def : constant Node_Id := Type_Definition (N);
+ Indic : constant Node_Id := Subtype_Indication (Def);
Corr_Record : constant Entity_Id := Make_Temporary (Loc, 'C');
Corr_Decl : Node_Id;
@@ -6854,8 +6844,7 @@ package body Sem_Ch3 is
-- this case.
Constraint_Present : constant Boolean :=
- Nkind (Subtype_Indication (Type_Definition (N))) =
- N_Subtype_Indication;
+ Nkind (Indic) = N_Subtype_Indication;
D_Constraint : Node_Id;
New_Constraint : Elist_Id := No_Elist;
@@ -6930,36 +6919,50 @@ package body Sem_Ch3 is
Expand_To_Stored_Constraint
(Parent_Type,
Build_Discriminant_Constraints
- (Parent_Type,
- Subtype_Indication (Type_Definition (N)), True));
+ (Parent_Type, Indic, True));
end if;
End_Scope;
elsif Constraint_Present then
- -- Build constrained subtype, copying the constraint, and derive
- -- from it to create a derived constrained type.
+ -- Build an unconstrained derived type and rewrite the derived type
+ -- as a subtype of this new base type.
declare
- Loc : constant Source_Ptr := Sloc (N);
- Anon : constant Entity_Id :=
- Make_Defining_Identifier (Loc,
- Chars => New_External_Name (Chars (Derived_Type), 'T'));
- Decl : Node_Id;
+ Parent_Base : constant Entity_Id := Base_Type (Parent_Type);
+ New_Base : Entity_Id;
+ New_Decl : Node_Id;
+ New_Indic : Node_Id;
begin
- Decl :=
+ New_Base :=
+ Create_Itype (Ekind (Derived_Type), N, Derived_Type, 'B');
+
+ New_Decl :=
+ Make_Full_Type_Declaration (Loc,
+ Defining_Identifier => New_Base,
+ Type_Definition =>
+ Make_Derived_Type_Definition (Loc,
+ Abstract_Present => Abstract_Present (Def),
+ Limited_Present => Limited_Present (Def),
+ Subtype_Indication =>
+ New_Occurrence_Of (Parent_Base, Loc)));
+
+ Mark_Rewrite_Insertion (New_Decl);
+ Insert_Before (N, New_Decl);
+ Analyze (New_Decl);
+
+ New_Indic :=
+ Make_Subtype_Indication (Loc,
+ Subtype_Mark => New_Occurrence_Of (New_Base, Loc),
+ Constraint => Relocate_Node (Constraint (Indic)));
+
+ Rewrite (N,
Make_Subtype_Declaration (Loc,
- Defining_Identifier => Anon,
- Subtype_Indication =>
- New_Copy_Tree (Subtype_Indication (Type_Definition (N))));
- Insert_Before (N, Decl);
- Analyze (Decl);
+ Defining_Identifier => Derived_Type,
+ Subtype_Indication => New_Indic));
- Rewrite (Subtype_Indication (Type_Definition (N)),
- New_Occurrence_Of (Anon, Loc));
- Set_Analyzed (Derived_Type, False);
Analyze (N);
return;
end;
@@ -6990,10 +6993,7 @@ package body Sem_Ch3 is
-- Verify that new discriminants are used to constrain old ones
- D_Constraint :=
- First
- (Constraints
- (Constraint (Subtype_Indication (Type_Definition (N)))));
+ D_Constraint := First (Constraints (Constraint (Indic)));
Old_Disc := First_Discriminant (Parent_Type);
@@ -7135,6 +7135,27 @@ package body Sem_Ch3 is
Parent_Type : Entity_Id;
Derived_Type : Entity_Id)
is
+ function Bound_Belongs_To_Type (B : Node_Id) return Boolean;
+ -- When the type declaration includes a constraint, we generate
+ -- a subtype declaration of an anonymous base type, with the constraint
+ -- given in the original type declaration. Conceptually, the bounds
+ -- are converted to the new base type, and this conversion freezes
+ -- (prematurely) that base type, when the bounds are simply literals.
+ -- As a result, a representation clause for the derived type is then
+ -- rejected or ignored. This procedure recognizes the simple case of
+ -- literal bounds, which allows us to indicate that the conversions
+ -- are not freeze points, and the subsequent representation clause
+ -- can be accepted.
+ -- A similar approach might be used to resolve the long-standing
+ -- problem of premature freezing of derived numeric types ???
+
+ function Bound_Belongs_To_Type (B : Node_Id) return Boolean is
+ begin
+ return Nkind (B) = N_Type_Conversion
+ and then Is_Entity_Name (Expression (B))
+ and then Ekind (Entity (Expression (B))) = E_Enumeration_Literal;
+ end Bound_Belongs_To_Type;
+
Loc : constant Source_Ptr := Sloc (N);
Def : constant Node_Id := Type_Definition (N);
Indic : constant Node_Id := Subtype_Indication (Def);
@@ -7350,7 +7371,9 @@ package body Sem_Ch3 is
-- However, if the type inherits predicates the expressions will
-- be elaborated earlier and must freeze.
- if Nkind (Indic) /= N_Subtype_Indication
+ if (Nkind (Indic) /= N_Subtype_Indication
+ or else
+ (Bound_Belongs_To_Type (Lo) and then Bound_Belongs_To_Type (Hi)))
and then not Has_Predicates (Derived_Type)
then
Set_Must_Not_Freeze (Lo);
@@ -7674,14 +7697,15 @@ package body Sem_Ch3 is
Full_Parent := Underlying_Full_View (Full_Parent);
end if;
- -- For record, access and most enumeration types, derivation from
- -- the full view requires a fully-fledged declaration. In the other
- -- cases, just use an itype.
+ -- For record, concurrent, access and most enumeration types, the
+ -- derivation from full view requires a fully-fledged declaration.
+ -- In the other cases, just use an itype.
- if Ekind (Full_Parent) in Record_Kind
- or else Ekind (Full_Parent) in Access_Kind
+ if Is_Record_Type (Full_Parent)
+ or else Is_Concurrent_Type (Full_Parent)
+ or else Is_Access_Type (Full_Parent)
or else
- (Ekind (Full_Parent) in Enumeration_Kind
+ (Is_Enumeration_Type (Full_Parent)
and then not Is_Standard_Character_Type (Full_Parent)
and then not Is_Generic_Type (Root_Type (Full_Parent)))
then
@@ -7710,7 +7734,7 @@ package body Sem_Ch3 is
-- is now installed. Subprograms have been derived on the partial
-- view, the completion does not derive them anew.
- if Ekind (Full_Parent) in Record_Kind then
+ if Is_Record_Type (Full_Parent) then
-- If parent type is tagged, the completion inherits the proper
-- primitive operations.
@@ -7912,12 +7936,10 @@ package body Sem_Ch3 is
-- Build the full derivation if this is not the anonymous derived
-- base type created by Build_Derived_Record_Type in the constrained
-- case (see point 5. of its head comment) since we build it for the
- -- derived subtype. And skip it for synchronized types altogether, as
- -- gigi does not use these types directly.
+ -- derived subtype.
if Present (Full_View (Parent_Type))
and then not Is_Itype (Derived_Type)
- and then not Is_Concurrent_Type (Full_View (Parent_Type))
then
declare
Der_Base : constant Entity_Id := Base_Type (Derived_Type);
@@ -8586,6 +8608,86 @@ package body Sem_Ch3 is
-- An empty Discs list means that there were no constraints in the
-- subtype indication or that there was an error processing it.
+ procedure Check_Generic_Ancestors;
+ -- In Ada 2005 (AI-344), the restriction that a derived tagged type
+ -- cannot be declared at a deeper level than its parent type is
+ -- removed. The check on derivation within a generic body is also
+ -- relaxed, but there's a restriction that a derived tagged type
+ -- cannot be declared in a generic body if it's derived directly
+ -- or indirectly from a formal type of that generic. This applies
+ -- to progenitors as well.
+
+ -----------------------------
+ -- Check_Generic_Ancestors --
+ -----------------------------
+
+ procedure Check_Generic_Ancestors is
+ Ancestor_Type : Entity_Id;
+ Intf_List : List_Id;
+ Intf_Name : Node_Id;
+
+ procedure Check_Ancestor;
+ -- For parent and progenitors.
+
+ --------------------
+ -- Check_Ancestor --
+ --------------------
+
+ procedure Check_Ancestor is
+ begin
+ -- If the derived type does have a formal type as an ancestor
+ -- then it's an error if the derived type is declared within
+ -- the body of the generic unit that declares the formal type
+ -- in its generic formal part. It's sufficient to check whether
+ -- the ancestor type is declared inside the same generic body
+ -- as the derived type (such as within a nested generic spec),
+ -- in which case the derivation is legal. If the formal type is
+ -- declared outside of that generic body, then it's certain
+ -- that the derived type is declared within the generic body
+ -- of the generic unit declaring the formal type.
+
+ if Is_Generic_Type (Ancestor_Type)
+ and then Enclosing_Generic_Body (Ancestor_Type) /=
+ Enclosing_Generic_Body (Derived_Type)
+ then
+ Error_Msg_NE
+ ("ancestor type& is formal type of enclosing"
+ & " generic unit (RM 3.9.1 (4/2))",
+ Indic, Ancestor_Type);
+ end if;
+ end Check_Ancestor;
+
+ begin
+ if Nkind (N) = N_Private_Extension_Declaration then
+ Intf_List := Interface_List (N);
+ else
+ Intf_List := Interface_List (Type_Definition (N));
+ end if;
+
+ if Present (Enclosing_Generic_Body (Derived_Type)) then
+ Ancestor_Type := Parent_Type;
+
+ while not Is_Generic_Type (Ancestor_Type)
+ and then Etype (Ancestor_Type) /= Ancestor_Type
+ loop
+ Ancestor_Type := Etype (Ancestor_Type);
+ end loop;
+
+ Check_Ancestor;
+
+ if Present (Intf_List) then
+ Intf_Name := First (Intf_List);
+ while Present (Intf_Name) loop
+ Ancestor_Type := Entity (Intf_Name);
+ Check_Ancestor;
+ Next (Intf_Name);
+ end loop;
+ end if;
+ end if;
+ end Check_Generic_Ancestors;
+
+ -- Start of processing for Build_Derived_Record_Type
+
begin
if Ekind (Parent_Type) = E_Record_Type_With_Private
and then Present (Full_View (Parent_Type))
@@ -8692,7 +8794,8 @@ package body Sem_Ch3 is
-- Indic can either be an N_Identifier if the subtype indication
-- contains no constraint or an N_Subtype_Indication if the subtype
- -- indication has a constraint.
+ -- indecation has a constraint. In either case it can include an
+ -- interface list.
Indic := Subtype_Indication (Type_Def);
Constraint_Present := (Nkind (Indic) = N_Subtype_Indication);
@@ -8921,52 +9024,8 @@ package body Sem_Ch3 is
Freeze_Before (N, Parent_Type);
end if;
- -- In Ada 2005 (AI-344), the restriction that a derived tagged type
- -- cannot be declared at a deeper level than its parent type is
- -- removed. The check on derivation within a generic body is also
- -- relaxed, but there's a restriction that a derived tagged type
- -- cannot be declared in a generic body if it's derived directly
- -- or indirectly from a formal type of that generic.
-
if Ada_Version >= Ada_2005 then
- if Present (Enclosing_Generic_Body (Derived_Type)) then
- declare
- Ancestor_Type : Entity_Id;
-
- begin
- -- Check to see if any ancestor of the derived type is a
- -- formal type.
-
- Ancestor_Type := Parent_Type;
- while not Is_Generic_Type (Ancestor_Type)
- and then Etype (Ancestor_Type) /= Ancestor_Type
- loop
- Ancestor_Type := Etype (Ancestor_Type);
- end loop;
-
- -- If the derived type does have a formal type as an
- -- ancestor, then it's an error if the derived type is
- -- declared within the body of the generic unit that
- -- declares the formal type in its generic formal part. It's
- -- sufficient to check whether the ancestor type is declared
- -- inside the same generic body as the derived type (such as
- -- within a nested generic spec), in which case the
- -- derivation is legal. If the formal type is declared
- -- outside of that generic body, then it's guaranteed that
- -- the derived type is declared within the generic body of
- -- the generic unit declaring the formal type.
-
- if Is_Generic_Type (Ancestor_Type)
- and then Enclosing_Generic_Body (Ancestor_Type) /=
- Enclosing_Generic_Body (Derived_Type)
- then
- Error_Msg_NE
- ("parent type of& must not be descendant of formal type"
- & " of an enclosing generic body",
- Indic, Derived_Type);
- end if;
- end;
- end if;
+ Check_Generic_Ancestors;
elsif Type_Access_Level (Derived_Type) /=
Type_Access_Level (Parent_Type)
@@ -10447,111 +10506,6 @@ package body Sem_Ch3 is
return New_Bound;
end Build_Scalar_Bound;
- --------------------------------
- -- Build_Underlying_Full_View --
- --------------------------------
-
- procedure Build_Underlying_Full_View
- (N : Node_Id;
- Typ : Entity_Id;
- Par : Entity_Id)
- is
- Loc : constant Source_Ptr := Sloc (N);
- Subt : constant Entity_Id :=
- Make_Defining_Identifier
- (Loc, New_External_Name (Chars (Typ), 'S'));
-
- Constr : Node_Id;
- Indic : Node_Id;
- C : Node_Id;
- Id : Node_Id;
-
- procedure Set_Discriminant_Name (Id : Node_Id);
- -- If the derived type has discriminants, they may rename discriminants
- -- of the parent. When building the full view of the parent, we need to
- -- recover the names of the original discriminants if the constraint is
- -- given by named associations.
-
- ---------------------------
- -- Set_Discriminant_Name --
- ---------------------------
-
- procedure Set_Discriminant_Name (Id : Node_Id) is
- Disc : Entity_Id;
-
- begin
- Set_Original_Discriminant (Id, Empty);
-
- if Has_Discriminants (Typ) then
- Disc := First_Discriminant (Typ);
- while Present (Disc) loop
- if Chars (Disc) = Chars (Id)
- and then Present (Corresponding_Discriminant (Disc))
- then
- Set_Chars (Id, Chars (Corresponding_Discriminant (Disc)));
- end if;
- Next_Discriminant (Disc);
- end loop;
- end if;
- end Set_Discriminant_Name;
-
- -- Start of processing for Build_Underlying_Full_View
-
- begin
- if Nkind (N) = N_Full_Type_Declaration then
- Constr := Constraint (Subtype_Indication (Type_Definition (N)));
-
- elsif Nkind (N) = N_Subtype_Declaration then
- Constr := New_Copy_Tree (Constraint (Subtype_Indication (N)));
-
- elsif Nkind (N) = N_Component_Declaration then
- Constr :=
- New_Copy_Tree
- (Constraint (Subtype_Indication (Component_Definition (N))));
-
- else
- raise Program_Error;
- end if;
-
- C := First (Constraints (Constr));
- while Present (C) loop
- if Nkind (C) = N_Discriminant_Association then
- Id := First (Selector_Names (C));
- while Present (Id) loop
- Set_Discriminant_Name (Id);
- Next (Id);
- end loop;
- end if;
-
- Next (C);
- end loop;
-
- Indic :=
- Make_Subtype_Declaration (Loc,
- Defining_Identifier => Subt,
- Subtype_Indication =>
- Make_Subtype_Indication (Loc,
- Subtype_Mark => New_Occurrence_Of (Par, Loc),
- Constraint => New_Copy_Tree (Constr)));
-
- -- If this is a component subtype for an outer itype, it is not
- -- a list member, so simply set the parent link for analysis: if
- -- the enclosing type does not need to be in a declarative list,
- -- neither do the components.
-
- if Is_List_Member (N)
- and then Nkind (N) /= N_Component_Declaration
- then
- Insert_Before (N, Indic);
- else
- Set_Parent (Indic, Parent (N));
- end if;
-
- Analyze (Indic);
- Set_Underlying_Full_View (Typ, Full_View (Subt));
- Set_Is_Underlying_Full_View (Full_View (Subt));
- end Build_Underlying_Full_View;
-
-------------------------------
-- Check_Abstract_Overriding --
-------------------------------
@@ -12347,10 +12301,9 @@ package body Sem_Ch3 is
Save_Next_Entity := Next_Entity (Full);
Save_Homonym := Homonym (Priv);
- if Ekind (Full_Base) in Private_Kind
- or else Ekind (Full_Base) in Protected_Kind
- or else Ekind (Full_Base) in Record_Kind
- or else Ekind (Full_Base) in Task_Kind
+ if Is_Private_Type (Full_Base)
+ or else Is_Record_Type (Full_Base)
+ or else Is_Concurrent_Type (Full_Base)
then
Copy_Node (Priv, Full);
@@ -12471,7 +12424,6 @@ package body Sem_Ch3 is
Set_Freeze_Node (Full, Empty);
Set_Is_Frozen (Full, False);
- Set_Full_View (Priv, Full);
if Has_Discriminants (Full) then
Set_Stored_Constraint_From_Discriminant_Constraint (Full);
@@ -12492,26 +12444,24 @@ package body Sem_Ch3 is
(Full, Related_Nod, Full_Base, Discriminant_Constraint (Priv));
-- If the full base is itself derived from private, build a congruent
- -- subtype of its underlying type, for use by the back end. For a
- -- constrained record component, the declaration cannot be placed on
- -- the component list, but it must nevertheless be built an analyzed, to
- -- supply enough information for Gigi to compute the size of component.
+ -- subtype of its underlying full view, for use by the back end.
- elsif Ekind (Full_Base) in Private_Kind
- and then Is_Derived_Type (Full_Base)
- and then Has_Discriminants (Full_Base)
- and then (Ekind (Current_Scope) /= E_Record_Subtype)
+ elsif Is_Private_Type (Full_Base)
+ and then Present (Underlying_Full_View (Full_Base))
then
- if not Is_Itype (Priv)
- and then
- Nkind (Subtype_Indication (Parent (Priv))) = N_Subtype_Indication
- then
- Build_Underlying_Full_View
- (Parent (Priv), Full, Etype (Full_Base));
-
- elsif Nkind (Related_Nod) = N_Component_Declaration then
- Build_Underlying_Full_View (Related_Nod, Full, Etype (Full_Base));
- end if;
+ declare
+ Underlying_Full_Base : constant Entity_Id
+ := Underlying_Full_View (Full_Base);
+ Underlying_Full : constant Entity_Id
+ := Make_Defining_Identifier (Sloc (Priv), Chars (Priv));
+ begin
+ Set_Is_Itype (Underlying_Full);
+ Set_Associated_Node_For_Itype (Underlying_Full, Related_Nod);
+ Complete_Private_Subtype
+ (Priv, Underlying_Full, Underlying_Full_Base, Related_Nod);
+ Set_Underlying_Full_View (Full, Underlying_Full);
+ Set_Is_Underlying_Full_View (Underlying_Full);
+ end;
elsif Is_Record_Type (Full_Base) then
@@ -19928,20 +19878,12 @@ package body Sem_Ch3 is
Related_Nod : Node_Id)
is
Id_B : constant Entity_Id := Base_Type (Id);
- Full_B : Entity_Id := Full_View (Id_B);
+ Full_B : constant Entity_Id := Full_View (Id_B);
Full : Entity_Id;
begin
if Present (Full_B) then
- -- Get to the underlying full view if necessary
-
- if Is_Private_Type (Full_B)
- and then Present (Underlying_Full_View (Full_B))
- then
- Full_B := Underlying_Full_View (Full_B);
- end if;
-
-- The Base_Type is already completed, we can complete the subtype
-- now. We have to create a new entity with the same name, Thus we
-- can't use Create_Itype.
@@ -19950,6 +19892,7 @@ package body Sem_Ch3 is
Set_Is_Itype (Full);
Set_Associated_Node_For_Itype (Full, Related_Nod);
Complete_Private_Subtype (Id, Full, Full_B, Related_Nod);
+ Set_Full_View (Id, Full);
end if;
-- The parent subtype may be private, but the base might not, in some
@@ -20755,6 +20698,7 @@ package body Sem_Ch3 is
end if;
Complete_Private_Subtype (Full, Priv, Full_T, N);
+ Set_Full_View (Full, Priv);
if Present (Priv_Scop) then
Pop_Scope;
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index f7b99d4..16614ed 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -676,9 +676,15 @@ package body Sem_Ch4 is
-- In GNATprove mode we need to preserve the link between
-- the original subtype indication and the anonymous subtype,
- -- to extend proofs to constrained acccess types.
-
- if Expander_Active or else GNATprove_Mode then
+ -- to extend proofs to constrained acccess types. We only do
+ -- that outside of spec expressions, otherwise the declaration
+ -- cannot be inserted and analyzed. In such a case, GNATprove
+ -- later rejects the allocator as it is not used here in
+ -- a non-interfering context (SPARK 4.8(2) and 7.1.3(12)).
+
+ if Expander_Active
+ or else (GNATprove_Mode and then not In_Spec_Expression)
+ then
Def_Id := Make_Temporary (Loc, 'S');
Insert_Action (E,
@@ -3619,59 +3625,6 @@ package body Sem_Ch4 is
Next_Actual (Actual);
Next_Formal (Formal);
- -- In a complex case where an enclosing generic and a nested
- -- generic package, both declared with partially parameterized
- -- formal subprograms with the same names, are instantiated
- -- with the same type, the types of the actual parameter and
- -- that of the formal may appear incompatible at first sight.
-
- -- generic
- -- type Outer_T is private;
- -- with function Func (Formal : Outer_T)
- -- return ... is <>;
-
- -- package Outer_Gen is
- -- generic
- -- type Inner_T is private;
- -- with function Func (Formal : Inner_T) -- (1)
- -- return ... is <>;
-
- -- package Inner_Gen is
- -- function Inner_Func (Formal : Inner_T) -- (2)
- -- return ... is (Func (Formal));
- -- end Inner_Gen;
- -- end Outer_Generic;
-
- -- package Outer_Inst is new Outer_Gen (Actual_T);
- -- package Inner_Inst is new Outer_Inst.Inner_Gen (Actual_T);
-
- -- In the example above, the type of parameter
- -- Inner_Func.Formal at (2) is incompatible with the type of
- -- Func.Formal at (1) in the context of instantiations
- -- Outer_Inst and Inner_Inst. In reality both types are generic
- -- actual subtypes renaming base type Actual_T as part of the
- -- generic prologues for the instantiations.
-
- -- Recognize this case and add a type conversion to allow this
- -- kind of generic actual subtype conformance. Note that this
- -- is done only when the call is non-overloaded because the
- -- resolution mechanism already has the means to disambiguate
- -- similar cases.
-
- elsif not Is_Overloaded (Name (N))
- and then Is_Type (Etype (Actual))
- and then Is_Type (Etype (Formal))
- and then Is_Generic_Actual_Type (Etype (Actual))
- and then Is_Generic_Actual_Type (Etype (Formal))
- and then Base_Type (Etype (Actual)) =
- Base_Type (Etype (Formal))
- then
- Rewrite (Actual,
- Convert_To (Etype (Formal), Relocate_Node (Actual)));
- Analyze_And_Resolve (Actual, Etype (Formal));
- Next_Actual (Actual);
- Next_Formal (Formal);
-
-- Handle failed type check
else
@@ -5041,7 +4994,15 @@ package body Sem_Ch4 is
if Comp = First_Private_Entity (Type_To_Use) then
if Etype (Sel) /= Any_Type then
- -- We have a candiate
+ -- If the first private entity's name matches, then treat
+ -- it as a private op: needed for the error check for
+ -- illegal selection of private entities further below.
+
+ if Chars (Comp) = Chars (Sel) then
+ Is_Private_Op := True;
+ end if;
+
+ -- We have a candidate, so exit the loop
exit;
diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index ebe610b..963819e 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -3636,11 +3636,16 @@ package body Sem_Ch5 is
then
Rng := Range_Expression (Constraint (Rng));
- -- Preanalyze the bounds of the range constraint
+ -- Preanalyze the bounds of the range constraint, setting
+ -- parent fields to associate the copied bounds with the range,
+ -- allowing proper tree climbing during preanalysis.
Low := New_Copy_Tree (Low_Bound (Rng));
High := New_Copy_Tree (High_Bound (Rng));
+ Set_Parent (Low, Rng);
+ Set_Parent (High, Rng);
+
Preanalyze (Low);
Preanalyze (High);
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index 25ee705..fb50ec7 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -1056,9 +1056,17 @@ package body Sem_Ch6 is
-- Apply constraint check. Note that this is done before the implicit
-- conversion of the expression done for anonymous access types to
-- ensure correct generation of the null-excluding check associated
- -- with null-excluding expressions found in return statements.
-
- Apply_Constraint_Check (Expr, R_Type);
+ -- with null-excluding expressions found in return statements. We
+ -- don't need a check if the subtype of the return object is the
+ -- same as the result subtype of the function.
+
+ if Nkind (N) /= N_Extended_Return_Statement
+ or else Nkind (Obj_Decl) /= N_Object_Declaration
+ or else Nkind (Object_Definition (Obj_Decl)) not in N_Has_Entity
+ or else Entity (Object_Definition (Obj_Decl)) /= R_Type
+ then
+ Apply_Constraint_Check (Expr, R_Type);
+ end if;
-- The return value is converted to the return type of the function,
-- which implies a predicate check if the return type is predicated.
@@ -7026,6 +7034,11 @@ package body Sem_Ch6 is
In_Scope : Boolean;
Typ : Entity_Id;
+ function Is_Valid_Formal (F : Entity_Id) return Boolean;
+ -- Predicate for legality rule in 9.4 (11.9/2): If an inherited
+ -- subprogram is implemented by a protected procedure or entry,
+ -- its first parameter must be out, in out, or access-to-variable.
+
function Matches_Prefixed_View_Profile
(Prim_Params : List_Id;
Iface_Params : List_Id) return Boolean;
@@ -7034,6 +7047,19 @@ package body Sem_Ch6 is
-- Iface_Params. Also determine if the type of first parameter of
-- Iface_Params is an implemented interface.
+ ----------------------
+ -- Is_Valid_Formal --
+ ----------------------
+
+ function Is_Valid_Formal (F : Entity_Id) return Boolean is
+ begin
+ return
+ Ekind_In (F, E_In_Out_Parameter, E_Out_Parameter)
+ or else
+ (Nkind (Parameter_Type (Parent (F))) = N_Access_Definition
+ and then not Constant_Present (Parameter_Type (Parent (F))));
+ end Is_Valid_Formal;
+
-----------------------------------
-- Matches_Prefixed_View_Profile --
-----------------------------------
@@ -7287,10 +7313,7 @@ package body Sem_Ch6 is
if Ekind_In (Candidate, E_Entry, E_Procedure)
and then Is_Protected_Type (Typ)
- and then Ekind (Formal) /= E_In_Out_Parameter
- and then Ekind (Formal) /= E_Out_Parameter
- and then Nkind (Parameter_Type (Parent (Formal))) /=
- N_Access_Definition
+ and then not Is_Valid_Formal (Formal)
then
null;
@@ -8420,11 +8443,12 @@ package body Sem_Ch6 is
begin
-- This check applies only if we have a subprogram declaration with an
- -- untagged record type.
+ -- untagged record type that is conformant to the predefined op.
if Nkind (Decl) /= N_Subprogram_Declaration
or else not Is_Record_Type (Typ)
or else Is_Tagged_Type (Typ)
+ or else Etype (Next_Formal (First_Formal (Eq_Op))) /= Typ
then
return;
end if;
diff --git a/gcc/ada/sem_ch7.adb b/gcc/ada/sem_ch7.adb
index e0d20ef..f7998c0 100644
--- a/gcc/ada/sem_ch7.adb
+++ b/gcc/ada/sem_ch7.adb
@@ -2261,13 +2261,14 @@ package body Sem_Ch7 is
procedure Swap_Private_Dependents (Priv_Deps : Elist_Id);
-- When the full view of a private type is made available, we do the
-- same for its private dependents under proper visibility conditions.
- -- When compiling a grandchild unit this needs to be done recursively.
+ -- When compiling a child unit this needs to be done recursively.
-----------------------------
-- Swap_Private_Dependents --
-----------------------------
procedure Swap_Private_Dependents (Priv_Deps : Elist_Id) is
+ Cunit : Entity_Id;
Deps : Elist_Id;
Priv : Entity_Id;
Priv_Elmt : Elmt_Id;
@@ -2285,6 +2286,7 @@ package body Sem_Ch7 is
if Present (Full_View (Priv)) and then Is_Visible_Dependent (Priv)
then
if Is_Private_Type (Priv) then
+ Cunit := Cunit_Entity (Current_Sem_Unit);
Deps := Private_Dependents (Priv);
Is_Priv := True;
else
@@ -2312,11 +2314,14 @@ package body Sem_Ch7 is
Set_Is_Potentially_Use_Visible
(Priv, Is_Potentially_Use_Visible (Node (Priv_Elmt)));
- -- Within a child unit, recurse, except in generic child unit,
- -- which (unfortunately) handle private_dependents separately.
+ -- Recurse for child units, except in generic child units,
+ -- which unfortunately handle private_dependents separately.
+ -- Note that the current unit may not have been analyzed,
+ -- for example a package body, so we cannot rely solely on
+ -- the Is_Child_Unit flag, but that's only an optimization.
if Is_Priv
- and then Is_Child_Unit (Cunit_Entity (Current_Sem_Unit))
+ and then (No (Etype (Cunit)) or else Is_Child_Unit (Cunit))
and then not Is_Empty_Elmt_List (Deps)
and then not Inside_A_Generic
then
@@ -2701,13 +2706,16 @@ package body Sem_Ch7 is
Decl : constant Node_Id := Unit_Declaration_Node (P);
Id : Entity_Id;
Full : Entity_Id;
- Priv_Elmt : Elmt_Id;
- Priv_Sub : Entity_Id;
procedure Preserve_Full_Attributes (Priv : Entity_Id; Full : Entity_Id);
-- Copy to the private declaration the attributes of the full view that
-- need to be available for the partial view also.
+ procedure Swap_Private_Dependents (Priv_Deps : Elist_Id);
+ -- When the full view of a private type is made unavailable, we do the
+ -- same for its private dependents under proper visibility conditions.
+ -- When compiling a child unit this needs to be done recursively.
+
function Type_In_Use (T : Entity_Id) return Boolean;
-- Check whether type or base type appear in an active use_type clause
@@ -2826,6 +2834,66 @@ package body Sem_Ch7 is
end if;
end Preserve_Full_Attributes;
+ -----------------------------
+ -- Swap_Private_Dependents --
+ -----------------------------
+
+ procedure Swap_Private_Dependents (Priv_Deps : Elist_Id) is
+ Cunit : Entity_Id;
+ Deps : Elist_Id;
+ Priv : Entity_Id;
+ Priv_Elmt : Elmt_Id;
+ Is_Priv : Boolean;
+
+ begin
+ Priv_Elmt := First_Elmt (Priv_Deps);
+ while Present (Priv_Elmt) loop
+ Priv := Node (Priv_Elmt);
+
+ -- Before we do the swap, we verify the presence of the Full_View
+ -- field, which may be empty due to a swap by a previous call to
+ -- End_Package_Scope (e.g. from the freezing mechanism).
+
+ if Present (Full_View (Priv)) then
+ if Is_Private_Type (Priv) then
+ Cunit := Cunit_Entity (Current_Sem_Unit);
+ Deps := Private_Dependents (Priv);
+ Is_Priv := True;
+ else
+ Is_Priv := False;
+ end if;
+
+ if Scope (Priv) = P
+ or else not In_Open_Scopes (Scope (Priv))
+ then
+ Set_Is_Immediately_Visible (Priv, False);
+ end if;
+
+ if Is_Visible_Dependent (Priv) then
+ Preserve_Full_Attributes (Priv, Full_View (Priv));
+ Replace_Elmt (Priv_Elmt, Full_View (Priv));
+ Exchange_Declarations (Priv);
+
+ -- Recurse for child units, except in generic child units,
+ -- which unfortunately handle private_dependents separately.
+ -- Note that the current unit may not have been analyzed,
+ -- for example a package body, so we cannot rely solely on
+ -- the Is_Child_Unit flag, but that's only an optimization.
+
+ if Is_Priv
+ and then (No (Etype (Cunit)) or else Is_Child_Unit (Cunit))
+ and then not Is_Empty_Elmt_List (Deps)
+ and then not Inside_A_Generic
+ then
+ Swap_Private_Dependents (Deps);
+ end if;
+ end if;
+ end if;
+
+ Next_Elmt (Priv_Elmt);
+ end loop;
+ end Swap_Private_Dependents;
+
-----------------
-- Type_In_Use --
-----------------
@@ -3077,31 +3145,7 @@ package body Sem_Ch7 is
-- were compiled in this scope, or installed previously
-- by Install_Private_Declarations.
- -- Before we do the swap, we verify the presence of the Full_View
- -- field which may be empty due to a swap by a previous call to
- -- End_Package_Scope (e.g. from the freezing mechanism).
-
- Priv_Elmt := First_Elmt (Private_Dependents (Id));
- while Present (Priv_Elmt) loop
- Priv_Sub := Node (Priv_Elmt);
-
- if Present (Full_View (Priv_Sub)) then
- if Scope (Priv_Sub) = P
- or else not In_Open_Scopes (Scope (Priv_Sub))
- then
- Set_Is_Immediately_Visible (Priv_Sub, False);
- end if;
-
- if Is_Visible_Dependent (Priv_Sub) then
- Preserve_Full_Attributes
- (Priv_Sub, Full_View (Priv_Sub));
- Replace_Elmt (Priv_Elmt, Full_View (Priv_Sub));
- Exchange_Declarations (Priv_Sub);
- end if;
- end if;
-
- Next_Elmt (Priv_Elmt);
- end loop;
+ Swap_Private_Dependents (Private_Dependents (Id));
-- Now restore the type itself to its private view
diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
index 7185c40..38c3980 100644
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -3368,7 +3368,16 @@ package body Sem_Ch8 is
if CW_Actual then
null;
- elsif not Is_Actual or else No (Enclosing_Instance) then
+
+ -- No need for a redundant error message if this is a nested
+ -- instance, unless the current instantiation (of a child unit)
+ -- is a compilation unit, which is not analyzed when the parent
+ -- generic is analyzed.
+
+ elsif not Is_Actual
+ or else No (Enclosing_Instance)
+ or else Is_Compilation_Unit (Current_Scope)
+ then
Check_Mode_Conformant (New_S, Old_S);
end if;
@@ -6721,6 +6730,15 @@ package body Sem_Ch8 is
Old_S : Entity_Id;
Inst : Entity_Id;
+ function Find_Nearer_Entity
+ (New_S : Entity_Id;
+ Old1_S : Entity_Id;
+ Old2_S : Entity_Id) return Entity_Id;
+ -- Determine whether one of Old_S1 and Old_S2 is nearer to New_S than
+ -- the other, and return it if so. Return Empty otherwise. We use this
+ -- in conjunction with Inherit_Renamed_Profile to simplify later type
+ -- disambiguation for actual subprograms in instances.
+
function Is_Visible_Operation (Op : Entity_Id) return Boolean;
-- If the renamed entity is an implicit operator, check whether it is
-- visible because its operand type is properly visible. This check
@@ -6737,6 +6755,99 @@ package body Sem_Ch8 is
-- enclosing instance. If yes, it has precedence over outer candidates.
--------------------------
+ -- Find_Nearer_Entity --
+ --------------------------
+
+ function Find_Nearer_Entity
+ (New_S : Entity_Id;
+ Old1_S : Entity_Id;
+ Old2_S : Entity_Id) return Entity_Id
+ is
+ New_F : Entity_Id;
+ Old1_F : Entity_Id;
+ Old2_F : Entity_Id;
+ Anc_T : Entity_Id;
+
+ begin
+ New_F := First_Formal (New_S);
+ Old1_F := First_Formal (Old1_S);
+ Old2_F := First_Formal (Old2_S);
+
+ -- The criterion is whether the type of the formals of one of Old1_S
+ -- and Old2_S is an ancestor subtype of the type of the corresponding
+ -- formals of New_S while the other is not (we already know that they
+ -- are all subtypes of the same base type).
+
+ -- This makes it possible to find the more correct renamed entity in
+ -- the case of a generic instantiation nested in an enclosing one for
+ -- which different formal types get the same actual type, which will
+ -- in turn make it possible for Inherit_Renamed_Profile to preserve
+ -- types on formal parameters and ultimately simplify disambiguation.
+
+ -- Consider the follow package G:
+
+ -- generic
+ -- type Item_T is private;
+ -- with function Compare (L, R: Item_T) return Boolean is <>;
+
+ -- type Bound_T is private;
+ -- with function Compare (L, R : Bound_T) return Boolean is <>;
+ -- package G is
+ -- ...
+ -- end G;
+
+ -- package body G is
+ -- package My_Inner is Inner_G (Bound_T);
+ -- ...
+ -- end G;
+
+ -- with the following package Inner_G:
+
+ -- generic
+ -- type T is private;
+ -- with function Compare (L, R: T) return Boolean is <>;
+ -- package Inner_G is
+ -- function "<" (L, R: T) return Boolean is (Compare (L, R));
+ -- end Inner_G;
+
+ -- If G is instantiated on the same actual type with a single Compare
+ -- function:
+
+ -- type T is ...
+ -- function Compare (L, R : T) return Boolean;
+ -- package My_G is new (T, T);
+
+ -- then the renaming generated for Compare in the inner instantiation
+ -- is ambiguous: it can rename either of the renamings generated for
+ -- the outer instantiation. Now if the first one is picked up, then
+ -- the subtypes of the formal parameters of the renaming will not be
+ -- preserved in Inherit_Renamed_Profile because they are subtypes of
+ -- the Bound_T formal type and not of the Item_T formal type, so we
+ -- need to arrange for the second one to be picked up instead.
+
+ while Present (New_F) loop
+ if Etype (Old1_F) /= Etype (Old2_F) then
+ Anc_T := Ancestor_Subtype (Etype (New_F));
+
+ if Etype (Old1_F) = Anc_T then
+ return Old1_S;
+ elsif Etype (Old2_F) = Anc_T then
+ return Old2_S;
+ end if;
+ end if;
+
+ Next_Formal (New_F);
+ Next_Formal (Old1_F);
+ Next_Formal (Old2_F);
+ end loop;
+
+ pragma Assert (No (Old1_F));
+ pragma Assert (No (Old2_F));
+
+ return Empty;
+ end Find_Nearer_Entity;
+
+ --------------------------
-- Is_Visible_Operation --
--------------------------
@@ -6860,21 +6971,37 @@ package body Sem_Ch8 is
if Present (Inst) then
if Within (It.Nam, Inst) then
if Within (Old_S, Inst) then
-
- -- Choose the innermost subprogram, which would
- -- have hidden the outer one in the generic.
-
- if Scope_Depth (It.Nam) <
- Scope_Depth (Old_S)
- then
- return Old_S;
- else
- return It.Nam;
- end if;
+ declare
+ It_D : constant Uint := Scope_Depth (It.Nam);
+ Old_D : constant Uint := Scope_Depth (Old_S);
+ N_Ent : Entity_Id;
+ begin
+ -- Choose the innermost subprogram, which
+ -- would hide the outer one in the generic.
+
+ if Old_D > It_D then
+ return Old_S;
+ elsif It_D > Old_D then
+ return It.Nam;
+ end if;
+
+ -- Otherwise, if we can determine that one
+ -- of the entities is nearer to the renaming
+ -- than the other, choose it. If not, then
+ -- return the newer one as done historically.
+
+ N_Ent :=
+ Find_Nearer_Entity (New_S, Old_S, It.Nam);
+ if Present (N_Ent) then
+ return N_Ent;
+ else
+ return It.Nam;
+ end if;
+ end;
end if;
elsif Within (Old_S, Inst) then
- return (Old_S);
+ return Old_S;
else
return Report_Overload;
diff --git a/gcc/ada/sem_dim.adb b/gcc/ada/sem_dim.adb
index 2bcccd2..177902f 100644
--- a/gcc/ada/sem_dim.adb
+++ b/gcc/ada/sem_dim.adb
@@ -1142,6 +1142,11 @@ package body Sem_Dim is
if Ada_Version < Ada_2012 then
return;
+ -- Inlined bodies have already been checked for dimensionality
+
+ elsif In_Inlined_Body then
+ return;
+
elsif not Comes_From_Source (N) then
if Nkind_In (N, N_Explicit_Dereference,
N_Identifier,
@@ -1245,10 +1250,13 @@ package body Sem_Dim is
-- Aspect is an Ada 2012 feature. Nothing to do here if the component
-- base type is not a dimensioned type.
+ -- Inlined bodies have already been checked for dimensionality.
+
-- Note that here the original node must come from source since the
-- original array aggregate may not have been entirely decorated.
if Ada_Version < Ada_2012
+ or else In_Inlined_Body
or else not Comes_From_Source (Original_Node (N))
or else not Has_Dimension_System (Base_Type (Comp_Typ))
then
@@ -1634,10 +1642,11 @@ package body Sem_Dim is
begin
-- Aspect is an Ada 2012 feature. Note that there is no need to check
- -- dimensions for calls that don't come from source, or those that may
- -- have semantic errors.
+ -- dimensions for calls in inlined bodies, or calls that don't come
+ -- from source, or those that may have semantic errors.
if Ada_Version < Ada_2012
+ or else In_Inlined_Body
or else not Comes_From_Source (N)
or else Error_Posted (N)
then
@@ -1966,11 +1975,12 @@ package body Sem_Dim is
begin
-- Aspect is an Ada 2012 feature. Note that there is no need to check
- -- dimensions for aggregates that don't come from source, or if we are
- -- within an initialization procedure, whose expressions have been
- -- checked at the point of record declaration.
+ -- dimensions in inlined bodies, or for aggregates that don't come
+ -- from source, or if we are within an initialization procedure, whose
+ -- expressions have been checked at the point of record declaration.
if Ada_Version < Ada_2012
+ or else In_Inlined_Body
or else not Comes_From_Source (N)
or else Inside_Init_Proc
then
diff --git a/gcc/ada/sem_disp.adb b/gcc/ada/sem_disp.adb
index 5deba18..ee8f443 100644
--- a/gcc/ada/sem_disp.adb
+++ b/gcc/ada/sem_disp.adb
@@ -1149,6 +1149,10 @@ package body Sem_Disp is
-- overridden primitives. The wrappers include checks on these
-- modified conditions. (AI12-113).
+ -- 5. Declarations built for subprograms without separate spec which
+ -- are eligible for inlining in GNATprove (inside
+ -- Sem_Ch6.Analyze_Subprogram_Body_Helper).
+
if Present (Old_Subp)
and then Present (Overridden_Operation (Subp))
and then Is_Dispatching_Operation (Old_Subp)
@@ -1168,7 +1172,9 @@ package body Sem_Disp is
or else Get_TSS_Name (Subp) = TSS_Stream_Read
or else Get_TSS_Name (Subp) = TSS_Stream_Write
- or else Present (Contract (Overridden_Operation (Subp))));
+ or else Present (Contract (Overridden_Operation (Subp)))
+
+ or else GNATprove_Mode);
Check_Controlling_Formals (Tagged_Type, Subp);
Override_Dispatching_Operation (Tagged_Type, Old_Subp, Subp);
diff --git a/gcc/ada/sem_disp.ads b/gcc/ada/sem_disp.ads
index c3f4586..fd399a3 100644
--- a/gcc/ada/sem_disp.ads
+++ b/gcc/ada/sem_disp.ads
@@ -151,7 +151,8 @@ package Sem_Disp is
-- Returns True if E is a null procedure that is an interface primitive
function Is_Overriding_Subprogram (E : Entity_Id) return Boolean;
- -- Returns True if E is an overriding subprogram
+ -- Returns True if E is an overriding subprogram and False otherwise, in
+ -- particular for an inherited subprogram.
function Is_Tag_Indeterminate (N : Node_Id) return Boolean;
-- Returns true if the expression N is tag-indeterminate. An expression
diff --git a/gcc/ada/sem_elab.adb b/gcc/ada/sem_elab.adb
index 3145559..714a9f7 100644
--- a/gcc/ada/sem_elab.adb
+++ b/gcc/ada/sem_elab.adb
@@ -49,6 +49,7 @@ with Sem_Aux; use Sem_Aux;
with Sem_Cat; use Sem_Cat;
with Sem_Ch7; use Sem_Ch7;
with Sem_Ch8; use Sem_Ch8;
+with Sem_Disp; use Sem_Disp;
with Sem_Prag; use Sem_Prag;
with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo;
@@ -15233,9 +15234,12 @@ package body Sem_Elab is
begin
-- Nothing to do for predefined primitives because they are
-- artifacts of tagged type expansion and cannot override source
- -- primitives.
+ -- primitives. Nothing to do as well for inherited primitives as
+ -- the check concerns overridding ones.
- if Is_Predefined_Dispatching_Operation (Prim) then
+ if Is_Predefined_Dispatching_Operation (Prim)
+ or else not Is_Overriding_Subprogram (Prim)
+ then
return;
end if;
diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb
index 734c961..78740b9 100644
--- a/gcc/ada/sem_eval.adb
+++ b/gcc/ada/sem_eval.adb
@@ -562,23 +562,31 @@ package body Sem_Eval is
elsif Is_Out_Of_Range (N, Base_Type (T), Assume_Valid => True) then
Out_Of_Range (N);
- -- Give warning if outside subtype (where one or both of the bounds of
- -- the subtype is static). This warning is omitted if the expression
- -- appears in a range that could be null (warnings are handled elsewhere
- -- for this case).
+ -- Give a warning or error on the value outside the subtype. A
+ -- warning is omitted if the expression appears in a range that could
+ -- be null (warnings are handled elsewhere for this case).
elsif T /= Base_Type (T) and then Nkind (Parent (N)) /= N_Range then
if Is_In_Range (N, T, Assume_Valid => True) then
null;
elsif Is_Out_Of_Range (N, T, Assume_Valid => True) then
-
-- Ignore out of range values for System.Priority in CodePeer
-- mode since the actual target compiler may provide a wider
-- range.
if CodePeer_Mode and then T = RTE (RE_Priority) then
Set_Do_Range_Check (N, False);
+
+ -- Determine if the out of range violation constitutes a warning
+ -- or an error based on context according to RM 4.9 (34/3).
+
+ elsif Nkind_In (Original_Node (N), N_Type_Conversion,
+ N_Qualified_Expression)
+ and then Comes_From_Source (Original_Node (N))
+ then
+ Apply_Compile_Time_Constraint_Error
+ (N, "value not in range of}", CE_Range_Check_Failed);
else
Apply_Compile_Time_Constraint_Error
(N, "value not in range of}<<", CE_Range_Check_Failed);
@@ -5515,8 +5523,18 @@ package body Sem_Eval is
-- CodePeer mode where the target runtime may have more priorities.
elsif not CodePeer_Mode or else Etype (N) /= RTE (RE_Priority) then
- Apply_Compile_Time_Constraint_Error
- (N, "value not in range of}", CE_Range_Check_Failed);
+ -- Determine if the out of range violation constitutes a warning
+ -- or an error based on context according to RM 4.9 (34/3).
+
+ if Nkind (Original_Node (N)) = N_Type_Conversion
+ and then not Comes_From_Source (Original_Node (N))
+ then
+ Apply_Compile_Time_Constraint_Error
+ (N, "value not in range of}??", CE_Range_Check_Failed);
+ else
+ Apply_Compile_Time_Constraint_Error
+ (N, "value not in range of}", CE_Range_Check_Failed);
+ end if;
end if;
-- Here we generate a warning for the Ada 83 case, or when we are in an
@@ -6013,17 +6031,7 @@ package body Sem_Eval is
-- same base type.
if Has_Discriminants (T1) /= Has_Discriminants (T2) then
- -- A generic actual type is declared through a subtype declaration
- -- and may have an inconsistent indication of the presence of
- -- discriminants, so check the type it renames.
-
- if Is_Generic_Actual_Type (T1)
- and then not Has_Discriminants (Etype (T1))
- and then not Has_Discriminants (T2)
- then
- return True;
-
- elsif In_Instance then
+ if In_Instance then
if Is_Private_Type (T2)
and then Present (Full_View (T2))
and then Has_Discriminants (Full_View (T2))
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 1a2a759..993a419d 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -299,11 +299,20 @@ package body Sem_Prag is
-- pragma. Entity name for unit and its parents is taken from item in
-- previous with_clause that mentions the unit.
- procedure Validate_Compile_Time_Warning_Error (N : Node_Id);
+ procedure Validate_Compile_Time_Warning_Or_Error
+ (N : Node_Id;
+ Eloc : Source_Ptr);
+ -- Common processing for Compile_Time_Error and Compile_Time_Warning of
+ -- pragma N. Called when the pragma is processed as part of its regular
+ -- analysis but also called after calling the back end to validate these
+ -- pragmas for size and alignment appropriateness.
+
+ procedure Defer_Compile_Time_Warning_Error_To_BE (N : Node_Id);
-- N is a pragma Compile_Time_Error or Compile_Warning_Error whose boolean
- -- expression is not known at compile time. This procedure makes an entry
- -- in a table. The actual checking is performed by Validate_Compile_Time_
- -- Warning_Errors, which is invoked after calling the back end.
+ -- expression is not known at compile time during the front end. This
+ -- procedure makes an entry in a table. The actual checking is performed by
+ -- Validate_Compile_Time_Warning_Errors, which is invoked after calling the
+ -- back end.
Dummy : Integer := 0;
pragma Volatile (Dummy);
@@ -323,21 +332,21 @@ package body Sem_Prag is
-- pragma in the source program, a breakpoint on rv catches this place in
-- the source, allowing convenient stepping to the point of interest.
- ---------------------------------------------------
- -- Table for Validate_Compile_Time_Warning_Error --
- ---------------------------------------------------
+ ------------------------------------------------------
+ -- Table for Defer_Compile_Time_Warning_Error_To_BE --
+ ------------------------------------------------------
-- The following table collects pragmas Compile_Time_Error and Compile_
-- Time_Warning for validation. Entries are made by calls to subprogram
- -- Validate_Compile_Time_Warning_Error, and the call to the procedure
+ -- Defer_Compile_Time_Warning_Error_To_BE, and the call to the procedure
-- Validate_Compile_Time_Warning_Errors does the actual error checking
-- and posting of warning and error messages. The reason for this delayed
-- processing is to take advantage of back-annotations of attributes size
-- and alignment values performed by the back end.
-- Note: the reason we store a Source_Ptr value instead of a Node_Id is
- -- that by the time Validate_Unchecked_Conversions is called, Sprint will
- -- already have modified all Sloc values if the -gnatD option is set.
+ -- that by the time Validate_Compile_Time_Warning_Errors is called, Sprint
+ -- will already have modified all Sloc values if the -gnatD option is set.
type CTWE_Entry is record
Eloc : Source_Ptr;
@@ -2064,6 +2073,7 @@ package body Sem_Prag is
(N : Node_Id;
Expr_Val : out Boolean)
is
+ Prag_Id : constant Pragma_Id := Get_Pragma_Id (Pragma_Name (N));
Arg1 : constant Node_Id :=
First (Pragma_Argument_Associations (N));
Obj_Decl : constant Node_Id := Find_Related_Context (N);
@@ -2090,9 +2100,28 @@ package body Sem_Prag is
-- pragma Async_Readers (Obj);
-- pragma Volatile (Obj);
- if not Is_Effectively_Volatile (Obj_Id) then
- SPARK_Msg_N
- ("external property % must apply to a volatile object", N);
+ if Prag_Id /= Pragma_No_Caching
+ and then not Is_Effectively_Volatile (Obj_Id)
+ then
+ if No_Caching_Enabled (Obj_Id) then
+ SPARK_Msg_N
+ ("illegal combination of external property % and property "
+ & """No_Caching"" (SPARK RM 7.1.2(6))", N);
+ else
+ SPARK_Msg_N
+ ("external property % must apply to a volatile object", N);
+ end if;
+
+ -- Pragma No_Caching should only apply to volatile variables of
+ -- a non-effectively volatile type (SPARK RM 7.1.2).
+
+ elsif Prag_Id = Pragma_No_Caching then
+ if Is_Effectively_Volatile (Etype (Obj_Id)) then
+ SPARK_Msg_N ("property % must not apply to an object of "
+ & "an effectively volatile type", N);
+ elsif not Is_Volatile (Obj_Id) then
+ SPARK_Msg_N ("property % must apply to a volatile object", N);
+ end if;
end if;
-- Ensure that the Boolean expression (if present) is static. A missing
@@ -7117,10 +7146,11 @@ package body Sem_Prag is
Item : Node_Id := First (Decls);
begin
- -- Only other pragmas can come before this pragma
+ -- Only other pragmas can come before this pragma, but they might
+ -- have been rewritten so check the original node.
loop
- if No (Item) or else Nkind (Item) /= N_Pragma then
+ if No (Item) or else Nkind (Original_Node (Item)) /= N_Pragma then
return False;
elsif Item = Pragma_Node then
@@ -7578,46 +7608,8 @@ package body Sem_Prag is
-------------------------------------------
procedure Process_Compile_Time_Warning_Or_Error is
- Validation_Needed : Boolean := False;
-
- function Check_Node (N : Node_Id) return Traverse_Result;
- -- Tree visitor that checks if N is an attribute reference that can
- -- be statically computed by the back end. Validation_Needed is set
- -- to True if found.
-
- ----------------
- -- Check_Node --
- ----------------
-
- function Check_Node (N : Node_Id) return Traverse_Result is
- begin
- if Nkind (N) = N_Attribute_Reference
- and then Is_Entity_Name (Prefix (N))
- and then not Is_Generic_Unit (Scope (Entity (Prefix (N))))
- then
- declare
- Attr_Id : constant Attribute_Id :=
- Get_Attribute_Id (Attribute_Name (N));
- begin
- if Attr_Id = Attribute_Alignment
- or else Attr_Id = Attribute_Size
- then
- Validation_Needed := True;
- end if;
- end;
- end if;
-
- return OK;
- end Check_Node;
-
- procedure Check_Expression is new Traverse_Proc (Check_Node);
-
- -- Local variables
-
+ P : Node_Id := Parent (N);
Arg1x : constant Node_Id := Get_Pragma_Arg (Arg1);
-
- -- Start of processing for Process_Compile_Time_Warning_Or_Error
-
begin
-- In GNATprove mode, pragmas Compile_Time_Error and
-- Compile_Time_Warning are ignored, as the analyzer may not have the
@@ -7635,19 +7627,28 @@ package body Sem_Prag is
Check_Arg_Is_OK_Static_Expression (Arg2, Standard_String);
Analyze_And_Resolve (Arg1x, Standard_Boolean);
- if Compile_Time_Known_Value (Arg1x) then
- Process_Compile_Time_Warning_Or_Error (N, Sloc (Arg1));
-
- -- Register the expression for its validation after the back end has
- -- been called if it has occurrences of attributes Size or Alignment
- -- (because they may be statically computed by the back end and hence
- -- the whole expression needs to be reevaluated).
+ -- If the condition is known at compile time (now), validate it now.
+ -- Otherwise, register the expression for validation after the back
+ -- end has been called, because it might be known at compile time
+ -- then. For example, if the expression is "Record_Type'Size /= 32"
+ -- it might be known after the back end has determined the size of
+ -- Record_Type. We do not defer validation if we're inside a generic
+ -- unit, because we will have more information in the instances.
+ if Compile_Time_Known_Value (Arg1x) then
+ Validate_Compile_Time_Warning_Or_Error (N, Sloc (Arg1));
else
- Check_Expression (Arg1x);
+ while Present (P) and then Nkind (P) not in N_Generic_Declaration
+ loop
+ if Nkind_In (P, N_Package_Body, N_Subprogram_Body) then
+ P := Corresponding_Spec (P);
+ else
+ P := Parent (P);
+ end if;
+ end loop;
- if Validation_Needed then
- Validate_Compile_Time_Warning_Error (N);
+ if No (P) then
+ Defer_Compile_Time_Warning_Error_To_BE (N);
end if;
end if;
end Process_Compile_Time_Warning_Or_Error;
@@ -13618,17 +13619,20 @@ package body Sem_Prag is
------------------------------------------------------------------
-- Async_Readers/Async_Writers/Effective_Reads/Effective_Writes --
+ -- No_Caching --
------------------------------------------------------------------
-- pragma Async_Readers [ (boolean_EXPRESSION) ];
-- pragma Async_Writers [ (boolean_EXPRESSION) ];
-- pragma Effective_Reads [ (boolean_EXPRESSION) ];
-- pragma Effective_Writes [ (boolean_EXPRESSION) ];
+ -- pragma No_Caching [ (boolean_EXPRESSION) ];
when Pragma_Async_Readers
| Pragma_Async_Writers
| Pragma_Effective_Reads
| Pragma_Effective_Writes
+ | Pragma_No_Caching
=>
Async_Effective : declare
Obj_Decl : Node_Id;
@@ -14426,25 +14430,17 @@ package body Sem_Prag is
-- Processing for this pragma is shared with Psect_Object
- ------------------------
- -- Compile_Time_Error --
- ------------------------
+ ----------------------------------------------
+ -- Compile_Time_Error, Compile_Time_Warning --
+ ----------------------------------------------
-- pragma Compile_Time_Error
-- (boolean_EXPRESSION, static_string_EXPRESSION);
- when Pragma_Compile_Time_Error =>
- GNAT_Pragma;
- Process_Compile_Time_Warning_Or_Error;
-
- --------------------------
- -- Compile_Time_Warning --
- --------------------------
-
-- pragma Compile_Time_Warning
-- (boolean_EXPRESSION, static_string_EXPRESSION);
- when Pragma_Compile_Time_Warning =>
+ when Pragma_Compile_Time_Error | Pragma_Compile_Time_Warning =>
GNAT_Pragma;
Process_Compile_Time_Warning_Or_Error;
@@ -19549,16 +19545,18 @@ package body Sem_Prag is
end loop;
end Main_Storage;
- ----------------------
- -- Max_Queue_Length --
- ----------------------
+ ----------------------------
+ -- Max_Entry_Queue_Length --
+ ----------------------------
- -- pragma Max_Queue_Length (static_integer_EXPRESSION);
+ -- pragma Max_Entry_Queue_Length (static_integer_EXPRESSION);
- -- This processing is shared by Pragma_Max_Entry_Queue_Depth
+ -- This processing is shared by Pragma_Max_Entry_Queue_Depth and
+ -- Pragma_Max_Queue_Length.
- when Pragma_Max_Queue_Length
+ when Pragma_Max_Entry_Queue_Length
| Pragma_Max_Entry_Queue_Depth
+ | Pragma_Max_Queue_Length
=>
Max_Queue_Length : declare
Arg : Node_Id;
@@ -19567,7 +19565,9 @@ package body Sem_Prag is
Val : Uint;
begin
- if Prag_Id = Pragma_Max_Queue_Length then
+ if Prag_Id = Pragma_Max_Entry_Queue_Depth
+ or else Prag_Id = Pragma_Max_Queue_Length
+ then
GNAT_Pragma;
end if;
@@ -24146,7 +24146,7 @@ package body Sem_Prag is
Error_Pragma_Arg
("argument of pragma% cannot be an incomplete type", Arg1);
else
- Set_Suppress_Initialization (Full_View (Base_Type (E)));
+ Set_Suppress_Initialization (Full_View (E));
end if;
-- For first subtype, set flag on base type
@@ -31036,14 +31036,16 @@ package body Sem_Prag is
Pragma_Main => -1,
Pragma_Main_Storage => -1,
Pragma_Max_Entry_Queue_Depth => 0,
+ Pragma_Max_Entry_Queue_Length => 0,
Pragma_Max_Queue_Length => 0,
Pragma_Memory_Size => 0,
- Pragma_No_Return => 0,
Pragma_No_Body => 0,
+ Pragma_No_Caching => 0,
Pragma_No_Component_Reordering => -1,
Pragma_No_Elaboration_Code_All => 0,
Pragma_No_Heap_Finalization => 0,
Pragma_No_Inline => 0,
+ Pragma_No_Return => 0,
Pragma_No_Run_Time => -1,
Pragma_No_Strict_Aliasing => -1,
Pragma_No_Tagged_Streams => 0,
@@ -31439,11 +31441,11 @@ package body Sem_Prag is
end Process_Compilation_Unit_Pragmas;
- -------------------------------------------
- -- Process_Compile_Time_Warning_Or_Error --
- -------------------------------------------
+ --------------------------------------------
+ -- Validate_Compile_Time_Warning_Or_Error --
+ --------------------------------------------
- procedure Process_Compile_Time_Warning_Or_Error
+ procedure Validate_Compile_Time_Warning_Or_Error
(N : Node_Id;
Eloc : Source_Ptr)
is
@@ -31550,8 +31552,16 @@ package body Sem_Prag is
end loop;
end;
end if;
+
+ -- Arg1x is not known at compile time, so issue a warning. This can
+ -- happen only if the pragma's processing was deferred until after the
+ -- back end is run (see Process_Compile_Time_Warning_Or_Error).
+ -- Note that the warning control switch applies to both pragmas.
+
+ elsif Warn_On_Unknown_Compile_Time_Warning then
+ Error_Msg_N ("?condition is not known at compile time", Arg1x);
end if;
- end Process_Compile_Time_Warning_Or_Error;
+ end Validate_Compile_Time_Warning_Or_Error;
------------------------------------
-- Record_Possible_Body_Reference --
@@ -32114,16 +32124,17 @@ package body Sem_Prag is
end Test_Case_Arg;
-----------------------------------------
- -- Validate_Compile_Time_Warning_Error --
+ -- Defer_Compile_Time_Warning_Error_To_BE --
-----------------------------------------
- procedure Validate_Compile_Time_Warning_Error (N : Node_Id) is
+ procedure Defer_Compile_Time_Warning_Error_To_BE (N : Node_Id) is
+ Arg1 : constant Node_Id := First (Pragma_Argument_Associations (N));
begin
Compile_Time_Warnings_Errors.Append
- (New_Val => CTWE_Entry'(Eloc => Sloc (N),
+ (New_Val => CTWE_Entry'(Eloc => Sloc (Arg1),
Scope => Current_Scope,
Prag => N));
- end Validate_Compile_Time_Warning_Error;
+ end Defer_Compile_Time_Warning_Error_To_BE;
------------------------------------------
-- Validate_Compile_Time_Warning_Errors --
@@ -32177,7 +32188,7 @@ package body Sem_Prag is
begin
Set_Scope (T.Scope);
Reset_Analyzed_Flags (T.Prag);
- Process_Compile_Time_Warning_Or_Error (T.Prag, T.Eloc);
+ Validate_Compile_Time_Warning_Or_Error (T.Prag, T.Eloc);
Unset_Scope (T.Scope);
end;
end loop;
diff --git a/gcc/ada/sem_prag.ads b/gcc/ada/sem_prag.ads
index 25353b7..88c103a 100644
--- a/gcc/ada/sem_prag.ads
+++ b/gcc/ada/sem_prag.ads
@@ -218,8 +218,9 @@ package Sem_Prag is
(N : Node_Id;
Expr_Val : out Boolean);
-- Perform full analysis of delayed pragmas Async_Readers, Async_Writers,
- -- Effective_Reads and Effective_Writes. Flag Expr_Val contains the Boolean
- -- argument of the pragma or a default True if no argument is present.
+ -- Effective_Reads, Effective_Writes and No_Caching. Flag Expr_Val contains
+ -- the Boolean argument of the pragma or a default True if no argument
+ -- is present.
procedure Analyze_Global_In_Decl_Part (N : Node_Id);
-- Perform full analysis of delayed pragma Global. This routine is also
@@ -398,6 +399,7 @@ package Sem_Prag is
-- Global
-- Initializes
-- Max_Entry_Queue_Depth
+ -- Max_Entry_Queue_Length
-- Max_Queue_Length
-- Post
-- Post_Class
@@ -497,14 +499,6 @@ package Sem_Prag is
-- Name_uInvariant, and Name_uType_Invariant (_Pre, _Post, _Invariant,
-- and _Type_Invariant).
- procedure Process_Compile_Time_Warning_Or_Error
- (N : Node_Id;
- Eloc : Source_Ptr);
- -- Common processing for Compile_Time_Error and Compile_Time_Warning of
- -- pragma N. Called when the pragma is processed as part of its regular
- -- analysis but also called after calling the back end to validate these
- -- pragmas for size and alignment appropriateness.
-
procedure Process_Compilation_Unit_Pragmas (N : Node_Id);
-- Called at the start of processing compilation unit N to deal with any
-- special issues regarding pragmas. In particular, we have to deal with
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index b668a51..7a52b90 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -30,9 +30,9 @@ with Debug_A; use Debug_A;
with Einfo; use Einfo;
with Errout; use Errout;
with Expander; use Expander;
-with Exp_Disp; use Exp_Disp;
with Exp_Ch6; use Exp_Ch6;
with Exp_Ch7; use Exp_Ch7;
+with Exp_Disp; use Exp_Disp;
with Exp_Tss; use Exp_Tss;
with Exp_Util; use Exp_Util;
with Freeze; use Freeze;
@@ -51,12 +51,12 @@ with Restrict; use Restrict;
with Rident; use Rident;
with Rtsfind; use Rtsfind;
with Sem; use Sem;
-with Sem_Aux; use Sem_Aux;
with Sem_Aggr; use Sem_Aggr;
with Sem_Attr; use Sem_Attr;
+with Sem_Aux; use Sem_Aux;
with Sem_Cat; use Sem_Cat;
-with Sem_Ch4; use Sem_Ch4;
with Sem_Ch3; use Sem_Ch3;
+with Sem_Ch4; use Sem_Ch4;
with Sem_Ch6; use Sem_Ch6;
with Sem_Ch8; use Sem_Ch8;
with Sem_Ch13; use Sem_Ch13;
@@ -67,9 +67,9 @@ with Sem_Elab; use Sem_Elab;
with Sem_Elim; use Sem_Elim;
with Sem_Eval; use Sem_Eval;
with Sem_Intr; use Sem_Intr;
-with Sem_Util; use Sem_Util;
-with Targparm; use Targparm;
+with Sem_Mech; use Sem_Mech;
with Sem_Type; use Sem_Type;
+with Sem_Util; use Sem_Util;
with Sem_Warn; use Sem_Warn;
with Sinfo; use Sinfo;
with Sinfo.CN; use Sinfo.CN;
@@ -77,6 +77,7 @@ with Snames; use Snames;
with Stand; use Stand;
with Stringt; use Stringt;
with Style; use Style;
+with Targparm; use Targparm;
with Tbuild; use Tbuild;
with Uintp; use Uintp;
with Urealp; use Urealp;
@@ -4517,7 +4518,7 @@ package body Sem_Res is
end if;
end if;
- if Etype (A) = Any_Type then
+ if A_Typ = Any_Type then
Set_Etype (N, Any_Type);
return;
end if;
@@ -4539,18 +4540,10 @@ package body Sem_Res is
-- Apply required constraint checks
- -- Gigi looks at the check flag and uses the appropriate types.
- -- For now since one flag is used there is an optimization
- -- which might not be done in the IN OUT case since Gigi does
- -- not do any analysis. More thought required about this ???
-
- -- In fact is this comment obsolete??? doesn't the expander now
- -- generate all these tests anyway???
-
- if Is_Scalar_Type (Etype (A)) then
+ if Is_Scalar_Type (A_Typ) then
Apply_Scalar_Range_Check (A, F_Typ);
- elsif Is_Array_Type (Etype (A)) then
+ elsif Is_Array_Type (A_Typ) then
Apply_Length_Check (A, F_Typ);
elsif Is_Record_Type (F_Typ)
@@ -4621,12 +4614,22 @@ package body Sem_Res is
if Nkind (A) = N_Type_Conversion then
if Is_Scalar_Type (A_Typ) then
- Apply_Scalar_Range_Check
- (Expression (A), Etype (Expression (A)), A_Typ);
- -- In addition, the returned value of the parameter must
- -- satisfy the bounds of the object type (see comment
- -- below).
+ -- Special case here tailored to Exp_Ch6.Is_Legal_Copy,
+ -- which would prevent the check from being generated.
+ -- This is for Starlet only though, so long obsolete.
+
+ if Mechanism (F) = By_Reference
+ and then Is_Valued_Procedure (Nam)
+ then
+ null;
+ else
+ Apply_Scalar_Range_Check
+ (Expression (A), Etype (Expression (A)), A_Typ);
+ end if;
+
+ -- In addition the return value must meet the constraints
+ -- of the object type (see the comment below).
Apply_Scalar_Range_Check (A, A_Typ, F_Typ);
@@ -4650,6 +4653,7 @@ package body Sem_Res is
and then Ekind (F) = E_Out_Parameter
then
Apply_Length_Check (A, F_Typ);
+
else
Apply_Range_Check (A, A_Typ, F_Typ);
end if;
@@ -6310,13 +6314,15 @@ package body Sem_Res is
-- an expression function may appear when it is part of a default
-- expression in a call to an initialization procedure, and must be
-- frozen now, even if the body is inserted at a later point.
+ -- Otherwise, the call freezes the expression if expander is active,
+ -- for example as part of an object declaration.
if Is_Entity_Name (Subp)
and then not In_Spec_Expression
and then not Is_Expression_Function_Or_Completion (Current_Scope)
and then
(not Is_Expression_Function_Or_Completion (Entity (Subp))
- or else Scope (Entity (Subp)) = Current_Scope)
+ or else Expander_Active)
then
if Is_Expression_Function (Entity (Subp)) then
@@ -6948,9 +6954,7 @@ package body Sem_Res is
-- Check the dimensions of the actuals in the call. For function calls,
-- propagate the dimensions from the returned type to N.
- if not In_Inlined_Body then
- Analyze_Dimension_Call (N, Nam);
- end if;
+ Analyze_Dimension_Call (N, Nam);
-- All done, evaluate call and deal with elaboration issues
@@ -6966,6 +6970,10 @@ package body Sem_Res is
Build_Call_Marker (N);
+ Mark_Use_Clauses (Subp);
+
+ Warn_On_Overlapping_Actuals (Nam, N);
+
-- In GNATprove mode, expansion is disabled, but we want to inline some
-- subprograms to facilitate formal verification. Indirect calls through
-- a subprogram type or within a generic cannot be inlined. Inlining is
@@ -7060,6 +7068,15 @@ package body Sem_Res is
end if;
end if;
+ -- Cannot inline a call inside the definition of a record type,
+ -- typically inside the constraints of the type. Calls in
+ -- default expressions are also not inlined, but this is
+ -- filtered out above when testing In_Default_Expr.
+
+ elsif Is_Record_Type (Current_Scope) then
+ Cannot_Inline
+ ("cannot inline & (inside record type)?", N, Nam_UA);
+
-- With the one-pass inlining technique, a call cannot be
-- inlined if the corresponding body has not been seen yet.
@@ -7105,10 +7122,6 @@ package body Sem_Res is
end if;
end if;
end if;
-
- Mark_Use_Clauses (Subp);
-
- Warn_On_Overlapping_Actuals (Nam, N);
end Resolve_Call;
-----------------------------
@@ -10587,6 +10600,10 @@ package body Sem_Res is
pragma Assert (Found);
Resolve (P, It1.Typ);
+
+ -- In general the expected type is the type of the context, not the
+ -- type of the candidate selected component.
+
Set_Etype (N, Typ);
Set_Entity_With_Checks (S, Comp1);
@@ -10599,6 +10616,17 @@ package body Sem_Res is
if Ekind (Typ) = E_Anonymous_Access_Subprogram_Type then
Set_Etype (N, Etype (Comp1));
+
+ -- When the type of the component is an access to a class-wide type
+ -- the relevant type is that of the component (since in such case we
+ -- may need to generate implicit type conversions or dispatching
+ -- calls).
+
+ elsif Is_Access_Type (Typ)
+ and then not Is_Class_Wide_Type (Designated_Type (Typ))
+ and then Is_Class_Wide_Type (Designated_Type (Etype (Comp1)))
+ then
+ Set_Etype (N, Etype (Comp1));
end if;
else
@@ -11757,6 +11785,8 @@ package body Sem_Res is
and then (Is_Fixed_Point_Type (Operand_Typ)
or else (not GNATprove_Mode
and then Is_Floating_Point_Type (Operand_Typ)))
+ and then not Range_Checks_Suppressed (Target_Typ)
+ and then not Range_Checks_Suppressed (Operand_Typ)
then
Set_Do_Range_Check (Operand);
end if;
diff --git a/gcc/ada/sem_spark.adb b/gcc/ada/sem_spark.adb
index a60a6cb..30e1426 100644
--- a/gcc/ada/sem_spark.adb
+++ b/gcc/ada/sem_spark.adb
@@ -637,6 +637,14 @@ package body Sem_SPARK is
procedure Check_Declaration (Decl : Node_Id);
+ procedure Check_Declaration_Legality
+ (Decl : Node_Id;
+ Force : Boolean;
+ Legal : in out Boolean);
+ -- Check the legality of declaration Decl regarding rules not related to
+ -- permissions. Update Legal to False if a rule is violated. Issue an
+ -- error message if Force is True and Emit_Messages returns True.
+
procedure Check_Expression (Expr : Node_Id; Mode : Extended_Checking_Mode);
pragma Precondition (Nkind_In (Expr, N_Index_Or_Discriminant_Constraint,
N_Range_Constraint,
@@ -663,6 +671,9 @@ package body Sem_SPARK is
procedure Check_Node (N : Node_Id);
-- Main traversal procedure to check safe pointer usage
+ procedure Check_Old_Loop_Entry (N : Node_Id);
+ -- Check SPARK RM 3.10(14) regarding 'Old and 'Loop_Entry
+
procedure Check_Package_Body (Pack : Node_Id);
procedure Check_Package_Spec (Pack : Node_Id);
@@ -683,7 +694,10 @@ package body Sem_SPARK is
procedure Check_Statement (Stmt : Node_Id);
- procedure Check_Type (Typ : Entity_Id);
+ procedure Check_Type_Legality
+ (Typ : Entity_Id;
+ Force : Boolean;
+ Legal : in out Boolean);
-- Check that type Typ is either not deep, or that it is an observing or
-- owning type according to SPARK RM 3.10
@@ -1135,11 +1149,12 @@ package body Sem_SPARK is
Expr_Root : Entity_Id;
Perm : Perm_Kind;
Status : Error_Status;
+ Dummy : Boolean := True;
-- Start of processing for Check_Assignment
begin
- Check_Type (Target_Typ);
+ Check_Type_Legality (Target_Typ, Force => True, Legal => Dummy);
if Is_Anonymous_Access_Type (Target_Typ) then
Check_Source_Of_Borrow_Or_Observe (Expr, Status);
@@ -1407,11 +1422,18 @@ package body Sem_SPARK is
Target : constant Entity_Id := Defining_Identifier (Decl);
Target_Typ : constant Node_Id := Etype (Target);
Expr : Node_Id;
+ Dummy : Boolean := True;
begin
+ -- Start with legality rules not related to permissions
+
+ Check_Declaration_Legality (Decl, Force => True, Legal => Dummy);
+
+ -- Now check permission-related legality rules
+
case N_Declaration'(Nkind (Decl)) is
when N_Full_Type_Declaration =>
- Check_Type (Target);
+ null;
-- ??? What about component declarations with defaults.
@@ -1421,7 +1443,105 @@ package body Sem_SPARK is
when N_Object_Declaration =>
Expr := Expression (Decl);
- Check_Type (Target_Typ);
+ if Present (Expr) then
+ Check_Assignment (Target => Target,
+ Expr => Expr);
+ end if;
+
+ if Is_Deep (Target_Typ) then
+ declare
+ Tree : constant Perm_Tree_Access :=
+ new Perm_Tree_Wrapper'
+ (Tree =>
+ (Kind => Entire_Object,
+ Is_Node_Deep => True,
+ Explanation => Decl,
+ Permission => Read_Write,
+ Children_Permission => Read_Write));
+ begin
+ Set (Current_Perm_Env, Target, Tree);
+ end;
+ end if;
+
+ when N_Iterator_Specification =>
+ null;
+
+ when N_Loop_Parameter_Specification =>
+ null;
+
+ -- Checking should not be called directly on these nodes
+
+ when N_Function_Specification
+ | N_Entry_Declaration
+ | N_Procedure_Specification
+ | N_Component_Declaration
+ =>
+ raise Program_Error;
+
+ -- Ignored constructs for pointer checking
+
+ when N_Formal_Object_Declaration
+ | N_Formal_Type_Declaration
+ | N_Incomplete_Type_Declaration
+ | N_Private_Extension_Declaration
+ | N_Private_Type_Declaration
+ | N_Protected_Type_Declaration
+ =>
+ null;
+
+ -- The following nodes are rewritten by semantic analysis
+
+ when N_Expression_Function =>
+ raise Program_Error;
+ end case;
+ end Check_Declaration;
+
+ --------------------------------
+ -- Check_Declaration_Legality --
+ --------------------------------
+
+ procedure Check_Declaration_Legality
+ (Decl : Node_Id;
+ Force : Boolean;
+ Legal : in out Boolean)
+ is
+ function Original_Emit_Messages return Boolean renames Emit_Messages;
+
+ function Emit_Messages return Boolean;
+ -- Local wrapper around generic formal parameter Emit_Messages, to
+ -- check the value of parameter Force before calling the original
+ -- Emit_Messages, and setting Legal to False.
+
+ -------------------
+ -- Emit_Messages --
+ -------------------
+
+ function Emit_Messages return Boolean is
+ begin
+ Legal := False;
+ return Force and then Original_Emit_Messages;
+ end Emit_Messages;
+
+ -- Local variables
+
+ Target : constant Entity_Id := Defining_Identifier (Decl);
+ Target_Typ : constant Node_Id := Etype (Target);
+ Expr : Node_Id;
+
+ -- Start of processing for Check_Declaration_Legality
+
+ begin
+ case N_Declaration'(Nkind (Decl)) is
+ when N_Full_Type_Declaration =>
+ Check_Type_Legality (Target, Force, Legal);
+
+ when N_Subtype_Declaration =>
+ null;
+
+ when N_Object_Declaration =>
+ Expr := Expression (Decl);
+
+ Check_Type_Legality (Target_Typ, Force, Legal);
-- A declaration of a stand-alone object of an anonymous access
-- type shall have an explicit initial value and shall occur
@@ -1450,26 +1570,6 @@ package body Sem_SPARK is
end if;
end if;
- if Present (Expr) then
- Check_Assignment (Target => Target,
- Expr => Expr);
- end if;
-
- if Is_Deep (Target_Typ) then
- declare
- Tree : constant Perm_Tree_Access :=
- new Perm_Tree_Wrapper'
- (Tree =>
- (Kind => Entire_Object,
- Is_Node_Deep => True,
- Explanation => Decl,
- Permission => Read_Write,
- Children_Permission => Read_Write));
- begin
- Set (Current_Perm_Env, Target, Tree);
- end;
- end if;
-
when N_Iterator_Specification =>
null;
@@ -1501,7 +1601,7 @@ package body Sem_SPARK is
when N_Expression_Function =>
raise Program_Error;
end case;
- end Check_Declaration;
+ end Check_Declaration_Legality;
----------------------
-- Check_Expression --
@@ -2583,6 +2683,43 @@ package body Sem_SPARK is
----------------
procedure Check_Node (N : Node_Id) is
+
+ procedure Check_Subprogram_Contract (N : Node_Id);
+ -- Check the postcondition-like contracts for use of 'Old
+
+ -------------------------------
+ -- Check_Subprogram_Contract --
+ -------------------------------
+
+ procedure Check_Subprogram_Contract (N : Node_Id) is
+ begin
+ if Nkind (N) = N_Subprogram_Declaration
+ or else Acts_As_Spec (N)
+ then
+ declare
+ E : constant Entity_Id := Unique_Defining_Entity (N);
+ Post : constant Node_Id :=
+ Get_Pragma (E, Pragma_Postcondition);
+ Cases : constant Node_Id :=
+ Get_Pragma (E, Pragma_Contract_Cases);
+ begin
+ Check_Old_Loop_Entry (Post);
+ Check_Old_Loop_Entry (Cases);
+ end;
+
+ elsif Nkind (N) = N_Subprogram_Body then
+ declare
+ E : constant Entity_Id := Defining_Entity (N);
+ Ref_Post : constant Node_Id :=
+ Get_Pragma (E, Pragma_Refined_Post);
+ begin
+ Check_Old_Loop_Entry (Ref_Post);
+ end;
+ end if;
+ end Check_Subprogram_Contract;
+
+ -- Start of processing for Check_Node
+
begin
case Nkind (N) is
when N_Declaration =>
@@ -2602,14 +2739,17 @@ package body Sem_SPARK is
Check_Package_Body (N);
end if;
- when N_Subprogram_Body
- | N_Entry_Body
- | N_Task_Body
- =>
+ when N_Subprogram_Body =>
if not Is_Generic_Unit (Unique_Defining_Entity (N)) then
+ Check_Subprogram_Contract (N);
Check_Callable_Body (N);
end if;
+ when N_Entry_Body
+ | N_Task_Body
+ =>
+ Check_Callable_Body (N);
+
when N_Protected_Body =>
Check_List (Declarations (N));
@@ -2622,6 +2762,15 @@ package body Sem_SPARK is
when N_Pragma =>
Check_Pragma (N);
+ when N_Subprogram_Declaration =>
+ Check_Subprogram_Contract (N);
+
+ -- Attribute references in statement position are not supported in
+ -- SPARK and will be rejected by GNATprove.
+
+ when N_Attribute_Reference =>
+ null;
+
-- Ignored constructs for pointer checking
when N_Abstract_Subprogram_Declaration
@@ -2655,7 +2804,6 @@ package body Sem_SPARK is
| N_Procedure_Instantiation
| N_Raise_xxx_Error
| N_Record_Representation_Clause
- | N_Subprogram_Declaration
| N_Subprogram_Renaming_Declaration
| N_Task_Type_Declaration
| N_Use_Package_Clause
@@ -2677,6 +2825,65 @@ package body Sem_SPARK is
end case;
end Check_Node;
+ --------------------------
+ -- Check_Old_Loop_Entry --
+ --------------------------
+
+ procedure Check_Old_Loop_Entry (N : Node_Id) is
+
+ function Check_Attribute (N : Node_Id) return Traverse_Result;
+
+ ---------------------
+ -- Check_Attribute --
+ ---------------------
+
+ function Check_Attribute (N : Node_Id) return Traverse_Result is
+ Attr_Id : Attribute_Id;
+ Aname : Name_Id;
+ Pref : Node_Id;
+
+ begin
+ if Nkind (N) = N_Attribute_Reference then
+ Attr_Id := Get_Attribute_Id (Attribute_Name (N));
+ Aname := Attribute_Name (N);
+
+ if Attr_Id = Attribute_Old
+ or else Attr_Id = Attribute_Loop_Entry
+ then
+ Pref := Prefix (N);
+
+ if Is_Deep (Etype (Pref)) then
+ if Nkind (Pref) /= N_Function_Call then
+ if Emit_Messages then
+ Error_Msg_Name_1 := Aname;
+ Error_Msg_N
+ ("prefix of % attribute must be a function call "
+ & "(SPARK RM 3.10(14))", Pref);
+ end if;
+
+ elsif Is_Traversal_Function_Call (Pref) then
+ if Emit_Messages then
+ Error_Msg_Name_1 := Aname;
+ Error_Msg_N
+ ("prefix of % attribute should not call a traversal "
+ & "function (SPARK RM 3.10(14))", Pref);
+ end if;
+ end if;
+ end if;
+ end if;
+ end if;
+
+ return OK;
+ end Check_Attribute;
+
+ procedure Check_All is new Traverse_Proc (Check_Attribute);
+
+ -- Start of processing for Check_Old_Loop_Entry
+
+ begin
+ Check_All (N);
+ end Check_Old_Loop_Entry;
+
------------------------
-- Check_Package_Body --
------------------------
@@ -2869,8 +3076,18 @@ package body Sem_SPARK is
Expr : constant Node_Id := Expression (Arg2);
begin
Check_Expression (Expr, Read);
+
+ -- Prefix of Loop_Entry should be checked inside any assertion
+ -- where it may appear.
+
+ Check_Old_Loop_Entry (Expr);
end;
+ -- Prefix of Loop_Entry should be checked inside a Loop_Variant
+
+ when Pragma_Loop_Variant =>
+ Check_Old_Loop_Entry (Prag);
+
-- There is no need to check contracts, as these can only access
-- inputs and outputs of the subprogram. Inputs are checked
-- independently for R permission. Outputs are checked
@@ -2963,6 +3180,7 @@ package body Sem_SPARK is
when N_Package_Body
| N_Package_Declaration
+ | N_Subprogram_Declaration
| N_Subprogram_Body
=>
declare
@@ -3388,13 +3606,38 @@ package body Sem_SPARK is
end case;
end Check_Statement;
- ----------------
- -- Check_Type --
- ----------------
+ -------------------------
+ -- Check_Type_Legality --
+ -------------------------
+
+ procedure Check_Type_Legality
+ (Typ : Entity_Id;
+ Force : Boolean;
+ Legal : in out Boolean)
+ is
+ function Original_Emit_Messages return Boolean renames Emit_Messages;
+
+ function Emit_Messages return Boolean;
+ -- Local wrapper around generic formal parameter Emit_Messages, to
+ -- check the value of parameter Force before calling the original
+ -- Emit_Messages, and setting Legal to False.
+
+ -------------------
+ -- Emit_Messages --
+ -------------------
+
+ function Emit_Messages return Boolean is
+ begin
+ Legal := False;
+ return Force and then Original_Emit_Messages;
+ end Emit_Messages;
+
+ -- Local variables
- procedure Check_Type (Typ : Entity_Id) is
Check_Typ : constant Entity_Id := Retysp (Typ);
+ -- Start of processing for Check_Type_Legality
+
begin
case Type_Kind'(Ekind (Check_Typ)) is
when Access_Kind =>
@@ -3404,7 +3647,7 @@ package body Sem_SPARK is
=>
null;
when E_Access_Subtype =>
- Check_Type (Base_Type (Check_Typ));
+ Check_Type_Legality (Base_Type (Check_Typ), Force, Legal);
when E_Access_Attribute_Type =>
if Emit_Messages then
Error_Msg_N ("access attribute not allowed in SPARK",
@@ -3431,7 +3674,7 @@ package body Sem_SPARK is
when E_Array_Type
| E_Array_Subtype
=>
- Check_Type (Component_Type (Check_Typ));
+ Check_Type_Legality (Component_Type (Check_Typ), Force, Legal);
when Record_Kind =>
if Is_Deep (Check_Typ)
@@ -3454,7 +3697,7 @@ package body Sem_SPARK is
-- Ignore components which are not visible in SPARK
if Component_Is_Visible_In_SPARK (Comp) then
- Check_Type (Etype (Comp));
+ Check_Type_Legality (Etype (Comp), Force, Legal);
end if;
Next_Component_Or_Discriminant (Comp);
end loop;
@@ -3480,7 +3723,7 @@ package body Sem_SPARK is
=>
null;
end case;
- end Check_Type;
+ end Check_Type_Legality;
--------------
-- Get_Expl --
@@ -4026,6 +4269,24 @@ package body Sem_SPARK is
end case;
end Is_Deep;
+ --------------
+ -- Is_Legal --
+ --------------
+
+ function Is_Legal (N : Node_Id) return Boolean is
+ Legal : Boolean := True;
+
+ begin
+ case Nkind (N) is
+ when N_Declaration =>
+ Check_Declaration_Legality (N, Force => False, Legal => Legal);
+ when others =>
+ null;
+ end case;
+
+ return Legal;
+ end Is_Legal;
+
----------------------
-- Is_Local_Context --
----------------------
@@ -4266,6 +4527,12 @@ package body Sem_SPARK is
is
begin
return Is_Path_Expression (Expr, Is_Traversal)
+
+ or else (Nkind_In (Expr, N_Qualified_Expression,
+ N_Type_Conversion,
+ N_Unchecked_Type_Conversion)
+ and then Is_Subpath_Expression (Expression (Expr)))
+
or else (Nkind (Expr) = N_Attribute_Reference
and then
(Get_Attribute_Id (Attribute_Name (Expr)) =
@@ -4276,7 +4543,8 @@ package body Sem_SPARK is
or else
Get_Attribute_Id (Attribute_Name (Expr)) =
Attribute_Image))
- or else Nkind (Expr) = N_Op_Concat;
+
+ or else Nkind (Expr) = N_Op_Concat;
end Is_Subpath_Expression;
---------------------------
@@ -4740,13 +5008,49 @@ package body Sem_SPARK is
Get_First_Key (Current_Borrowers);
Var : Entity_Id;
Borrowed : Node_Id;
+ B_Pledge : Entity_Id := Empty;
begin
+ -- Search for a call to a pledge function or a global pragma in
+ -- the parents of Expr.
+
+ declare
+ Call : Node_Id := Expr;
+ begin
+ while Present (Call)
+ and then
+ (Nkind (Call) /= N_Function_Call
+ or else not Is_Pledge_Function (Get_Called_Entity (Call)))
+ loop
+ -- Do not check for borrowed objects in global contracts
+ -- ??? However we should keep these objects in the borrowed
+ -- state when verifying the subprogram so that we can make
+ -- sure that they are only read inside pledges.
+ -- ??? There is probably a better way to disable checking of
+ -- borrows inside global contracts.
+
+ if Nkind (Call) = N_Pragma
+ and then Get_Pragma_Id (Pragma_Name (Call)) = Pragma_Global
+ then
+ return;
+ end if;
+
+ Call := Parent (Call);
+ end loop;
+
+ if Present (Call)
+ and then Nkind (First_Actual (Call)) in N_Has_Entity
+ then
+ B_Pledge := Entity (First_Actual (Call));
+ end if;
+ end;
+
while Key.Present loop
Var := Key.K;
Borrowed := Get (Current_Borrowers, Var);
if Is_Prefix_Or_Almost (Pref => Borrowed, Expr => Expr)
+ and then Var /= B_Pledge
and then Emit_Messages
then
Error_Msg_Sloc := Sloc (Borrowed);
diff --git a/gcc/ada/sem_spark.ads b/gcc/ada/sem_spark.ads
index 195e833..0aaa115 100644
--- a/gcc/ada/sem_spark.ads
+++ b/gcc/ada/sem_spark.ads
@@ -150,8 +150,17 @@ generic
with function Emit_Messages return Boolean;
-- Return True when error messages should be emitted.
+ with function Is_Pledge_Function (E : Entity_Id) return Boolean;
+ -- Return True if E is annotated with a pledge annotation
+
package Sem_SPARK is
+ function Is_Legal (N : Node_Id) return Boolean;
+ -- Test the legality of a node wrt ownership-checking rules. This does not
+ -- check rules related to the validity of permissions associated with paths
+ -- from objects, so that it can be called from GNATprove on code of library
+ -- units analyzed in SPARK_Mode Auto.
+
procedure Check_Safe_Pointers (N : Node_Id);
-- The entry point of this package. It analyzes a node and reports errors
-- when there are violations of ownership rules.
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index f18eb0f..dcef852 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -26,7 +26,6 @@
with Treepr; -- ???For debugging code below
with Aspects; use Aspects;
-with Atree; use Atree;
with Casing; use Casing;
with Checks; use Checks;
with Debug; use Debug;
@@ -5359,11 +5358,12 @@ package body Sem_Util is
-----------------------------------
function Compile_Time_Constraint_Error
- (N : Node_Id;
- Msg : String;
- Ent : Entity_Id := Empty;
- Loc : Source_Ptr := No_Location;
- Warn : Boolean := False) return Node_Id
+ (N : Node_Id;
+ Msg : String;
+ Ent : Entity_Id := Empty;
+ Loc : Source_Ptr := No_Location;
+ Warn : Boolean := False;
+ Extra_Msg : String := "") return Node_Id
is
Msgc : String (1 .. Msg'Length + 3);
-- Copy of message, with room for possible ?? or << and ! at end
@@ -5457,6 +5457,12 @@ package body Sem_Util is
Error_Msg_NEL (Msgc (1 .. Msgl), N, Etype (N), Eloc);
end if;
+ -- Emit any extra message as a continuation
+
+ if Extra_Msg /= "" then
+ Error_Msg_N ('\' & Extra_Msg, N);
+ end if;
+
if Wmsg then
-- Check whether the context is an Init_Proc
@@ -14606,8 +14612,11 @@ package body Sem_Util is
-- Otherwise Id denotes an object
else
+ -- A volatile object for which No_Caching is enabled is not
+ -- effectively volatile.
+
return
- Is_Volatile (Id)
+ (Is_Volatile (Id) and then not No_Caching_Enabled (Id))
or else Has_Volatile_Components (Id)
or else Is_Effectively_Volatile (Etype (Id));
end if;
@@ -14667,6 +14676,7 @@ package body Sem_Util is
return
Nkind (E) = N_Function_Call
and then not Configurable_Run_Time_Mode
+ and then Nkind (Original_Node (E)) = N_Attribute_Reference
and then (Entity (Name (E)) = RTE (RE_Get_Ceiling)
or else Entity (Name (E)) = RTE (RO_PE_Get_Ceiling));
end Is_Expanded_Priority_Attribute;
@@ -20424,6 +20434,21 @@ package body Sem_Util is
Update_First_Real_Statement
(Old_HSS => N,
New_HSS => Result);
+
+ -- Update the Chars attribute of identifiers
+
+ elsif Nkind (N) = N_Identifier then
+
+ -- The Entity field of identifiers that denote aspects is used
+ -- to store arbitrary expressions (and hence we must check that
+ -- they reference an actual entity before copying their Chars
+ -- value).
+
+ if Present (Entity (Result))
+ and then Nkind (Entity (Result)) in N_Entity
+ then
+ Set_Chars (Result, Chars (Entity (Result)));
+ end if;
end if;
end if;
@@ -20796,16 +20821,27 @@ package body Sem_Util is
-- this restriction leads to a performance penalty.
-- ??? this list is flaky, and may hide dormant bugs
+ -- Should functions be included???
+
+ -- Loop parameters appear within quantified expressions and contain
+ -- an entity declaration that must be replaced when the expander is
+ -- active if the expression has been preanalyzed or analyzed.
elsif not Ekind_In (Id, E_Block,
E_Constant,
E_Label,
+ E_Loop_Parameter,
E_Procedure,
E_Variable)
and then not Is_Type (Id)
then
return;
+ elsif Ekind (Id) = E_Loop_Parameter
+ and then No (Etype (Condition (Parent (Parent (Id)))))
+ then
+ return;
+
-- Nothing to do when the entity was already visited
elsif NCT_Tables_In_Use
@@ -21078,7 +21114,14 @@ package body Sem_Util is
begin
pragma Assert (Nkind (N) not in N_Entity);
- if Nkind (N) = N_Expression_With_Actions then
+ -- If the node is a quantified expression and expander is active,
+ -- it contains an implicit declaration that may require a new entity
+ -- when the condition has already been (pre)analyzed.
+
+ if Nkind (N) = N_Expression_With_Actions
+ or else
+ (Nkind (N) = N_Quantified_Expression and then Expander_Active)
+ then
EWA_Level := EWA_Level + 1;
elsif EWA_Level > 0
@@ -21222,6 +21265,12 @@ package body Sem_Util is
-- * Semantic fields of nodes such as First_Real_Statement must be
-- updated to reference the proper replicated nodes.
+ -- Finally, quantified expressions contain an implicit delaration for
+ -- the bound variable. Given that quantified expressions appearing
+ -- in contracts are copied to create pragmas and eventually checking
+ -- procedures, a new bound variable must be created for each copy, to
+ -- prevent multiple declarations of the same symbol.
+
-- To meet all these demands, routine New_Copy_Tree is split into two
-- phases.
@@ -21653,6 +21702,38 @@ package body Sem_Util is
end if;
end New_Requires_Transient_Scope;
+ ------------------------
+ -- No_Caching_Enabled --
+ ------------------------
+
+ function No_Caching_Enabled (Id : Entity_Id) return Boolean is
+ Prag : constant Node_Id := Get_Pragma (Id, Pragma_No_Caching);
+ Arg1 : Node_Id;
+
+ begin
+ if Present (Prag) then
+ Arg1 := First (Pragma_Argument_Associations (Prag));
+
+ -- The pragma has an optional Boolean expression, the related
+ -- property is enabled only when the expression evaluates to True.
+
+ if Present (Arg1) then
+ return Is_True (Expr_Value (Get_Pragma_Arg (Arg1)));
+
+ -- Otherwise the lack of expression enables the property by
+ -- default.
+
+ else
+ return True;
+ end if;
+
+ -- The property was never set in the first place
+
+ else
+ return False;
+ end if;
+ end No_Caching_Enabled;
+
--------------------------
-- No_Heap_Finalization --
--------------------------
@@ -25437,6 +25518,210 @@ package body Sem_Util is
end if;
end Transfer_Entities;
+ ------------------------
+ -- Traverse_More_Func --
+ ------------------------
+
+ function Traverse_More_Func (Node : Node_Id) return Traverse_Final_Result is
+
+ Processing_Itype : Boolean := False;
+ -- Set to True while traversing the nodes under an Itype, to prevent
+ -- looping on Itype handling during that traversal.
+
+ function Process_More (N : Node_Id) return Traverse_Result;
+ -- Wrapper over the Process callback to handle parts of the AST that
+ -- are not normally traversed as syntactic children.
+
+ function Traverse_Rec (N : Node_Id) return Traverse_Final_Result;
+ -- Main recursive traversal implemented as an instantiation of
+ -- Traverse_Func over a modified Process callback.
+
+ ------------------
+ -- Process_More --
+ ------------------
+
+ function Process_More (N : Node_Id) return Traverse_Result is
+
+ procedure Traverse_More (N : Node_Id;
+ Res : in out Traverse_Result);
+ procedure Traverse_More (L : List_Id;
+ Res : in out Traverse_Result);
+ -- Traverse a node or list and update the traversal result to value
+ -- Abandon when needed.
+
+ -------------------
+ -- Traverse_More --
+ -------------------
+
+ procedure Traverse_More (N : Node_Id;
+ Res : in out Traverse_Result)
+ is
+ begin
+ -- Do not process any more nodes if Abandon was reached
+
+ if Res = Abandon then
+ return;
+ end if;
+
+ if Traverse_Rec (N) = Abandon then
+ Res := Abandon;
+ end if;
+ end Traverse_More;
+
+ procedure Traverse_More (L : List_Id;
+ Res : in out Traverse_Result)
+ is
+ N : Node_Id := First (L);
+
+ begin
+ -- Do not process any more nodes if Abandon was reached
+
+ if Res = Abandon then
+ return;
+ end if;
+
+ while Present (N) loop
+ Traverse_More (N, Res);
+ Next (N);
+ end loop;
+ end Traverse_More;
+
+ -- Local variables
+
+ Node : Node_Id;
+ Result : Traverse_Result;
+
+ -- Start of processing for Process_More
+
+ begin
+ -- Initial callback to Process. Return immediately on Skip/Abandon.
+ -- Otherwise update the value of Node for further processing of
+ -- non-syntactic children.
+
+ Result := Process (N);
+
+ case Result is
+ when OK => Node := N;
+ when OK_Orig => Node := Original_Node (N);
+ when Skip => return Skip;
+ when Abandon => return Abandon;
+ end case;
+
+ -- Process the relevant semantic children which are a logical part of
+ -- the AST under this node before returning for the processing of
+ -- syntactic children.
+
+ -- Start with all non-syntactic lists of action nodes
+
+ case Nkind (Node) is
+ when N_Component_Association =>
+ Traverse_More (Loop_Actions (Node), Result);
+
+ when N_Elsif_Part =>
+ Traverse_More (Condition_Actions (Node), Result);
+
+ when N_Short_Circuit =>
+ Traverse_More (Actions (Node), Result);
+
+ when N_Case_Expression_Alternative =>
+ Traverse_More (Actions (Node), Result);
+
+ when N_Iterated_Component_Association =>
+ Traverse_More (Loop_Actions (Node), Result);
+
+ when N_Iteration_Scheme =>
+ Traverse_More (Condition_Actions (Node), Result);
+
+ when N_If_Expression =>
+ Traverse_More (Then_Actions (Node), Result);
+ Traverse_More (Else_Actions (Node), Result);
+
+ -- Various nodes have a field Actions as a syntactic node,
+ -- so it will be traversed in the regular syntactic traversal.
+
+ when N_Compilation_Unit_Aux
+ | N_Compound_Statement
+ | N_Expression_With_Actions
+ | N_Freeze_Entity
+ =>
+ null;
+
+ when others =>
+ null;
+ end case;
+
+ -- If Process_Itypes is True, process unattached nodes which come
+ -- from Itypes. This only concerns currently ranges of scalar
+ -- (possibly as index) types. This traversal is protected against
+ -- looping with Processing_Itype.
+
+ if Process_Itypes
+ and then not Processing_Itype
+ and then Nkind (Node) in N_Has_Etype
+ and then Present (Etype (Node))
+ and then Is_Itype (Etype (Node))
+ then
+ declare
+ Typ : constant Entity_Id := Etype (Node);
+ begin
+ Processing_Itype := True;
+
+ case Ekind (Typ) is
+ when Scalar_Kind =>
+ Traverse_More (Scalar_Range (Typ), Result);
+
+ when Array_Kind =>
+ declare
+ Index : Node_Id := First_Index (Typ);
+ Rng : Node_Id;
+ begin
+ while Present (Index) loop
+ if Nkind (Index) in N_Has_Entity then
+ Rng := Scalar_Range (Entity (Index));
+ else
+ Rng := Index;
+ end if;
+
+ Traverse_More (Rng, Result);
+ Next_Index (Index);
+ end loop;
+ end;
+ when others =>
+ null;
+ end case;
+
+ Processing_Itype := False;
+ end;
+ end if;
+
+ return Result;
+ end Process_More;
+
+ -- Define Traverse_Rec as a renaming of the instantiation, as an
+ -- instantiation cannot complete a previous spec.
+
+ function Traverse_Recursive is new Traverse_Func (Process_More);
+ function Traverse_Rec (N : Node_Id) return Traverse_Final_Result
+ renames Traverse_Recursive;
+
+ -- Start of processing for Traverse_More_Func
+
+ begin
+ return Traverse_Rec (Node);
+ end Traverse_More_Func;
+
+ ------------------------
+ -- Traverse_More_Proc --
+ ------------------------
+
+ procedure Traverse_More_Proc (Node : Node_Id) is
+ function Traverse is new Traverse_More_Func (Process, Process_Itypes);
+ Discard : Traverse_Final_Result;
+ pragma Warnings (Off, Discard);
+ begin
+ Discard := Traverse (Node);
+ end Traverse_More_Proc;
+
-----------------------
-- Type_Access_Level --
-----------------------
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index 35ef111..4d738da 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -25,6 +25,7 @@
-- Package containing utility procedures used throughout the semantics
+with Atree; use Atree;
with Einfo; use Einfo;
with Exp_Tss; use Exp_Tss;
with Namet; use Namet;
@@ -464,16 +465,20 @@ package Sem_Util is
-- the type itself.
function Compile_Time_Constraint_Error
- (N : Node_Id;
- Msg : String;
- Ent : Entity_Id := Empty;
- Loc : Source_Ptr := No_Location;
- Warn : Boolean := False) return Node_Id;
+ (N : Node_Id;
+ Msg : String;
+ Ent : Entity_Id := Empty;
+ Loc : Source_Ptr := No_Location;
+ Warn : Boolean := False;
+ Extra_Msg : String := "") return Node_Id;
-- This is similar to Apply_Compile_Time_Constraint_Error in that it
-- generates a warning (or error) message in the same manner, but it does
-- not replace any nodes. For convenience, the function always returns its
-- first argument. The message is a warning if the message ends with ?, or
-- we are operating in Ada 83 mode, or the Warn parameter is set to True.
+ -- If Extra_Msg is not a null string, then it's associated with N and
+ -- emitted immediately after the main message (and before output of any
+ -- message indicating that Constraint_Error will be raised).
procedure Conditional_Delay (New_Ent, Old_Ent : Entity_Id);
-- Sets the Has_Delayed_Freeze flag of New_Ent if the Delayed_Freeze flag
@@ -1681,7 +1686,7 @@ package Sem_Util is
function Is_Effectively_Volatile (Id : Entity_Id) return Boolean;
-- Determine whether a type or object denoted by entity Id is effectively
-- volatile (SPARK RM 7.1.2). To qualify as such, the entity must be either
- -- * Volatile
+ -- * Volatile without No_Caching
-- * An array type subject to aspect Volatile_Components
-- * An array type whose component type is effectively volatile
-- * A protected type
@@ -2386,6 +2391,11 @@ package Sem_Util is
-- and possibly Next_Global a number of times. Returns the next global item
-- with the same mode.
+ function No_Caching_Enabled (Id : Entity_Id) return Boolean;
+ -- Given the entity of a variable, determine whether Id is subject to
+ -- volatility property No_Caching and if it is, the related expression
+ -- evaluates to True.
+
function No_Heap_Finalization (Typ : Entity_Id) return Boolean;
-- Determine whether type Typ is subject to pragma No_Heap_Finalization
@@ -2811,6 +2821,25 @@ package Sem_Util is
-- Move a list of entities from one scope to another, and recompute
-- Is_Public based upon the new scope.
+ generic
+ with function Process (N : Node_Id) return Traverse_Result is <>;
+ Process_Itypes : Boolean := False;
+ function Traverse_More_Func (Node : Node_Id) return Traverse_Final_Result;
+ -- This is a version of Atree.Traverse_Func that not only traverses
+ -- syntactic children of nodes, but also semantic children which are
+ -- logically children of the node. This concerns currently lists of
+ -- action nodes and ranges under Itypes, both inserted by the compiler.
+ -- Itypes are only traversed when Process_Itypes is True.
+
+ generic
+ with function Process (N : Node_Id) return Traverse_Result is <>;
+ Process_Itypes : Boolean := False;
+ procedure Traverse_More_Proc (Node : Node_Id);
+ pragma Inline (Traverse_More_Proc);
+ -- This is the same as Traverse_More_Func except that no result is
+ -- returned, i.e. Traverse_More_Func is called and the result is simply
+ -- discarded.
+
function Type_Access_Level (Typ : Entity_Id) return Uint;
-- Return the accessibility level of Typ
diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb
index ab85162..8f85057 100644
--- a/gcc/ada/sem_warn.adb
+++ b/gcc/ada/sem_warn.adb
@@ -818,6 +818,14 @@ package body Sem_Warn is
-- For an entry formal entity from an entry declaration, find the
-- corresponding body formal from the given accept statement.
+ function Generic_Body_Formal (E : Entity_Id) return Entity_Id;
+ -- Warnings on unused formals of subprograms are placed on the entity
+ -- in the subprogram body, which seems preferable because it suggests
+ -- a better codefix for GPS. The analysis of generic subprogram bodies
+ -- uses a different circuitry, so the choice for the proper placement
+ -- of the warning in the generic case takes place here, by finding the
+ -- body entity that corresponds to a formal in a spec.
+
procedure May_Need_Initialized_Actual (Ent : Entity_Id);
-- If an entity of a generic type has default initialization, then the
-- corresponding actual type should be fully initialized, or else there
@@ -876,6 +884,35 @@ package body Sem_Warn is
raise Program_Error;
end Body_Formal;
+ -------------------------
+ -- Generic_Body_Formal --
+ -------------------------
+
+ function Generic_Body_Formal (E : Entity_Id) return Entity_Id is
+ Gen_Decl : constant Node_Id := Unit_Declaration_Node (Scope (E));
+ Gen_Body : constant Entity_Id := Corresponding_Body (Gen_Decl);
+ Form : Entity_Id;
+
+ begin
+ if No (Gen_Body) then
+ return E;
+
+ else
+ Form := First_Entity (Gen_Body);
+ while Present (Form) loop
+ if Chars (Form) = Chars (E) then
+ return Form;
+ end if;
+
+ Next_Entity (Form);
+ end loop;
+ end if;
+
+ -- Should never fall through, should always find a match
+
+ raise Program_Error;
+ end Generic_Body_Formal;
+
---------------------------------
-- May_Need_Initialized_Actual --
---------------------------------
@@ -1688,7 +1725,15 @@ package body Sem_Warn is
elsif not Warnings_Off_E1
and then not Has_Junk_Name (E1)
then
- Unreferenced_Entities.Append (E1);
+ if Is_Formal (E1)
+ and then Nkind (Unit_Declaration_Node (Scope (E1)))
+ = N_Generic_Subprogram_Declaration
+ then
+ Unreferenced_Entities.Append
+ (Generic_Body_Formal (E1));
+ else
+ Unreferenced_Entities.Append (E1);
+ end if;
end if;
end if;
@@ -4362,11 +4407,31 @@ package body Sem_Warn is
E := Body_E;
end if;
- if not Is_Trivial_Subprogram (Scope (E)) then
- Error_Msg_NE -- CODEFIX
- ("?u?formal parameter & is not referenced!",
- E, Spec_E);
- end if;
+ declare
+ B : constant Node_Id := Parent (Parent (Scope (E)));
+ S : Entity_Id := Empty;
+ begin
+ if Nkind_In (B,
+ N_Expression_Function,
+ N_Subprogram_Body,
+ N_Subprogram_Renaming_Declaration)
+ then
+ S := Corresponding_Spec (B);
+ end if;
+
+ -- Do not warn for dispatching operations, because
+ -- that causes too much noise. Also do not warn for
+ -- trivial subprograms.
+
+ if (not Present (S)
+ or else not Is_Dispatching_Operation (S))
+ and then not Is_Trivial_Subprogram (Scope (E))
+ then
+ Error_Msg_NE -- CODEFIX
+ ("?u?formal parameter & is not referenced!",
+ E, Spec_E);
+ end if;
+ end;
end if;
end if;
diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads
index 064147e..e3f7fd3 100644
--- a/gcc/ada/sinfo.ads
+++ b/gcc/ada/sinfo.ads
@@ -11959,7 +11959,7 @@ package Sinfo is
N_Iterated_Component_Association =>
(1 => True, -- Defining_Identifier (Node1)
- 2 => False, -- unused
+ 2 => True, -- Loop_Actions (List2-Sem)
3 => True, -- Expression (Node3)
4 => True, -- Discrete_Choices (List4)
5 => False), -- unused
diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl
index 2715310..d7507a2 100644
--- a/gcc/ada/snames.ads-tmpl
+++ b/gcc/ada/snames.ads-tmpl
@@ -592,10 +592,12 @@ package Snames is
Name_Machine_Attribute : constant Name_Id := N + $; -- GNAT
Name_Main : constant Name_Id := N + $; -- GNAT
Name_Main_Storage : constant Name_Id := N + $; -- GNAT
- Name_Max_Entry_Queue_Depth : constant Name_Id := N + $; -- Ada 12
+ Name_Max_Entry_Queue_Depth : constant Name_Id := N + $; -- GNAT
+ Name_Max_Entry_Queue_Length : constant Name_Id := N + $; -- Ada 12
Name_Max_Queue_Length : constant Name_Id := N + $; -- GNAT
Name_Memory_Size : constant Name_Id := N + $; -- Ada 83
Name_No_Body : constant Name_Id := N + $; -- GNAT
+ Name_No_Caching : constant Name_Id := N + $; -- GNAT
Name_No_Elaboration_Code_All : constant Name_Id := N + $; -- GNAT
Name_No_Inline : constant Name_Id := N + $; -- GNAT
Name_No_Return : constant Name_Id := N + $; -- Ada 05
@@ -781,7 +783,6 @@ package Snames is
Name_Link_Name : constant Name_Id := N + $;
Name_Low_Order_First : constant Name_Id := N + $;
Name_Lowercase : constant Name_Id := N + $;
- Name_Max_Entry_Queue_Length : constant Name_Id := N + $;
Name_Max_Size : constant Name_Id := N + $;
Name_Mechanism : constant Name_Id := N + $;
Name_Message : constant Name_Id := N + $;
@@ -2006,9 +2007,11 @@ package Snames is
Pragma_Main,
Pragma_Main_Storage,
Pragma_Max_Entry_Queue_Depth,
+ Pragma_Max_Entry_Queue_Length,
Pragma_Max_Queue_Length,
Pragma_Memory_Size,
Pragma_No_Body,
+ Pragma_No_Caching,
Pragma_No_Elaboration_Code_All,
Pragma_No_Inline,
Pragma_No_Return,
diff --git a/gcc/ada/socket.c b/gcc/ada/socket.c
index 8fc8415..94538d4 100644
--- a/gcc/ada/socket.c
+++ b/gcc/ada/socket.c
@@ -704,12 +704,6 @@ __gnat_servent_s_proto (struct servent * s)
#if defined(AF_INET6) && !defined(__rtems__)
-#if defined (__vxworks)
-#define getaddrinfo ipcom_getaddrinfo
-#define getnameinfo ipcom_getnameinfo
-#define freeaddrinfo ipcom_freeaddrinfo
-#endif
-
int __gnat_getaddrinfo(
const char *node,
const char *service,
diff --git a/gcc/ada/sprint.ads b/gcc/ada/sprint.ads
index 11a552f..c510ac6 100644
--- a/gcc/ada/sprint.ads
+++ b/gcc/ada/sprint.ads
@@ -48,8 +48,8 @@ package Sprint is
-- Allocator new xxx [storage_pool = xxx]
-- Cleanup action at end procedure name;
- -- Conversion wi Float_Truncate target^(source)
-- Convert wi Conversion_OK target?(source)
+ -- Convert wi Float_Truncate target^(source)
-- Convert wi Rounded_Result target@(source)
-- Divide wi Treat_Fixed_As_Integer x #/ y
-- Divide wi Rounded_Result x @/ y
diff --git a/gcc/ada/table.adb b/gcc/ada/table.adb
index ebbb857..9794047 100644
--- a/gcc/ada/table.adb
+++ b/gcc/ada/table.adb
@@ -80,6 +80,7 @@ package body Table is
procedure Append (New_Val : Table_Component_Type) is
begin
+ pragma Assert (not Locked);
Set_Item (Table_Index_Type (Last_Val + 1), New_Val);
end Append;
@@ -120,6 +121,7 @@ package body Table is
procedure Increment_Last is
begin
+ pragma Assert (not Locked);
Last_Val := Last_Val + 1;
if Last_Val > Max then
@@ -384,6 +386,8 @@ package body Table is
procedure Set_Last (New_Val : Table_Index_Type) is
begin
+ pragma Assert (Int (New_Val) <= Last_Val or else not Locked);
+
if Int (New_Val) < Last_Val then
Last_Val := Int (New_Val);
diff --git a/gcc/ada/table.ads b/gcc/ada/table.ads
index a816c73..5f03cf3 100644
--- a/gcc/ada/table.ads
+++ b/gcc/ada/table.ads
@@ -130,14 +130,15 @@ package Table is
-- First .. Last.
Locked : Boolean := False;
- -- Table expansion is permitted only if this switch is set to False. A
- -- client may set Locked to True, in which case any attempt to expand
- -- the table will cause an assertion failure. Note that while a table
- -- is locked, its address in memory remains fixed and unchanging. This
- -- feature is used to control table expansion during Gigi processing.
- -- Gigi assumes that tables other than the Uint and Ureal tables do
- -- not move during processing, which means that they cannot be expanded.
- -- The Locked flag is used to enforce this restriction.
+ -- Increasing the value of Last is permitted only if this switch is set
+ -- to False. A client may set Locked to True, in which case any attempt
+ -- to increase the value of Last (which might expand the table) will
+ -- cause an assertion failure. Note that while a table is locked, its
+ -- address in memory remains fixed and unchanging. This feature is used
+ -- to control table expansion during Gigi processing. Gigi assumes that
+ -- tables other than the Uint and Ureal tables do not move during
+ -- processing, which means that they cannot be expanded. The Locked
+ -- flag is used to enforce this restriction.
procedure Init;
-- This procedure allocates a new table of size Initial (freeing any
diff --git a/gcc/ada/warnsw.adb b/gcc/ada/warnsw.adb
index 219d440..a731907 100644
--- a/gcc/ada/warnsw.adb
+++ b/gcc/ada/warnsw.adb
@@ -43,53 +43,54 @@ package body Warnsw is
procedure All_Warnings (Setting : Boolean) is
begin
- Address_Clause_Overlay_Warnings := Setting;
- Check_Unreferenced := Setting;
- Check_Unreferenced_Formals := Setting;
- Check_Withs := Setting;
- Constant_Condition_Warnings := Setting;
- Elab_Warnings := Setting;
- Implementation_Unit_Warnings := Setting;
- Ineffective_Inline_Warnings := Setting;
- List_Body_Required_Info := Setting;
- List_Inherited_Aspects := Setting;
- Warn_On_Ada_2005_Compatibility := Setting;
- Warn_On_Ada_2012_Compatibility := Setting;
- Warn_On_All_Unread_Out_Parameters := Setting;
- Warn_On_Anonymous_Allocators := Setting;
- Warn_On_Assertion_Failure := Setting;
- Warn_On_Assumed_Low_Bound := Setting;
- Warn_On_Atomic_Synchronization := Setting;
- Warn_On_Bad_Fixed_Value := Setting;
- Warn_On_Biased_Representation := Setting;
- Warn_On_Constant := Setting;
- Warn_On_Deleted_Code := Setting;
- Warn_On_Dereference := Setting;
- Warn_On_Export_Import := Setting;
- Warn_On_Hiding := Setting;
- Warn_On_Late_Primitives := Setting;
- Warn_On_Modified_Unread := Setting;
- Warn_On_No_Value_Assigned := Setting;
- Warn_On_Non_Local_Exception := Setting;
- Warn_On_Object_Renames_Function := Setting;
- Warn_On_Obsolescent_Feature := Setting;
- Warn_On_Overlap := Setting;
- Warn_On_Overridden_Size := Setting;
- Warn_On_Parameter_Order := Setting;
- Warn_On_Questionable_Layout := Setting;
- Warn_On_Questionable_Missing_Parens := Setting;
- Warn_On_Record_Holes := Setting;
- Warn_On_Redundant_Constructs := Setting;
- Warn_On_Reverse_Bit_Order := Setting;
- Warn_On_Size_Alignment := Setting;
- Warn_On_Standard_Redefinition := Setting;
- Warn_On_Suspicious_Contract := Setting;
- Warn_On_Suspicious_Modulus_Value := Setting;
- Warn_On_Unchecked_Conversion := Setting;
- Warn_On_Unordered_Enumeration_Type := Setting;
- Warn_On_Unrecognized_Pragma := Setting;
- Warn_On_Unrepped_Components := Setting;
- Warn_On_Warnings_Off := Setting;
+ Address_Clause_Overlay_Warnings := Setting;
+ Check_Unreferenced := Setting;
+ Check_Unreferenced_Formals := Setting;
+ Check_Withs := Setting;
+ Constant_Condition_Warnings := Setting;
+ Elab_Warnings := Setting;
+ Implementation_Unit_Warnings := Setting;
+ Ineffective_Inline_Warnings := Setting;
+ List_Body_Required_Info := Setting;
+ List_Inherited_Aspects := Setting;
+ Warn_On_Ada_2005_Compatibility := Setting;
+ Warn_On_Ada_2012_Compatibility := Setting;
+ Warn_On_All_Unread_Out_Parameters := Setting;
+ Warn_On_Anonymous_Allocators := Setting;
+ Warn_On_Assertion_Failure := Setting;
+ Warn_On_Assumed_Low_Bound := Setting;
+ Warn_On_Atomic_Synchronization := Setting;
+ Warn_On_Bad_Fixed_Value := Setting;
+ Warn_On_Biased_Representation := Setting;
+ Warn_On_Constant := Setting;
+ Warn_On_Deleted_Code := Setting;
+ Warn_On_Dereference := Setting;
+ Warn_On_Export_Import := Setting;
+ Warn_On_Hiding := Setting;
+ Warn_On_Late_Primitives := Setting;
+ Warn_On_Modified_Unread := Setting;
+ Warn_On_No_Value_Assigned := Setting;
+ Warn_On_Non_Local_Exception := Setting;
+ Warn_On_Object_Renames_Function := Setting;
+ Warn_On_Obsolescent_Feature := Setting;
+ Warn_On_Overlap := Setting;
+ Warn_On_Overridden_Size := Setting;
+ Warn_On_Parameter_Order := Setting;
+ Warn_On_Questionable_Layout := Setting;
+ Warn_On_Questionable_Missing_Parens := Setting;
+ Warn_On_Record_Holes := Setting;
+ Warn_On_Redundant_Constructs := Setting;
+ Warn_On_Reverse_Bit_Order := Setting;
+ Warn_On_Size_Alignment := Setting;
+ Warn_On_Standard_Redefinition := Setting;
+ Warn_On_Suspicious_Contract := Setting;
+ Warn_On_Suspicious_Modulus_Value := Setting;
+ Warn_On_Unchecked_Conversion := Setting;
+ Warn_On_Unknown_Compile_Time_Warning := Setting;
+ Warn_On_Unordered_Enumeration_Type := Setting;
+ Warn_On_Unrecognized_Pragma := Setting;
+ Warn_On_Unrepped_Components := Setting;
+ Warn_On_Warnings_Off := Setting;
end All_Warnings;
----------------------
@@ -98,103 +99,105 @@ package body Warnsw is
procedure Restore_Warnings (W : Warning_Record) is
begin
- Address_Clause_Overlay_Warnings :=
+ Address_Clause_Overlay_Warnings :=
W.Address_Clause_Overlay_Warnings;
- Check_Unreferenced :=
+ Check_Unreferenced :=
W.Check_Unreferenced;
- Check_Unreferenced_Formals :=
+ Check_Unreferenced_Formals :=
W.Check_Unreferenced_Formals;
- Check_Withs :=
+ Check_Withs :=
W.Check_Withs;
- Constant_Condition_Warnings :=
+ Constant_Condition_Warnings :=
W.Constant_Condition_Warnings;
- Elab_Warnings :=
+ Elab_Warnings :=
W.Elab_Warnings;
- Elab_Info_Messages :=
+ Elab_Info_Messages :=
W.Elab_Info_Messages;
- Implementation_Unit_Warnings :=
+ Implementation_Unit_Warnings :=
W.Implementation_Unit_Warnings;
- Ineffective_Inline_Warnings :=
+ Ineffective_Inline_Warnings :=
W.Ineffective_Inline_Warnings;
- List_Body_Required_Info :=
+ List_Body_Required_Info :=
W.List_Body_Required_Info;
- List_Inherited_Aspects :=
+ List_Inherited_Aspects :=
W.List_Inherited_Aspects;
- No_Warn_On_Non_Local_Exception :=
+ No_Warn_On_Non_Local_Exception :=
W.No_Warn_On_Non_Local_Exception;
- Warning_Doc_Switch :=
+ Warning_Doc_Switch :=
W.Warning_Doc_Switch;
- Warn_On_Ada_2005_Compatibility :=
+ Warn_On_Ada_2005_Compatibility :=
W.Warn_On_Ada_2005_Compatibility;
- Warn_On_Ada_2012_Compatibility :=
+ Warn_On_Ada_2012_Compatibility :=
W.Warn_On_Ada_2012_Compatibility;
- Warn_On_All_Unread_Out_Parameters :=
+ Warn_On_All_Unread_Out_Parameters :=
W.Warn_On_All_Unread_Out_Parameters;
- Warn_On_Anonymous_Allocators :=
+ Warn_On_Anonymous_Allocators :=
W.Warn_On_Anonymous_Allocators;
- Warn_On_Assertion_Failure :=
+ Warn_On_Assertion_Failure :=
W.Warn_On_Assertion_Failure;
- Warn_On_Assumed_Low_Bound :=
+ Warn_On_Assumed_Low_Bound :=
W.Warn_On_Assumed_Low_Bound;
- Warn_On_Atomic_Synchronization :=
+ Warn_On_Atomic_Synchronization :=
W.Warn_On_Atomic_Synchronization;
- Warn_On_Bad_Fixed_Value :=
+ Warn_On_Bad_Fixed_Value :=
W.Warn_On_Bad_Fixed_Value;
- Warn_On_Biased_Representation :=
+ Warn_On_Biased_Representation :=
W.Warn_On_Biased_Representation;
- Warn_On_Constant :=
+ Warn_On_Constant :=
W.Warn_On_Constant;
- Warn_On_Deleted_Code :=
+ Warn_On_Deleted_Code :=
W.Warn_On_Deleted_Code;
- Warn_On_Dereference :=
+ Warn_On_Dereference :=
W.Warn_On_Dereference;
- Warn_On_Export_Import :=
+ Warn_On_Export_Import :=
W.Warn_On_Export_Import;
- Warn_On_Hiding :=
+ Warn_On_Hiding :=
W.Warn_On_Hiding;
- Warn_On_Late_Primitives :=
+ Warn_On_Late_Primitives :=
W.Warn_On_Late_Primitives;
- Warn_On_Modified_Unread :=
+ Warn_On_Modified_Unread :=
W.Warn_On_Modified_Unread;
- Warn_On_No_Value_Assigned :=
+ Warn_On_No_Value_Assigned :=
W.Warn_On_No_Value_Assigned;
- Warn_On_Non_Local_Exception :=
+ Warn_On_Non_Local_Exception :=
W.Warn_On_Non_Local_Exception;
- Warn_On_Object_Renames_Function :=
+ Warn_On_Object_Renames_Function :=
W.Warn_On_Object_Renames_Function;
- Warn_On_Obsolescent_Feature :=
+ Warn_On_Obsolescent_Feature :=
W.Warn_On_Obsolescent_Feature;
- Warn_On_Overlap :=
+ Warn_On_Overlap :=
W.Warn_On_Overlap;
- Warn_On_Overridden_Size :=
+ Warn_On_Overridden_Size :=
W.Warn_On_Overridden_Size;
- Warn_On_Parameter_Order :=
+ Warn_On_Parameter_Order :=
W.Warn_On_Parameter_Order;
- Warn_On_Questionable_Layout :=
+ Warn_On_Questionable_Layout :=
W.Warn_On_Questionable_Layout;
- Warn_On_Questionable_Missing_Parens :=
+ Warn_On_Questionable_Missing_Parens :=
W.Warn_On_Questionable_Missing_Parens;
- Warn_On_Record_Holes :=
+ Warn_On_Record_Holes :=
W.Warn_On_Record_Holes;
- Warn_On_Redundant_Constructs :=
+ Warn_On_Redundant_Constructs :=
W.Warn_On_Redundant_Constructs;
- Warn_On_Reverse_Bit_Order :=
+ Warn_On_Reverse_Bit_Order :=
W.Warn_On_Reverse_Bit_Order;
- Warn_On_Size_Alignment :=
+ Warn_On_Size_Alignment :=
W.Warn_On_Size_Alignment;
- Warn_On_Standard_Redefinition :=
+ Warn_On_Standard_Redefinition :=
W.Warn_On_Standard_Redefinition;
- Warn_On_Suspicious_Contract :=
+ Warn_On_Suspicious_Contract :=
W.Warn_On_Suspicious_Contract;
- Warn_On_Unchecked_Conversion :=
+ Warn_On_Unchecked_Conversion :=
W.Warn_On_Unchecked_Conversion;
- Warn_On_Unordered_Enumeration_Type :=
+ Warn_On_Unknown_Compile_Time_Warning :=
+ W.Warn_On_Unknown_Compile_Time_Warning;
+ Warn_On_Unordered_Enumeration_Type :=
W.Warn_On_Unordered_Enumeration_Type;
- Warn_On_Unrecognized_Pragma :=
+ Warn_On_Unrecognized_Pragma :=
W.Warn_On_Unrecognized_Pragma;
- Warn_On_Unrepped_Components :=
+ Warn_On_Unrepped_Components :=
W.Warn_On_Unrepped_Components;
- Warn_On_Warnings_Off :=
+ Warn_On_Warnings_Off :=
W.Warn_On_Warnings_Off;
end Restore_Warnings;
@@ -206,103 +209,105 @@ package body Warnsw is
W : Warning_Record;
begin
- W.Address_Clause_Overlay_Warnings :=
+ W.Address_Clause_Overlay_Warnings :=
Address_Clause_Overlay_Warnings;
- W.Check_Unreferenced :=
+ W.Check_Unreferenced :=
Check_Unreferenced;
- W.Check_Unreferenced_Formals :=
+ W.Check_Unreferenced_Formals :=
Check_Unreferenced_Formals;
- W.Check_Withs :=
+ W.Check_Withs :=
Check_Withs;
- W.Constant_Condition_Warnings :=
+ W.Constant_Condition_Warnings :=
Constant_Condition_Warnings;
- W.Elab_Info_Messages :=
+ W.Elab_Info_Messages :=
Elab_Info_Messages;
- W.Elab_Warnings :=
+ W.Elab_Warnings :=
Elab_Warnings;
- W.Implementation_Unit_Warnings :=
+ W.Implementation_Unit_Warnings :=
Implementation_Unit_Warnings;
- W.Ineffective_Inline_Warnings :=
+ W.Ineffective_Inline_Warnings :=
Ineffective_Inline_Warnings;
- W.List_Body_Required_Info :=
+ W.List_Body_Required_Info :=
List_Body_Required_Info;
- W.List_Inherited_Aspects :=
+ W.List_Inherited_Aspects :=
List_Inherited_Aspects;
- W.No_Warn_On_Non_Local_Exception :=
+ W.No_Warn_On_Non_Local_Exception :=
No_Warn_On_Non_Local_Exception;
- W.Warning_Doc_Switch :=
+ W.Warning_Doc_Switch :=
Warning_Doc_Switch;
- W.Warn_On_Ada_2005_Compatibility :=
+ W.Warn_On_Ada_2005_Compatibility :=
Warn_On_Ada_2005_Compatibility;
- W.Warn_On_Ada_2012_Compatibility :=
+ W.Warn_On_Ada_2012_Compatibility :=
Warn_On_Ada_2012_Compatibility;
- W.Warn_On_All_Unread_Out_Parameters :=
+ W.Warn_On_All_Unread_Out_Parameters :=
Warn_On_All_Unread_Out_Parameters;
- W.Warn_On_Anonymous_Allocators :=
+ W.Warn_On_Anonymous_Allocators :=
Warn_On_Anonymous_Allocators;
- W.Warn_On_Assertion_Failure :=
+ W.Warn_On_Assertion_Failure :=
Warn_On_Assertion_Failure;
- W.Warn_On_Assumed_Low_Bound :=
+ W.Warn_On_Assumed_Low_Bound :=
Warn_On_Assumed_Low_Bound;
- W.Warn_On_Atomic_Synchronization :=
+ W.Warn_On_Atomic_Synchronization :=
Warn_On_Atomic_Synchronization;
- W.Warn_On_Bad_Fixed_Value :=
+ W.Warn_On_Bad_Fixed_Value :=
Warn_On_Bad_Fixed_Value;
- W.Warn_On_Biased_Representation :=
+ W.Warn_On_Biased_Representation :=
Warn_On_Biased_Representation;
- W.Warn_On_Constant :=
+ W.Warn_On_Constant :=
Warn_On_Constant;
- W.Warn_On_Deleted_Code :=
+ W.Warn_On_Deleted_Code :=
Warn_On_Deleted_Code;
- W.Warn_On_Dereference :=
+ W.Warn_On_Dereference :=
Warn_On_Dereference;
- W.Warn_On_Export_Import :=
+ W.Warn_On_Export_Import :=
Warn_On_Export_Import;
- W.Warn_On_Hiding :=
+ W.Warn_On_Hiding :=
Warn_On_Hiding;
- W.Warn_On_Late_Primitives :=
+ W.Warn_On_Late_Primitives :=
Warn_On_Late_Primitives;
- W.Warn_On_Modified_Unread :=
+ W.Warn_On_Modified_Unread :=
Warn_On_Modified_Unread;
- W.Warn_On_No_Value_Assigned :=
+ W.Warn_On_No_Value_Assigned :=
Warn_On_No_Value_Assigned;
- W.Warn_On_Non_Local_Exception :=
+ W.Warn_On_Non_Local_Exception :=
Warn_On_Non_Local_Exception;
- W.Warn_On_Object_Renames_Function :=
+ W.Warn_On_Object_Renames_Function :=
Warn_On_Object_Renames_Function;
- W.Warn_On_Obsolescent_Feature :=
+ W.Warn_On_Obsolescent_Feature :=
Warn_On_Obsolescent_Feature;
- W.Warn_On_Overlap :=
+ W.Warn_On_Overlap :=
Warn_On_Overlap;
- W.Warn_On_Overridden_Size :=
+ W.Warn_On_Overridden_Size :=
Warn_On_Overridden_Size;
- W.Warn_On_Parameter_Order :=
+ W.Warn_On_Parameter_Order :=
Warn_On_Parameter_Order;
- W.Warn_On_Questionable_Layout :=
+ W.Warn_On_Questionable_Layout :=
Warn_On_Questionable_Layout;
- W.Warn_On_Questionable_Missing_Parens :=
+ W.Warn_On_Questionable_Missing_Parens :=
Warn_On_Questionable_Missing_Parens;
- W.Warn_On_Record_Holes :=
+ W.Warn_On_Record_Holes :=
Warn_On_Record_Holes;
- W.Warn_On_Redundant_Constructs :=
+ W.Warn_On_Redundant_Constructs :=
Warn_On_Redundant_Constructs;
- W.Warn_On_Reverse_Bit_Order :=
+ W.Warn_On_Reverse_Bit_Order :=
Warn_On_Reverse_Bit_Order;
- W.Warn_On_Size_Alignment :=
+ W.Warn_On_Size_Alignment :=
Warn_On_Size_Alignment;
- W.Warn_On_Standard_Redefinition :=
+ W.Warn_On_Standard_Redefinition :=
Warn_On_Standard_Redefinition;
- W.Warn_On_Suspicious_Contract :=
+ W.Warn_On_Suspicious_Contract :=
Warn_On_Suspicious_Contract;
- W.Warn_On_Unchecked_Conversion :=
+ W.Warn_On_Unchecked_Conversion :=
Warn_On_Unchecked_Conversion;
- W.Warn_On_Unordered_Enumeration_Type :=
+ W.Warn_On_Unknown_Compile_Time_Warning :=
+ Warn_On_Unknown_Compile_Time_Warning;
+ W.Warn_On_Unordered_Enumeration_Type :=
Warn_On_Unordered_Enumeration_Type;
- W.Warn_On_Unrecognized_Pragma :=
+ W.Warn_On_Unrecognized_Pragma :=
Warn_On_Unrecognized_Pragma;
- W.Warn_On_Unrepped_Components :=
+ W.Warn_On_Unrepped_Components :=
Warn_On_Unrepped_Components;
- W.Warn_On_Warnings_Off :=
+ W.Warn_On_Warnings_Off :=
Warn_On_Warnings_Off;
return W;
end Save_Warnings;
@@ -489,6 +494,12 @@ package body Warnsw is
when 'A' =>
Warn_On_Anonymous_Allocators := False;
+ when 'c' =>
+ Warn_On_Unknown_Compile_Time_Warning := True;
+
+ when 'C' =>
+ Warn_On_Unknown_Compile_Time_Warning := False;
+
when others =>
if Ignore_Unrecognized_VWY_Switches then
Write_Line ("unrecognized switch -gnatw_" & C & " ignored");
diff --git a/gcc/ada/warnsw.ads b/gcc/ada/warnsw.ads
index 422f8df..f96c11c 100644
--- a/gcc/ada/warnsw.ads
+++ b/gcc/ada/warnsw.ads
@@ -48,6 +48,10 @@ package Warnsw is
-- Warn when tagged type public primitives are defined after its private
-- extensions.
+ Warn_On_Unknown_Compile_Time_Warning : Boolean := True;
+ -- Warn on a pragma Compile_Time_Warning or Compile_Time_Error whose
+ -- condition has a value that is not known at compile time.
+
Warn_On_Overridden_Size : Boolean := False;
-- Warn when explicit record component clause or array component_size
-- clause specifies a size that overrides a size for the type which was
@@ -80,56 +84,57 @@ package Warnsw is
-- Type used to save and restore warnings
type Warning_Record is record
- Address_Clause_Overlay_Warnings : Boolean;
- Check_Unreferenced : Boolean;
- Check_Unreferenced_Formals : Boolean;
- Check_Withs : Boolean;
- Constant_Condition_Warnings : Boolean;
- Elab_Info_Messages : Boolean;
- Elab_Warnings : Boolean;
- Implementation_Unit_Warnings : Boolean;
- Ineffective_Inline_Warnings : Boolean;
- List_Body_Required_Info : Boolean;
- List_Inherited_Aspects : Boolean;
- No_Warn_On_Non_Local_Exception : Boolean;
- Warning_Doc_Switch : Boolean;
- Warn_On_Ada_2005_Compatibility : Boolean;
- Warn_On_Ada_2012_Compatibility : Boolean;
- Warn_On_All_Unread_Out_Parameters : Boolean;
- Warn_On_Anonymous_Allocators : Boolean;
- Warn_On_Assertion_Failure : Boolean;
- Warn_On_Assumed_Low_Bound : Boolean;
- Warn_On_Atomic_Synchronization : Boolean;
- Warn_On_Bad_Fixed_Value : Boolean;
- Warn_On_Biased_Representation : Boolean;
- Warn_On_Constant : Boolean;
- Warn_On_Deleted_Code : Boolean;
- Warn_On_Dereference : Boolean;
- Warn_On_Export_Import : Boolean;
- Warn_On_Hiding : Boolean;
- Warn_On_Late_Primitives : Boolean;
- Warn_On_Modified_Unread : Boolean;
- Warn_On_No_Value_Assigned : Boolean;
- Warn_On_Non_Local_Exception : Boolean;
- Warn_On_Object_Renames_Function : Boolean;
- Warn_On_Obsolescent_Feature : Boolean;
- Warn_On_Overlap : Boolean;
- Warn_On_Overridden_Size : Boolean;
- Warn_On_Parameter_Order : Boolean;
- Warn_On_Questionable_Layout : Boolean;
- Warn_On_Questionable_Missing_Parens : Boolean;
- Warn_On_Record_Holes : Boolean;
- Warn_On_Redundant_Constructs : Boolean;
- Warn_On_Reverse_Bit_Order : Boolean;
- Warn_On_Size_Alignment : Boolean;
- Warn_On_Standard_Redefinition : Boolean;
- Warn_On_Suspicious_Contract : Boolean;
- Warn_On_Suspicious_Modulus_Value : Boolean;
- Warn_On_Unchecked_Conversion : Boolean;
- Warn_On_Unordered_Enumeration_Type : Boolean;
- Warn_On_Unrecognized_Pragma : Boolean;
- Warn_On_Unrepped_Components : Boolean;
- Warn_On_Warnings_Off : Boolean;
+ Address_Clause_Overlay_Warnings : Boolean;
+ Check_Unreferenced : Boolean;
+ Check_Unreferenced_Formals : Boolean;
+ Check_Withs : Boolean;
+ Constant_Condition_Warnings : Boolean;
+ Elab_Info_Messages : Boolean;
+ Elab_Warnings : Boolean;
+ Implementation_Unit_Warnings : Boolean;
+ Ineffective_Inline_Warnings : Boolean;
+ List_Body_Required_Info : Boolean;
+ List_Inherited_Aspects : Boolean;
+ No_Warn_On_Non_Local_Exception : Boolean;
+ Warning_Doc_Switch : Boolean;
+ Warn_On_Ada_2005_Compatibility : Boolean;
+ Warn_On_Ada_2012_Compatibility : Boolean;
+ Warn_On_All_Unread_Out_Parameters : Boolean;
+ Warn_On_Anonymous_Allocators : Boolean;
+ Warn_On_Assertion_Failure : Boolean;
+ Warn_On_Assumed_Low_Bound : Boolean;
+ Warn_On_Atomic_Synchronization : Boolean;
+ Warn_On_Bad_Fixed_Value : Boolean;
+ Warn_On_Biased_Representation : Boolean;
+ Warn_On_Constant : Boolean;
+ Warn_On_Deleted_Code : Boolean;
+ Warn_On_Dereference : Boolean;
+ Warn_On_Export_Import : Boolean;
+ Warn_On_Hiding : Boolean;
+ Warn_On_Late_Primitives : Boolean;
+ Warn_On_Modified_Unread : Boolean;
+ Warn_On_No_Value_Assigned : Boolean;
+ Warn_On_Non_Local_Exception : Boolean;
+ Warn_On_Object_Renames_Function : Boolean;
+ Warn_On_Obsolescent_Feature : Boolean;
+ Warn_On_Overlap : Boolean;
+ Warn_On_Overridden_Size : Boolean;
+ Warn_On_Parameter_Order : Boolean;
+ Warn_On_Questionable_Layout : Boolean;
+ Warn_On_Questionable_Missing_Parens : Boolean;
+ Warn_On_Record_Holes : Boolean;
+ Warn_On_Redundant_Constructs : Boolean;
+ Warn_On_Reverse_Bit_Order : Boolean;
+ Warn_On_Size_Alignment : Boolean;
+ Warn_On_Standard_Redefinition : Boolean;
+ Warn_On_Suspicious_Contract : Boolean;
+ Warn_On_Suspicious_Modulus_Value : Boolean;
+ Warn_On_Unchecked_Conversion : Boolean;
+ Warn_On_Unknown_Compile_Time_Warning : Boolean;
+ Warn_On_Unordered_Enumeration_Type : Boolean;
+ Warn_On_Unrecognized_Pragma : Boolean;
+ Warn_On_Unrepped_Components : Boolean;
+ Warn_On_Warnings_Off : Boolean;
end record;
function Save_Warnings return Warning_Record;
diff --git a/gcc/alias.c b/gcc/alias.c
index 2755df7..1579dfa 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -793,8 +793,16 @@ alias_ptr_types_compatible_p (tree t1, tree t2)
|| ref_all_alias_ptr_type_p (t2))
return false;
- return (TYPE_MAIN_VARIANT (TREE_TYPE (t1))
- == TYPE_MAIN_VARIANT (TREE_TYPE (t2)));
+ /* This function originally abstracts from simply comparing
+ get_deref_alias_set so that we are sure this still computes
+ the same result after LTO type merging is applied.
+ When in LTO type merging is done we can actually do this compare.
+ */
+ if (in_lto_p)
+ return get_deref_alias_set (t1) == get_deref_alias_set (t2);
+ else
+ return (TYPE_MAIN_VARIANT (TREE_TYPE (t1))
+ == TYPE_MAIN_VARIANT (TREE_TYPE (t2)));
}
/* Create emptry alias set entry. */
diff --git a/gcc/attribs.c b/gcc/attribs.c
index f4777c6..b89be58 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -691,6 +691,7 @@ decl_attributes (tree *node, tree attributes, int flags,
if (!built_in
|| !DECL_P (*anode)
+ || DECL_BUILT_IN_CLASS (*anode) != BUILT_IN_NORMAL
|| (DECL_FUNCTION_CODE (*anode) != BUILT_IN_UNREACHABLE
&& (DECL_FUNCTION_CODE (*anode)
!= BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE)))
diff --git a/gcc/bitmap.c b/gcc/bitmap.c
index c99d646..ce68a62 100644
--- a/gcc/bitmap.c
+++ b/gcc/bitmap.c
@@ -267,7 +267,8 @@ bitmap_list_link_element (bitmap head, bitmap_element *element)
and return it to the freelist. */
static inline void
-bitmap_list_unlink_element (bitmap head, bitmap_element *element)
+bitmap_list_unlink_element (bitmap head, bitmap_element *element,
+ bool to_freelist = true)
{
bitmap_element *next = element->next;
bitmap_element *prev = element->prev;
@@ -294,18 +295,21 @@ bitmap_list_unlink_element (bitmap head, bitmap_element *element)
head->indx = 0;
}
- bitmap_elem_to_freelist (head, element);
+ if (to_freelist)
+ bitmap_elem_to_freelist (head, element);
}
-/* Insert a new uninitialized element into bitmap HEAD after element
- ELT. If ELT is NULL, insert the element at the start. Return the
- new element. */
+/* Insert a new uninitialized element (or NODE if not NULL) into bitmap
+ HEAD after element ELT. If ELT is NULL, insert the element at the start.
+ Return the new element. */
static bitmap_element *
bitmap_list_insert_element_after (bitmap head,
- bitmap_element *elt, unsigned int indx)
+ bitmap_element *elt, unsigned int indx,
+ bitmap_element *node = NULL)
{
- bitmap_element *node = bitmap_element_allocate (head);
+ if (!node)
+ node = bitmap_element_allocate (head);
node->indx = indx;
gcc_checking_assert (!head->tree_form);
@@ -2026,6 +2030,56 @@ bitmap_ior_into (bitmap a, const_bitmap b)
return changed;
}
+/* A |= B. Return true if A changes. Free B (re-using its storage
+ for the result). */
+
+bool
+bitmap_ior_into_and_free (bitmap a, bitmap *b_)
+{
+ bitmap b = *b_;
+ bitmap_element *a_elt = a->first;
+ bitmap_element *b_elt = b->first;
+ bitmap_element *a_prev = NULL;
+ bitmap_element **a_prev_pnext = &a->first;
+ bool changed = false;
+
+ gcc_checking_assert (!a->tree_form && !b->tree_form);
+ gcc_assert (a->obstack == b->obstack);
+ if (a == b)
+ return false;
+
+ while (b_elt)
+ {
+ /* If A lags behind B, just advance it. */
+ if (!a_elt || a_elt->indx == b_elt->indx)
+ {
+ changed = bitmap_elt_ior (a, a_elt, a_prev, a_elt, b_elt, changed);
+ b_elt = b_elt->next;
+ }
+ else if (a_elt->indx > b_elt->indx)
+ {
+ bitmap_element *b_elt_next = b_elt->next;
+ bitmap_list_unlink_element (b, b_elt, false);
+ bitmap_list_insert_element_after (a, a_prev, b_elt->indx, b_elt);
+ b_elt = b_elt_next;
+ }
+
+ a_prev = *a_prev_pnext;
+ a_prev_pnext = &a_prev->next;
+ a_elt = *a_prev_pnext;
+ }
+
+ gcc_checking_assert (!a->current == !a->first);
+ if (a->current)
+ a->indx = a->current->indx;
+
+ if (b->obstack)
+ BITMAP_FREE (*b_);
+ else
+ bitmap_clear (b);
+ return changed;
+}
+
/* DST = A ^ B */
void
@@ -2367,16 +2421,75 @@ bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b, const_bitmap k
bool
bitmap_ior_and_compl_into (bitmap a, const_bitmap b, const_bitmap c)
{
- bitmap_head tmp;
- bool changed;
+ bitmap_element *a_elt = a->first;
+ const bitmap_element *b_elt = b->first;
+ const bitmap_element *c_elt = c->first;
+ bitmap_element and_elt;
+ bitmap_element *a_prev = NULL;
+ bitmap_element **a_prev_pnext = &a->first;
+ bool changed = false;
+ unsigned ix;
gcc_checking_assert (!a->tree_form && !b->tree_form && !c->tree_form);
- bitmap_initialize (&tmp, &bitmap_default_obstack);
- bitmap_and_compl (&tmp, b, c);
- changed = bitmap_ior_into (a, &tmp);
- bitmap_clear (&tmp);
+ if (a == b)
+ return false;
+ if (bitmap_empty_p (c))
+ return bitmap_ior_into (a, b);
+ else if (bitmap_empty_p (a))
+ return bitmap_and_compl (a, b, c);
+
+ and_elt.indx = -1;
+ while (b_elt)
+ {
+ /* Advance C. */
+ while (c_elt && c_elt->indx < b_elt->indx)
+ c_elt = c_elt->next;
+ const bitmap_element *and_elt_ptr;
+ if (c_elt && c_elt->indx == b_elt->indx)
+ {
+ BITMAP_WORD overall = 0;
+ and_elt_ptr = &and_elt;
+ and_elt.indx = b_elt->indx;
+ for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
+ {
+ and_elt.bits[ix] = b_elt->bits[ix] & ~c_elt->bits[ix];
+ overall |= and_elt.bits[ix];
+ }
+ if (!overall)
+ {
+ b_elt = b_elt->next;
+ continue;
+ }
+ }
+ else
+ and_elt_ptr = b_elt;
+
+ b_elt = b_elt->next;
+
+ /* Now find a place to insert AND_ELT. */
+ do
+ {
+ ix = a_elt ? a_elt->indx : and_elt_ptr->indx;
+ if (ix == and_elt_ptr->indx)
+ changed = bitmap_elt_ior (a, a_elt, a_prev, a_elt,
+ and_elt_ptr, changed);
+ else if (ix > and_elt_ptr->indx)
+ changed = bitmap_elt_copy (a, NULL, a_prev, and_elt_ptr, changed);
+
+ a_prev = *a_prev_pnext;
+ a_prev_pnext = &a_prev->next;
+ a_elt = *a_prev_pnext;
+
+ /* If A lagged behind B/C, we advanced it so loop once more. */
+ }
+ while (ix < and_elt_ptr->indx);
+ }
+
+ gcc_checking_assert (!a->current == !a->first);
+ if (a->current)
+ a->indx = a->current->indx;
return changed;
}
diff --git a/gcc/bitmap.h b/gcc/bitmap.h
index b0ca7b9..5e080af 100644
--- a/gcc/bitmap.h
+++ b/gcc/bitmap.h
@@ -415,6 +415,7 @@ extern void bitmap_clear_range (bitmap, unsigned int, unsigned int);
extern void bitmap_set_range (bitmap, unsigned int, unsigned int);
extern bool bitmap_ior (bitmap, const_bitmap, const_bitmap);
extern bool bitmap_ior_into (bitmap, const_bitmap);
+extern bool bitmap_ior_into_and_free (bitmap, bitmap *);
extern void bitmap_xor (bitmap, const_bitmap, const_bitmap);
extern void bitmap_xor_into (bitmap, const_bitmap);
diff --git a/gcc/brig/ChangeLog b/gcc/brig/ChangeLog
index 1fdc0f1..a5c3b9b 100644
--- a/gcc/brig/ChangeLog
+++ b/gcc/brig/ChangeLog
@@ -1,11 +1,16 @@
+2019-06-25 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * brig-lang.c (brig_build_c_type_nodes): Accept "__intN__"
+ format of "__intN" types for SIZE_TYPE.
+
2019-05-16 Martin Sebor <msebor@redhat.com>
- * brigfrontend/brig-control-handler.cc
- (brig_directive_control_handler::operator): Remove trailing newline
- from a diagnostic.
- * brigfrontend/brig-module-handler.cc
- (brig_directive_module_handler::operator): Remove a duplicated space
- from a diagnostic.
+ * brigfrontend/brig-control-handler.cc
+ (brig_directive_control_handler::operator): Remove trailing newline
+ from a diagnostic.
+ * brigfrontend/brig-module-handler.cc
+ (brig_directive_module_handler::operator): Remove a duplicated space
+ from a diagnostic.
2019-01-01 Jakub Jelinek <jakub@redhat.com>
@@ -18,7 +23,7 @@
2018-07-20 Martin Sebor <msebor@redhat.com>
PR middle-end/82063
- * brig/brig-lang.c (brig_langhook_handle_option): Change function
+ * brig-lang.c (brig_langhook_handle_option): Change function
argument to HOST_WIDE_INT.
2018-07-04 Martin Jambor <mjambor@suse.cz>
@@ -46,7 +51,7 @@
2018-05-04 Pekka Jääskeläinen <pekka.jaaskelainen@parmance.com>
- * brig/brigfrontend/brig-basic-inst-handler.cc: Fix handling of NOPs.
+ * brigfrontend/brig-basic-inst-handler.cc: Fix handling of NOPs.
2018-05-04 Pekka Jääskeläinen <pekka.jaaskelainen@parmance.com>
@@ -75,52 +80,52 @@
- add qualifiers to generated function parameters.
Const and restrict on the hidden local/private pointers,
the arg buffer and the context pointer help some optimizations.
- * brig/brigfrontend/brig-basic-inst-handler.cc: See above.
- * brig/brigfrontend/brig-branch-inst-handler.cc: See above.
- * brig/brigfrontend/brig-cmp-inst-handler.cc: See above.
- * brig/brigfrontend/brig-code-entry-handler.cc: See above.
- * brig/brigfrontend/brig-code-entry-handler.h: See above.
- * brig/brigfrontend/brig-control-handler.cc: See above.
- * brig/brigfrontend/brig-cvt-inst-handler.cc: See above.
- * brig/brigfrontend/brig-function-handler.cc: See above.
- * brig/brigfrontend/brig-function.cc: See above.
- * brig/brigfrontend/brig-function.h: See above.
- * brig/brigfrontend/brig-label-handler.cc: See above.
- * brig/brigfrontend/brig-lane-inst-handler.cc: See above.
- * brig/brigfrontend/brig-mem-inst-handler.cc: See above.
- * brig/brigfrontend/phsa.h: See above.
- * brig/lang.opt: See above.
+ * brigfrontend/brig-basic-inst-handler.cc: See above.
+ * brigfrontend/brig-branch-inst-handler.cc: See above.
+ * brigfrontend/brig-cmp-inst-handler.cc: See above.
+ * brigfrontend/brig-code-entry-handler.cc: See above.
+ * brigfrontend/brig-code-entry-handler.h: See above.
+ * brigfrontend/brig-control-handler.cc: See above.
+ * brigfrontend/brig-cvt-inst-handler.cc: See above.
+ * brigfrontend/brig-function-handler.cc: See above.
+ * brigfrontend/brig-function.cc: See above.
+ * brigfrontend/brig-function.h: See above.
+ * brigfrontend/brig-label-handler.cc: See above.
+ * brigfrontend/brig-lane-inst-handler.cc: See above.
+ * brigfrontend/brig-mem-inst-handler.cc: See above.
+ * brigfrontend/phsa.h: See above.
+ * lang.opt: See above.
2018-05-04 Pekka Jääskeläinen <pekka.jaaskelainen@parmance.com>
- * brig/brigfrontend/brig-function-handler.cc: Skip multiple forward
+ * brigfrontend/brig-function-handler.cc: Skip multiple forward
declarations of the same function.
2018-05-04 Pekka Jääskeläinen <pekka.jaaskelainen@parmance.com>
- * brig/brig-lang.c: Do not allow optimizations based on known C
+ * brig-lang.c: Do not allow optimizations based on known C
builtins.
2018-05-04 Pekka Jääskeläinen <pekka.jaaskelainen@parmance.com>
- * brig/brig-lang.c: Allow controlling strict aliasing from
+ * brig-lang.c: Allow controlling strict aliasing from
cmd line.
2018-05-04 Pekka Jääskeläinen <pekka.jaaskelainen@parmance.com>
- * brig/brigfrontend/brig-code-entry-handler.cc: The modulo in
+ * brigfrontend/brig-code-entry-handler.cc: The modulo in
ID computation should not be needed.
2018-05-04 Pekka Jääskeläinen <pekka.jaaskelainen@parmance.com>
- * brig/brig-lang.c: Add support for whole program
+ * brig-lang.c: Add support for whole program
optimizations by marking the kernels externally visible.
- * brig/brigfrontend/brig-branch-inst-handler.cc: See above.
- * brig/brigfrontend/brig-function-handler.cc: See above.
- * brig/brigfrontend/brig-function.cc: See above.
- * brig/brigfrontend/brig-to-generic.cc: See above.
- * brig/brigfrontend/brig-to-generic.h: See above.
- * brig/brigfrontend/brig-variable-handler.h: See above.
+ * brigfrontend/brig-branch-inst-handler.cc: See above.
+ * brigfrontend/brig-function-handler.cc: See above.
+ * brigfrontend/brig-function.cc: See above.
+ * brigfrontend/brig-to-generic.cc: See above.
+ * brigfrontend/brig-to-generic.h: See above.
+ * brigfrontend/brig-variable-handler.h: See above.
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
@@ -217,7 +222,7 @@
can be used to patch away BRIG entries at the binary level.
Also add extra error detection for zeroed regions: make sure
the byteCount field is never zero.
- * brig/brigfrontend/phsa.h: Added a new error prefix for
+ * brigfrontend/phsa.h: Added a new error prefix for
errors which are due to corrupted BRIG modules.
2017-10-09 Henry Linjamäki <henry.linjamaki@parmance.com>
diff --git a/gcc/builtins.c b/gcc/builtins.c
index e5a9261..9a766e4 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -3652,6 +3652,20 @@ compute_objsize (tree dest, int ostype)
if (!ostype)
return NULL_TREE;
+ if (TREE_CODE (dest) == MEM_REF)
+ {
+ tree ref = TREE_OPERAND (dest, 0);
+ tree off = TREE_OPERAND (dest, 1);
+ if (tree size = compute_objsize (ref, ostype))
+ {
+ if (tree_int_cst_lt (off, size))
+ return fold_build2 (MINUS_EXPR, size_type_node, size, off);
+ return integer_zero_node;
+ }
+
+ return NULL_TREE;
+ }
+
if (TREE_CODE (dest) != ADDR_EXPR)
return NULL_TREE;
@@ -5742,6 +5756,7 @@ expand_builtin_init_descriptor (tree exp)
r_descr = expand_normal (t_descr);
m_descr = gen_rtx_MEM (BLKmode, r_descr);
MEM_NOTRAP_P (m_descr) = 1;
+ set_mem_align (m_descr, GET_MODE_ALIGNMENT (ptr_mode));
r_func = expand_normal (t_func);
r_chain = expand_normal (t_chain);
@@ -7222,7 +7237,6 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
int ignore)
{
tree fndecl = get_callee_fndecl (exp);
- enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp));
int flags;
@@ -7234,6 +7248,7 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
redundant checks and be sure, that possible overflow will be detected
by ASan. */
+ enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
if ((flag_sanitize & SANITIZE_ADDRESS) && asan_intercepted_p (fcode))
return expand_call (exp, target, ignore);
@@ -11230,3 +11245,90 @@ target_char_cst_p (tree t, char *p)
*p = (char)tree_to_uhwi (t);
return true;
}
+
+/* Return true if the builtin DECL is implemented in a standard library.
+ Otherwise returns false which doesn't guarantee it is not (thus the list of
+ handled builtins below may be incomplete). */
+
+bool
+builtin_with_linkage_p (tree decl)
+{
+ if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+ switch (DECL_FUNCTION_CODE (decl))
+ {
+ CASE_FLT_FN (BUILT_IN_ACOS):
+ CASE_FLT_FN (BUILT_IN_ACOSH):
+ CASE_FLT_FN (BUILT_IN_ASIN):
+ CASE_FLT_FN (BUILT_IN_ASINH):
+ CASE_FLT_FN (BUILT_IN_ATAN):
+ CASE_FLT_FN (BUILT_IN_ATANH):
+ CASE_FLT_FN (BUILT_IN_ATAN2):
+ CASE_FLT_FN (BUILT_IN_CBRT):
+ CASE_FLT_FN (BUILT_IN_CEIL):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_CEIL):
+ CASE_FLT_FN (BUILT_IN_COPYSIGN):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_COPYSIGN):
+ CASE_FLT_FN (BUILT_IN_COS):
+ CASE_FLT_FN (BUILT_IN_COSH):
+ CASE_FLT_FN (BUILT_IN_ERF):
+ CASE_FLT_FN (BUILT_IN_ERFC):
+ CASE_FLT_FN (BUILT_IN_EXP):
+ CASE_FLT_FN (BUILT_IN_EXP2):
+ CASE_FLT_FN (BUILT_IN_EXPM1):
+ CASE_FLT_FN (BUILT_IN_FABS):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_FABS):
+ CASE_FLT_FN (BUILT_IN_FDIM):
+ CASE_FLT_FN (BUILT_IN_FLOOR):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_FLOOR):
+ CASE_FLT_FN (BUILT_IN_FMA):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMA):
+ CASE_FLT_FN (BUILT_IN_FMAX):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMAX):
+ CASE_FLT_FN (BUILT_IN_FMIN):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_FMIN):
+ CASE_FLT_FN (BUILT_IN_FMOD):
+ CASE_FLT_FN (BUILT_IN_FREXP):
+ CASE_FLT_FN (BUILT_IN_HYPOT):
+ CASE_FLT_FN (BUILT_IN_ILOGB):
+ CASE_FLT_FN (BUILT_IN_LDEXP):
+ CASE_FLT_FN (BUILT_IN_LGAMMA):
+ CASE_FLT_FN (BUILT_IN_LLRINT):
+ CASE_FLT_FN (BUILT_IN_LLROUND):
+ CASE_FLT_FN (BUILT_IN_LOG):
+ CASE_FLT_FN (BUILT_IN_LOG10):
+ CASE_FLT_FN (BUILT_IN_LOG1P):
+ CASE_FLT_FN (BUILT_IN_LOG2):
+ CASE_FLT_FN (BUILT_IN_LOGB):
+ CASE_FLT_FN (BUILT_IN_LRINT):
+ CASE_FLT_FN (BUILT_IN_LROUND):
+ CASE_FLT_FN (BUILT_IN_MODF):
+ CASE_FLT_FN (BUILT_IN_NAN):
+ CASE_FLT_FN (BUILT_IN_NEARBYINT):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_NEARBYINT):
+ CASE_FLT_FN (BUILT_IN_NEXTAFTER):
+ CASE_FLT_FN (BUILT_IN_NEXTTOWARD):
+ CASE_FLT_FN (BUILT_IN_POW):
+ CASE_FLT_FN (BUILT_IN_REMAINDER):
+ CASE_FLT_FN (BUILT_IN_REMQUO):
+ CASE_FLT_FN (BUILT_IN_RINT):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_RINT):
+ CASE_FLT_FN (BUILT_IN_ROUND):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_ROUND):
+ CASE_FLT_FN (BUILT_IN_SCALBLN):
+ CASE_FLT_FN (BUILT_IN_SCALBN):
+ CASE_FLT_FN (BUILT_IN_SIN):
+ CASE_FLT_FN (BUILT_IN_SINH):
+ CASE_FLT_FN (BUILT_IN_SINCOS):
+ CASE_FLT_FN (BUILT_IN_SQRT):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_SQRT):
+ CASE_FLT_FN (BUILT_IN_TAN):
+ CASE_FLT_FN (BUILT_IN_TANH):
+ CASE_FLT_FN (BUILT_IN_TGAMMA):
+ CASE_FLT_FN (BUILT_IN_TRUNC):
+ CASE_FLT_FN_FLOATN_NX (BUILT_IN_TRUNC):
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
diff --git a/gcc/builtins.h b/gcc/builtins.h
index 1ffb491..66c9295 100644
--- a/gcc/builtins.h
+++ b/gcc/builtins.h
@@ -150,5 +150,6 @@ extern internal_fn replacement_internal_fn (gcall *);
extern void warn_string_no_nul (location_t, const char *, tree, tree);
extern tree unterminated_array (tree, tree * = NULL, bool * = NULL);
+extern bool builtin_with_linkage_p (tree);
#endif /* GCC_BUILTINS_H */
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index e645254..a4a0bff 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,47 @@
+2019-08-15 Richard Biener <rguenther@suse.de>
+
+ * c-common.c (c_stddef_cpp_builtins): When the GIMPLE FE is
+ enabled, define __SIZETYPE__.
+
+2019-08-14 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * c-attribs.c (c_common_attribute_table): Add "noinit" entry. Add
+ exclusion with "section" attribute.
+ (attr_noinit_exclusions): New table.
+ (handle_noinit_attribute): New function.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR middle-end/91421
+ * c-common.c (resolve_overloaded_builtin): Use
+ copy_decl_built_in_function.
+
+2019-08-13 Martin Sebor <msebor@redhat.com>
+
+ PR c/80619
+ * c-format.c (printf_length_specs): Set FMT_LEN_w for "w".
+ (asm_fprintf_length_spec): Same.
+ * c-format.h (format_lengths): Add FMT_LEN_w.
+
+2019-08-10 Jakub Jelinek <jakub@redhat.com>
+
+ * c-pragma.h (enum pragma_omp_clause): Add
+ PRAGMA_OMP_CLAUSE_DEVICE_TYPE.
+
+2019-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ * c-pragma.h (enum pragma_omp_clause): Add
+ PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR. Set PRAGMA_OACC_CLAUSE_USE_DEVICE
+ equal to PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR instead of being a separate
+ enumeration value.
+
+2019-08-05 Marek Polacek <polacek@redhat.com>
+
+ PR c++/91338 - Implement P1161R3: Deprecate a[b,c].
+ * c-opts.c (c_common_post_options): Enable -Wcomma-subscript by
+ default for C++2a, unless -Wno-deprecated.
+ * c.opt (Wcomma-subscript): New warning.
+
2019-07-20 Jakub Jelinek <jakub@redhat.com>
* c-pragma.h (enum pragma_kind): Add PRAGMA_OMP_LOOP.
@@ -61,6 +105,11 @@
* c-omp.c (c_finish_omp_atomic): Allow tree_invariant_p in addition
to SAVE_EXPR in first operand of a COMPOUND_EXPR.
+2019-06-25 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * c-common.c (c_common_nodes_and_builtins): Define
+ alternate "__intN__" name for "__intN" types.
+
2019-06-24 Jan Hubicka <jh@suse.cz>
* c-common.c (braced_lists_to_strings): Check that
@@ -170,36 +219,36 @@
2019-05-16 Martin Sebor <msebor@redhat.com>
- * c-attribs.c (handle_no_sanitize_attribute): Quote identifiers,
- keywords, operators, and types in diagnostics.
- (handle_scalar_storage_order_attribute): Same.
- (handle_mode_attribute): Same.
- (handle_visibility_attribute): Same.
- (handle_assume_aligned_attribute): Same.
- (handle_no_split_stack_attribute): Same.
- * c-common.c (shorten_compare): Same.
- (c_common_truthvalue_conversion): Same.
- (cb_get_source_date_epoch): Same.
- * c-lex.c (cb_def_pragma): Quote keywords, operators, and types
- in diagnostics.
- (interpret_float): Same.
- * c-omp.c (c_finish_omp_for): Same.
- * c-opts.c (c_common_post_options): Same.
- * c-pch.c (c_common_pch_pragma): Same.
- * c-pragma.c (pop_alignment): Same.
- (handle_pragma_pack): Same.
- (apply_pragma_weak): Same.
- (handle_pragma_weak): Same.
- (handle_pragma_scalar_storage_order): Same.
- (handle_pragma_redefine_extname): Same.
- (add_to_renaming_pragma_list): Same.
- (maybe_apply_renaming_pragma): Same.
- (push_visibility): Same.
- (handle_pragma_visibility): Same.
- (handle_pragma_optimize): Same.
- (handle_pragma_message): Same.
- * c-warn.c (warn_for_omitted_condop): Same.
- (lvalue_error): Same.
+ * c-attribs.c (handle_no_sanitize_attribute): Quote identifiers,
+ keywords, operators, and types in diagnostics.
+ (handle_scalar_storage_order_attribute): Same.
+ (handle_mode_attribute): Same.
+ (handle_visibility_attribute): Same.
+ (handle_assume_aligned_attribute): Same.
+ (handle_no_split_stack_attribute): Same.
+ * c-common.c (shorten_compare): Same.
+ (c_common_truthvalue_conversion): Same.
+ (cb_get_source_date_epoch): Same.
+ * c-lex.c (cb_def_pragma): Quote keywords, operators, and types
+ in diagnostics.
+ (interpret_float): Same.
+ * c-omp.c (c_finish_omp_for): Same.
+ * c-opts.c (c_common_post_options): Same.
+ * c-pch.c (c_common_pch_pragma): Same.
+ * c-pragma.c (pop_alignment): Same.
+ (handle_pragma_pack): Same.
+ (apply_pragma_weak): Same.
+ (handle_pragma_weak): Same.
+ (handle_pragma_scalar_storage_order): Same.
+ (handle_pragma_redefine_extname): Same.
+ (add_to_renaming_pragma_list): Same.
+ (maybe_apply_renaming_pragma): Same.
+ (push_visibility): Same.
+ (handle_pragma_visibility): Same.
+ (handle_pragma_optimize): Same.
+ (handle_pragma_message): Same.
+ * c-warn.c (warn_for_omitted_condop): Same.
+ (lvalue_error): Same.
2019-05-15 Richard Biener <rguenther@suse.de>
@@ -207,7 +256,7 @@
* c-common.c (c_common_mark_addressable_vec): Also mark
a COMPOUND_LITERAL_EXPR_DECL addressable similar to
c_mark_addressable.
-
+
2019-05-06 Nathan Sidwell <nathan@acm.org>
* c-opts.c (handle_defered_opts): Rename struct deps to struc mkdeps.
@@ -270,7 +319,7 @@
2019-04-05 Marek Polacek <polacek@redhat.com>
- PR c++/89973 - -Waddress-of-packed-member ICE with invalid conversion.
+ PR c++/89973 - -Waddress-of-packed-member ICE with invalid conversion.
* c-warn.c (check_address_or_pointer_of_packed_member): Check the type
of RHS.
@@ -1042,7 +1091,7 @@
2018-08-01 Martin Sebor <msebor@redhat.com>
PR tree-optimization/86650
- * c-family/c-format.c (gcc_tdiag_char_table): Update comment for "%G".
+ * c-format.c (gcc_tdiag_char_table): Update comment for "%G".
(gcc_cdiag_char_table, gcc_cxxdiag_char_table): Same.
(init_dynamic_diag_info): Update from "gcall *" to "gimple *".
* c-format.h (T89_G): Update to be "gimple *" rather than
@@ -1081,7 +1130,7 @@
2018-07-20 Martin Sebor <msebor@redhat.com>
PR middle-end/82063
- * gcc/c-family/c.opt (-Warray-bounds): Remove redundant -Wall.
+ * c.opt (-Warray-bounds): Remove redundant -Wall.
2018-07-20 Martin Sebor <msebor@redhat.com>
@@ -1161,8 +1210,8 @@
* cppspec.c: Include opt-suggestions.h.
-2018-06-20 Chung-Lin Tang <cltang@codesourcery.com>
- Thomas Schwinge <thomas@codesourcery.com>
+2018-06-20 Chung-Lin Tang <cltang@codesourcery.com>
+ Thomas Schwinge <thomas@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com>
* c-pragma.h (enum pragma_omp_clause): Add
@@ -1251,7 +1300,7 @@
PR c/55976
* c-opts.c (c_common_post_options): Set default for warn_return_type
- for C++/C++ with ObjC extensions only. For C, makes it possible to
+ for C++/C++ with ObjC extensions only. For C, makes it possible to
differentiate between default (no option), -Wreturn-type, and
-Wno-return-type.
@@ -1393,12 +1442,12 @@
2018-03-12 Martin Sebor <msebor@redhat.com>
PR tree-optimization/83456
- * gcc/c-family/c-common.c (check_function_restrict): Return bool.
+ * c-common.c (check_function_restrict): Return bool.
Restore checking of bounded built-in functions.
(check_function_arguments): Also return the result
of warn_for_restrict.
- * gcc/c-family/c-common.c (check_function_restrict): Return bool.
- * gcc/c-family/c-warn.c (warn_for_restrict): Return bool.
+ * c-common.c (check_function_restrict): Return bool.
+ * c-warn.c (warn_for_restrict): Return bool.
2018-03-02 Marek Polacek <polacek@redhat.com>
@@ -1609,7 +1658,7 @@
* c-pragma.c (init_pragma): Register pragma GCC unroll.
* c-pragma.h (enum pragma_kind): Add PRAGMA_UNROLL.
-2017-12-22 Alexandre Oliva <aoliva@redhat.com>
+2017-12-22 Alexandre Oliva <aoliva@redhat.com>
PR debug/83527
PR debug/83419
@@ -1663,7 +1712,7 @@
Adjust the size of buf1 and buf2, add a new buf to avoid
format-overflow warning.
-2017-12-12 Alexandre Oliva <aoliva@redhat.com>
+2017-12-12 Alexandre Oliva <aoliva@redhat.com>
* c-semantics.c (pop_stmt_list): Move begin stmt marker into
subsequent statement list.
@@ -1967,7 +2016,7 @@
rather than DECL_INITIAL.
(common_handle_aligned_attribute): Likewise.
-2017-09-20 Alexandre Oliva <aoliva@redhat.com>
+2017-09-20 Alexandre Oliva <aoliva@redhat.com>
* c.opt (gen-decls): Add RejectNegative.
@@ -2029,7 +2078,7 @@
* c-warn.c (warn_tautological_bitwise_comparison): New function.
(warn_tautological_cmp): Call it.
-2017-09-01 Boris Kolpackov <boris@codesynthesis.com>
+2017-09-01 Boris Kolpackov <boris@codesynthesis.com>
* c-opts.c (c_common_finish): Write dependency information even if
there are errors.
@@ -2120,7 +2169,7 @@
* c-format.c (struct format_check_context): Add field "arglocs".
(check_function_format): Add param "arglocs"; pass it to
check_format_info.
- (check_format_info): Add param "arglocs"; use it to initialize
+ (check_format_info): Add param "arglocs"; use it to initialize
new field of format_ctx.
(check_format_arg): Pass format_ctx->arglocs to new param of
check_format_info_main.
@@ -2788,7 +2837,7 @@
PR middle-end/77708
* c.opt (-Wformat-truncation): New option.
-2017-01-06 Alexandre Oliva <aoliva@redhat.com>
+2017-01-06 Alexandre Oliva <aoliva@redhat.com>
* c-pretty-print.c (pp_c_tree_decl_identifier): Convert 16-bit
value to unsigned short to fit in 4 hex digits without
@@ -3399,7 +3448,7 @@
(format_warning_va): Move to substring-locations.c.
(format_warning_at_substring): Likewise.
-2016-09-06 Martin Sebor <msebor@redhat.com>
+2016-09-06 Martin Sebor <msebor@redhat.com>
PR c/77336
* c-format.c (check_function_format): Avoid issuing warnings for
@@ -5869,7 +5918,7 @@
Commentary and rearrangement of tests.
* g++.dg/cpp1y/feat-cxx14.C: Enable aggregate NSDMI test.
Commentary and rearrangement of tests.
- * g++.dg/cpp1y/feat-cxx98-neg.C: Ditto
+ * g++.dg/cpp1y/feat-cxx98-neg.C: Ditto.
* g++.dg/cpp1y/feat-cxx98.C: Commentary.
2014-10-29 Richard Sandiford <richard.sandiford@arm.com>
@@ -6259,7 +6308,7 @@
2014-08-03 Marek Polacek <polacek@redhat.com>
- * c-common.c (check_case_value): Add location_t parameter. Use it.
+ * c-common.c (check_case_value): Add location_t parameter. Use it.
(c_add_case_label): Pass loc to check_case_value.
2014-08-02 Trevor Saunders <tsaunders@mozilla.com>
@@ -6616,7 +6665,7 @@
* c-common.h (registered_builtin_types): Declare.
2014-04-14 Richard Biener <rguenther@suse.de>
- Marc Glisse <marc.glisse@inria.fr>
+ Marc Glisse <marc.glisse@inria.fr>
PR c/60819
* c-common.c (convert_vector_to_pointer_for_subscript): Properly
@@ -6876,7 +6925,7 @@
* c-common.c (c_common_attribute_table): Added "cilk simd function"
attribute.
* c-pragma.h (enum pragma_cilk_clause): Remove.
- (enum pragma_omp_clause): Added the following fields:
+ (enum pragma_omp_clause): Added the following fields:
PRAGMA_CILK_CLAUSE_NOMASK, PRAGMA_CILK_CLAUSE_MASK,
PRAGMA_CILK_CLAUSE_VECTORLENGTH, PRAGMA_CILK_CLAUSE_NONE,
PRAGMA_CILK_CLAUSE_LINEAR, PRAGMA_CILK_CLAUSE_PRIVATE,
@@ -6950,8 +6999,8 @@
2013-11-22 Andrew MacLeod <amacleod@redhat.com>
* c-common.c: Add required include files from gimple.h.
- * c-gimplify.c: Likewise
- * cilk.c: Likewise
+ * c-gimplify.c: Likewise.
+ * cilk.c: Likewise.
2013-11-22 David Malcolm <dmalcolm@redhat.com>
@@ -7461,7 +7510,7 @@
(pp_c_direct_abstract_declarator): Likewise.
* c-pretty-print.c (c_pretty_printer::abstract_declarator): Rename
from pp_c_abstract_declarator. Adjust.
- (c_pretty_printer::direct_abstract_declarator): Rename from
+ (c_pretty_printer::direct_abstract_declarator): Rename from
pp_c_direct_abstract_declarator. Adjust.
(c_pretty_printer::function_specifier): Rename from
pp_c_function_specifier. Adjust.
@@ -7943,15 +7992,15 @@
* c-opts.c (c_common_handle_option): Do not handle Wformat here.
* c-format.c (set_Wformat): Delete.
(decode_format_attr): Replace OPT_Wformat with OPT_Wformat_.
- (maybe_read_dollar_number): Likewise.
- (avoid_dollar_number): Likewise.
- (finish_dollar_format_checking): Likewise.
- (check_format_info): Likewise.
- (check_format_info_main): Likewise.
- (check_format_types): Likewise.
- (format_type_warning): Likewise.
- * c-common.c (int): Likewise.
- (check_function_sentinel): Likewise.
+ (maybe_read_dollar_number): Likewise.
+ (avoid_dollar_number): Likewise.
+ (finish_dollar_format_checking): Likewise.
+ (check_format_info): Likewise.
+ (check_format_info_main): Likewise.
+ (check_format_types): Likewise.
+ (format_type_warning): Likewise.
+ * c-common.c (int): Likewise.
+ (check_function_sentinel): Likewise.
* c-common.h (warn_format,set_Wformat): Do not declare here.
2012-11-07 Manuel López-Ibáñez <manu@gcc.gnu.org>
@@ -8299,7 +8348,7 @@
2012-05-16 Dodji Seketeli <dodji@redhat.com>
PR preprocessor/7263
- * c-lex.c (c_lex_with_flags): Pass a virtual location to the call
+ * c-lex.c (c_lex_with_flags): Pass a virtual location to the call
to cpp_classify_number. For diagnostics, use the precise location
instead of the global input_location.
@@ -8375,7 +8424,7 @@
2012-04-30 Dodji Seketeli <dodji@redhat.com>
Add -Wvarargs option
- * c.opt (Wvarargs): Define new option.
+ * c.opt (Wvarargs): Define new option.
2012-04-30 Manuel López-Ibáñez <manu@gcc.gnu.org>
@@ -8575,7 +8624,7 @@
2011-11-08 Richard Guenther <rguenther@suse.de>
PR middle-end/51010
- c-family/
+ * c-pretty-print.c (pp_c_expression): Handle SSA_NAMEs.
2011-11-07 Richard Henderson <rth@redhat.com>
Aldy Hernandez <aldyh@redhat.com>
@@ -9511,7 +9560,7 @@
first_target_format_type: New variable.
(handle_format_attribute): Set up first_target_format_type, pass the
expected format arg string type to check_format_string().
- * c-common.h (FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL): New flag.
+ * c-common.h (FMT_FLAG_PARSE_ARG_CONVERT_EXTERNAL): New flag.
* stub-objc.c (objc_string_ref_type_p): New.
(objc_check_format_arg): New.
@@ -9656,7 +9705,7 @@
Merge from 'apple/trunk' branch on FSF servers.
- 2006-03-27 Fariborz Jahanian <fjahanian@apple.com>
+ 2006-03-27 Fariborz Jahanian <fjahanian@apple.com>
Radar 4133425
* c-common.h (objc_diagnose_private_ivar): New decl.
@@ -9698,7 +9747,7 @@
2010-10-13 Iain Sandoe <iains@gcc.gnu.org>
merge from FSF apple 'trunk' branch.
- 2006-04-26 Fariborz Jahanian <fjahanian@apple.com>
+ 2006-04-26 Fariborz Jahanian <fjahanian@apple.com>
Radar 3803157 (method attributes)
* c-common.c (handle_deprecated_attribute): Recognize
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index 48819e7..820c83f 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -92,6 +92,7 @@ static tree handle_section_attribute (tree *, tree, tree, int, bool *);
static tree handle_aligned_attribute (tree *, tree, tree, int, bool *);
static tree handle_warn_if_not_aligned_attribute (tree *, tree, tree,
int, bool *);
+static tree handle_noinit_attribute (tree *, tree, tree, int, bool *);
static tree handle_weak_attribute (tree *, tree, tree, int, bool *) ;
static tree handle_noplt_attribute (tree *, tree, tree, int, bool *) ;
static tree handle_alias_ifunc_attribute (bool, tree *, tree, tree, bool *);
@@ -235,6 +236,13 @@ static const struct attribute_spec::exclusions attr_const_pure_exclusions[] =
ATTR_EXCL (NULL, false, false, false)
};
+static const struct attribute_spec::exclusions attr_noinit_exclusions[] =
+{
+ ATTR_EXCL ("noinit", true, true, true),
+ ATTR_EXCL ("section", true, true, true),
+ ATTR_EXCL (NULL, false, false, false),
+};
+
/* Table of machine-independent attributes common to all C-like languages.
Current list of processed common attributes: nonnull. */
@@ -307,7 +315,7 @@ const struct attribute_spec c_common_attribute_table[] =
{ "mode", 1, 1, false, true, false, false,
handle_mode_attribute, NULL },
{ "section", 1, 1, true, false, false, false,
- handle_section_attribute, NULL },
+ handle_section_attribute, attr_noinit_exclusions },
{ "aligned", 0, 1, false, false, false, false,
handle_aligned_attribute,
attr_aligned_exclusions },
@@ -458,6 +466,8 @@ const struct attribute_spec c_common_attribute_table[] =
handle_nocf_check_attribute, NULL },
{ "copy", 1, 1, false, false, false, false,
handle_copy_attribute, NULL },
+ { "noinit", 0, 0, true, false, false, false,
+ handle_noinit_attribute, attr_noinit_exclusions },
{ NULL, 0, 0, false, false, false, false, NULL, NULL }
};
@@ -2224,6 +2234,54 @@ handle_weak_attribute (tree *node, tree name,
return NULL_TREE;
}
+/* Handle a "noinit" attribute; arguments as in struct
+ attribute_spec.handler. Check whether the attribute is allowed
+ here and add the attribute to the variable decl tree or otherwise
+ issue a diagnostic. This function checks NODE is of the expected
+ type and issues diagnostics otherwise using NAME. If it is not of
+ the expected type *NO_ADD_ATTRS will be set to true. */
+
+static tree
+handle_noinit_attribute (tree * node,
+ tree name,
+ tree args,
+ int flags ATTRIBUTE_UNUSED,
+ bool *no_add_attrs)
+{
+ const char *message = NULL;
+
+ gcc_assert (DECL_P (*node));
+ gcc_assert (args == NULL);
+
+ if (TREE_CODE (*node) != VAR_DECL)
+ message = G_("%qE attribute only applies to variables");
+
+ /* Check that it's possible for the variable to have a section. */
+ else if ((TREE_STATIC (*node) || DECL_EXTERNAL (*node) || in_lto_p)
+ && DECL_SECTION_NAME (*node))
+ message = G_("%qE attribute cannot be applied to variables "
+ "with specific sections");
+
+ else if (!targetm.have_switchable_bss_sections)
+ message = G_("%qE attribute is specific to ELF targets");
+
+ if (message)
+ {
+ warning (OPT_Wattributes, message, name);
+ *no_add_attrs = true;
+ }
+ else
+ /* If this var is thought to be common, then change this. Common
+ variables are assigned to sections before the backend has a
+ chance to process them. Do this only if the attribute is
+ valid. */
+ if (DECL_COMMON (*node))
+ DECL_COMMON (*node) = 0;
+
+ return NULL_TREE;
+}
+
+
/* Handle a "noplt" attribute; arguments as in
struct attribute_spec.handler. */
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index cb92710..2810867 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -5148,6 +5148,10 @@ c_stddef_cpp_builtins(void)
builtin_define_with_value ("__INTPTR_TYPE__", INTPTR_TYPE, 0);
if (UINTPTR_TYPE)
builtin_define_with_value ("__UINTPTR_TYPE__", UINTPTR_TYPE, 0);
+ /* GIMPLE FE testcases need access to the GCC internal 'sizetype'.
+ Expose it as __SIZETYPE__. */
+ if (flag_gimple)
+ builtin_define_with_value ("__SIZETYPE__", SIZETYPE, 0);
}
static void
@@ -7332,8 +7336,6 @@ tree
resolve_overloaded_builtin (location_t loc, tree function,
vec<tree, va_gc> *params)
{
- enum built_in_function orig_code = DECL_FUNCTION_CODE (function);
-
/* Is function one of the _FETCH_OP_ or _OP_FETCH_ built-ins?
Those are not valid to call with a pointer to _Bool (or C++ bool)
and so must be rejected. */
@@ -7355,6 +7357,7 @@ resolve_overloaded_builtin (location_t loc, tree function,
}
/* Handle BUILT_IN_NORMAL here. */
+ enum built_in_function orig_code = DECL_FUNCTION_CODE (function);
switch (orig_code)
{
case BUILT_IN_SPECULATION_SAFE_VALUE_N:
diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index d134116..6b05996 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -497,7 +497,7 @@ static const format_length_info printf_length_specs[] =
static const format_length_info asm_fprintf_length_specs[] =
{
{ "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
- { "w", FMT_LEN_none, STD_C89, NO_FMT, 0 },
+ { "w", FMT_LEN_w, STD_C89, NO_FMT, 0 },
{ NO_FMT, NO_FMT, 0 }
};
@@ -505,7 +505,7 @@ static const format_length_info asm_fprintf_length_specs[] =
static const format_length_info gcc_diag_length_specs[] =
{
{ "l", FMT_LEN_l, STD_C89, "ll", FMT_LEN_ll, STD_C89, 0 },
- { "w", FMT_LEN_none, STD_C89, NO_FMT, 0 },
+ { "w", FMT_LEN_w, STD_C89, NO_FMT, 0 },
{ NO_FMT, NO_FMT, 0 }
};
diff --git a/gcc/c-family/c-format.h b/gcc/c-family/c-format.h
index 972ba46..6aa68df 100644
--- a/gcc/c-family/c-format.h
+++ b/gcc/c-family/c-format.h
@@ -36,6 +36,7 @@ enum format_lengths
FMT_LEN_H,
FMT_LEN_D,
FMT_LEN_DD,
+ FMT_LEN_w, /* GCC's HOST_WIDE_INT. */
FMT_LEN_MAX
};
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index e97bbdf5..2d4af63 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -916,6 +916,10 @@ c_common_post_options (const char **pfilename)
if (!global_options_set.x_warn_register)
warn_register = cxx_dialect >= cxx17;
+ /* -Wcomma-subscript is enabled by default in C++20. */
+ if (!global_options_set.x_warn_comma_subscript)
+ warn_comma_subscript = (cxx_dialect >= cxx2a && warn_deprecated);
+
/* Declone C++ 'structors if -Os. */
if (flag_declone_ctor_dtor == -1)
flag_declone_ctor_dtor = optimize_size;
diff --git a/gcc/c-family/c-pragma.h b/gcc/c-family/c-pragma.h
index e8a509f..e0aa774 100644
--- a/gcc/c-family/c-pragma.h
+++ b/gcc/c-family/c-pragma.h
@@ -93,6 +93,7 @@ enum pragma_omp_clause {
PRAGMA_OMP_CLAUSE_DEFAULTMAP,
PRAGMA_OMP_CLAUSE_DEPEND,
PRAGMA_OMP_CLAUSE_DEVICE,
+ PRAGMA_OMP_CLAUSE_DEVICE_TYPE,
PRAGMA_OMP_CLAUSE_DIST_SCHEDULE,
PRAGMA_OMP_CLAUSE_FINAL,
PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
@@ -137,6 +138,7 @@ enum pragma_omp_clause {
PRAGMA_OMP_CLAUSE_UNIFORM,
PRAGMA_OMP_CLAUSE_UNTIED,
PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR,
+ PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR,
/* Clauses for OpenACC. */
PRAGMA_OACC_CLAUSE_ASYNC,
@@ -157,7 +159,6 @@ enum pragma_omp_clause {
PRAGMA_OACC_CLAUSE_SELF,
PRAGMA_OACC_CLAUSE_SEQ,
PRAGMA_OACC_CLAUSE_TILE,
- PRAGMA_OACC_CLAUSE_USE_DEVICE,
PRAGMA_OACC_CLAUSE_VECTOR,
PRAGMA_OACC_CLAUSE_VECTOR_LENGTH,
PRAGMA_OACC_CLAUSE_WAIT,
@@ -171,7 +172,8 @@ enum pragma_omp_clause {
PRAGMA_OACC_CLAUSE_IF = PRAGMA_OMP_CLAUSE_IF,
PRAGMA_OACC_CLAUSE_PRIVATE = PRAGMA_OMP_CLAUSE_PRIVATE,
PRAGMA_OACC_CLAUSE_REDUCTION = PRAGMA_OMP_CLAUSE_REDUCTION,
- PRAGMA_OACC_CLAUSE_LINK = PRAGMA_OMP_CLAUSE_LINK
+ PRAGMA_OACC_CLAUSE_LINK = PRAGMA_OMP_CLAUSE_LINK,
+ PRAGMA_OACC_CLAUSE_USE_DEVICE = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR
};
extern struct cpp_reader* parse_in;
diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c
index b5d09e7..d671b77 100644
--- a/gcc/c-family/c-warn.c
+++ b/gcc/c-family/c-warn.c
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "gcc-rich-location.h"
#include "gimplify.h"
#include "c-family/c-indentation.h"
+#include "c-family/c-spellcheck.h"
#include "calls.h"
#include "stor-layout.h"
@@ -1628,6 +1629,15 @@ c_do_switch_warnings (splay_tree cases, location_t switch_location,
if (cond && tree_int_cst_compare (cond, value))
continue;
+ /* If the enumerator is defined in a system header and uses a reserved
+ name, then we continue to avoid throwing a warning. */
+ location_t loc = DECL_SOURCE_LOCATION
+ (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (type)));
+ if (in_system_header_at (loc)
+ && name_reserved_for_implementation_p
+ (IDENTIFIER_POINTER (TREE_PURPOSE (chain))))
+ continue;
+
/* If there is a default_node, the only relevant option is
Wswitch-enum. Otherwise, if both are enabled then we prefer
to warn using -Wswitch because -Wswitch is enabled by -Wall
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 4c8b002..257cadf 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -428,6 +428,10 @@ Wclobbered
C ObjC C++ ObjC++ Var(warn_clobbered) Warning EnabledBy(Wextra)
Warn about variables that might be changed by \"longjmp\" or \"vfork\".
+Wcomma-subscript
+C++ ObjC++ Var(warn_comma_subscript) Warning
+Warn about uses of a comma operator within a subscripting expression.
+
Wcomment
C ObjC C++ ObjC++ CPP(warn_comments) CppReason(CPP_W_COMMENTS) Var(cpp_warn_comment) Init(0) Warning LangEnabledBy(C ObjC C++ ObjC++,Wall)
Warn about possibly nested block comments, and C++ comments spanning more than one physical line.
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 0bb1d4c..4d2897e 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,80 @@
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR middle-end/91421
+ * c-decl.c (merge_decls): Use copy_decl_built_in_function.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR middle-end/91421
+ * c-decl.c (header_for_builtin_fn): Take a FUNCTION_DECL instead
+ of a built_in_function.
+ (diagnose_mismatched_decls, implicitly_declare): Update accordingly.
+
+2019-08-10 Jakub Jelinek <jakub@redhat.com>
+
+ * c-parser.c (c_parser_omp_clause_name): Parse device_type.
+ (c_parser_omp_clause_device_type): New function.
+ (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DEVICE_TYPE.
+ (OMP_DECLARE_TARGET_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DEVICE_TYPE.
+ (c_parser_omp_declare_target): Handle device_type clauses. Remove
+ diagnostics for declare target with clauses nested in clause-less
+ declare target declaration-definition-seq.
+ * c-typeck.c (c_finish_omp_clauses): Handle OMP_CLAUSE_DEVICE_TYPE.
+
+2019-08-09 Jakub Jelinek <jakub@redhat.com>
+
+ * c-parser.c (check_no_duplicate_clause): Simplify using
+ omp_find_clause.
+ (c_parser_omp_clause_if): Fix up printing of target {enter,exit} data
+ directive name modifiers.
+ (c_parser_omp_clause_proc_bind): Check for duplicate proc_bind clause.
+
+ PR c/91401
+ * c-parser.c (c_parser_omp_clause_dist_schedule): Fix up typos in the
+ check_no_duplicate_clause call. Comment it out, instead emit a
+ warning for duplicate dist_schedule clauses.
+
+2019-08-08 Richard Sandiford <richard.sandiford@arm.com>
+
+ * c-decl.c (finish_enum): Clear C_TYPE_BEING_DEFINED.
+
+2019-08-08 Jakub Jelinek <jakub@redhat.com>
+
+ * c-typeck.c (c_finish_omp_clauses): For C_ORT_OMP
+ OMP_CLAUSE_USE_DEVICE_* clauses use oacc_reduction_head bitmap
+ instead of generic_head to track duplicates.
+
+2019-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ * c-parser.c (c_parser_omp_clause_name): Parse use_device_addr clause.
+ (c_parser_omp_clause_use_device_addr): New function.
+ (c_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR.
+ (OMP_TARGET_DATA_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR.
+ (c_parser_omp_target_data): Handle PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
+ like PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR, adjust diagnostics about no
+ map or use_device_* clauses.
+ * c-typeck.c (c_finish_omp_clauses): For OMP_CLAUSE_USE_DEVICE_PTR
+ in OpenMP, require pointer type rather than pointer or array type.
+ Handle OMP_CLAUSE_USE_DEVICE_ADDR.
+
+2019-07-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR c/91192
+ * c-parser.c (c_parser_sizeof_expression): Call set_c_expr_source_range
+ even if finish is UNKNOWN_LOCATION, just use start as finish in that
+ case.
+
+2019-07-25 Martin Liska <mliska@suse.cz>
+ Dominik Infuhr <dominik.infuehr@theobroma-systems.com>
+
+ PR c++/23383
+ * c-decl.c (merge_decls): Merge OPERATOR_DELETE flag.
+
+2019-07-25 Martin Liska <mliska@suse.cz>
+
+ * c-decl.c (merge_decls): Use new macros
+ (e.g. DECL_SET_LAMBDA_FUNCTION and DECL_LAMBDA_FUNCTION_P).
+
2019-07-23 Richard Biener <rguenther@suse.de>
PR tree-optimization/83518
@@ -22,7 +99,7 @@
* c-decl.c (finish_function): Check targetm.warn_func_return
before issuing a -Wreturn-type warning.
-2019-07-12 Alexandre Oliva <oliva@adacore.com>
+2019-07-12 Alexandre Oliva <oliva@adacore.com>
* gimple-parser.c (c_parser_gimple_try_stmt): New.
(c_parser_compound_statement): Call it.
@@ -64,6 +141,12 @@
_Literal (char *) &"foo" for address literals pointing to
STRING_CSTs.
+2019-06-25 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * c-parser.c (c_parse_init): Create keyword for "__intN__" type.
+ * c-decl.c (declspecs_add_type): Don't pedwarn about "__intN" ISO
+ C incompatibility if alternate "__intN__" form is used.
+
2019-06-24 Martin Sebor <msebor@redhat.com>
* c-typeck.c (build_binary_op): Hyphenate floating-point.
@@ -112,17 +195,17 @@
2019-05-16 Martin Sebor <msebor@redhat.com>
- * c-decl.c (start_decl): Quote keywords, operators, and
- types in diagnostics.
- (finish_decl): Same.
- * c-parser.c (c_parser_asm_statement): Same.
- (c_parser_conditional_expression): Same.
- (c_parser_transaction_cancel): Same.
- * c-typeck.c (c_common_type): Same.
- (build_conditional_expr): Same.
- (digest_init): Same.
- (process_init_element): Same.
- (build_binary_op): Same.
+ * c-decl.c (start_decl): Quote keywords, operators, and
+ types in diagnostics.
+ (finish_decl): Same.
+ * c-parser.c (c_parser_asm_statement): Same.
+ (c_parser_conditional_expression): Same.
+ (c_parser_transaction_cancel): Same.
+ * c-typeck.c (c_common_type): Same.
+ (build_conditional_expr): Same.
+ (digest_init): Same.
+ (process_init_element): Same.
+ (build_binary_op): Same.
2019-05-17 Richard Biener <rguenther@suse.de>
@@ -281,7 +364,7 @@
(c_parser_oacc_simple_clause): Replace parser with loc formal
parameter. Adjust all users.
-2019-02-19 Chung-Lin Tang <cltang@codesourcery.com>
+2019-02-19 Chung-Lin Tang <cltang@codesourcery.com>
PR c/87924
* c-parser.c (c_parser_oacc_clause_wait): Add representation of wait
@@ -661,7 +744,7 @@
PR c/87347
* c-parser.c (warn_for_abs): Bail out if TYPE_ARG_TYPES is NULL. Fix
- comment.
+ comment.
2018-09-17 David Malcolm <dmalcolm@redhat.com>
@@ -753,7 +836,7 @@
(build_binary_op): Use it when calling binary_op_error.
2018-08-15 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
-
+
* c-decl.c (start_decl): Do not warn if variables is named as main
and is a local variable.
@@ -794,8 +877,8 @@
type here, instead add "omp declare target implicit" attribute.
(finish_decl): Diagnose vars without mappable type here.
-2018-06-20 Chung-Lin Tang <cltang@codesourcery.com>
- Thomas Schwinge <thomas@codesourcery.com>
+2018-06-20 Chung-Lin Tang <cltang@codesourcery.com>
+ Thomas Schwinge <thomas@codesourcery.com>
Cesar Philippidis <cesar@codesourcery.com>
* c-parser.c (c_parser_omp_clause_name): Add support for finalize
@@ -1038,7 +1121,7 @@
PR c/82679
* c-decl.c (grokdeclarator): Check declspecs insted of atomicp.
-2017-12-12 Alexandre Oliva <aoliva@redhat.com>
+2017-12-12 Alexandre Oliva <aoliva@redhat.com>
* c-objc-common.h (LANG_HOOKS_EMITS_BEGIN_STMT): Redefine as true.
* c-parser.c (add_debug_begin_stmt): New.
@@ -1150,7 +1233,7 @@
* c-typeck.c (c_start_case): Build SWITCH_EXPR using build2 instead
of build3.
-2017-11-14 Boris Kolpackov <boris@codesynthesis.com>
+2017-11-14 Boris Kolpackov <boris@codesynthesis.com>
* Make-lang.in (c.install-plugin): Install backend import library.
@@ -1558,7 +1641,7 @@
PR c/81417
* c-array-notation.c (fix_builtin_array_notation_fn): Update calls to
- build_conditional_expr.
+ build_conditional_expr.
* c-parser.c (c_parser_conditional_expression): Create locations for
EXP1 and EXP2 from their source ranges. Pass the locations down to
build_conditional_expr.
@@ -1586,7 +1669,7 @@
* c-warn.c (warn_for_multistatement_macros): Prevent bogus
warnings. Avoid walking MACRO_MAP_LOCATIONS.
-2017-07-31 Jan Hubicka <hubicka@ucw.cz>
+2017-07-31 Jan Hubicka <hubicka@ucw.cz>
Martin Liska <mliska@suse.cz>
* c-typeck.c (c_finish_goto_label): Build gimple predict
@@ -1782,7 +1865,7 @@
* c-convert.c (convert): Replace c_save_expr with save_expr. Don't
call c_fully_fold.
(convert) <case COMPLEX_TYPE>: Remove special handling of COMPLEX_TYPEs.
- * c-decl.c (grokdeclarator): Replace c_save_expr with save_expr.
+ * c-decl.c (grokdeclarator): Replace c_save_expr with save_expr.
* c-fold.c (c_fully_fold_internal): Handle SAVE_EXPR.
* c-parser.c (c_parser_declaration_or_fndef): Replace c_save_expr with
save_expr.
@@ -2014,7 +2097,7 @@
set_c_expr_source_range when parsing ssa-name.
2017-02-10 Prasad Ghangal <prasad.ghangal@gmail.com>
- Richard Biener <rguenther@suse.de>
+ Richard Biener <rguenther@suse.de>
* gimple-parser.c (c_parser_gimple_binary_expression): Avoid
building IL when arguments are error_mark_node.
@@ -3459,7 +3542,6 @@
Julian Brown <julian@codesourcery.com>
Nathan Sidwell <nathan@codesourcery.com>
- c/
* c-parser.c (c_parser_declaration_or_fndef): Add OpenACC
routine arg.
(c_parser_declaration_or_fndef): Call c_finish_oacc_routine.
@@ -4881,7 +4963,7 @@
PR c/49706
* c-typeck.c (parser_build_binary_op): Warn when logical not is used
- on the left hand side operand of a comparison.
+ on the left hand side operand of a comparison.
2014-06-05 Marek Polacek <polacek@redhat.com>
@@ -5699,7 +5781,7 @@
(build_cilk_spawn): New function.
(build_cilk_sync): Likewise.
* Makefile.in (c-decl.o): Added cilk.h in dependency list.
-
+
2013-10-27 Tobias Burnus <burnus@net-b.de>
PR other/33426
@@ -5984,7 +6066,7 @@
* c-array-notation.c (expand_array_notation_exprs): Added
ARRAY_NOTATION_REF case.
-
+
2013-06-07 Balaji V. Iyer <balaji.v.iyer@intel.com>
* c-array-notation.c (length_mismatch_in_expr_p): Moved this
@@ -6000,7 +6082,7 @@
(replace_invariant_exprs): Initialized additional_tcodes to NULL.
(struct inv_list): Moved this to c-family/array-notation-common.c.
* c-tree.h (is_cilkplus_builtin_reduce): Remove prototype.
-
+
2013-06-05 Balaji V. Iyer <balaji.v.iyer@intel.com>
* c-typeck.c (convert_arguments): Moved checking of builtin cilkplus
@@ -6019,7 +6101,7 @@
to the end of function parsing.
* c-array-notation.c (fix_conditional_array_notations_1): Expanded the
whole if-statement instead of just the condition.
- (expand_array_notation_exprs): Added MODIFY_EXPR case.
+ (expand_array_notation_exprs): Added MODIFY_EXPR case.
2013-06-03 Balaji V. Iyer <balaji.v.iyer@intel.com>
@@ -6027,7 +6109,7 @@
* c-array-notation.c (build_array_notation_expr): Initialized rhs_length
array to NULL_TREE if they are unused. Also added a check for the
field to be NULL before its fields are used in future.
-
+
2013-05-29 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR bootstrap/57450
@@ -6075,7 +6157,7 @@
(c_parser_array_notation): New function.
* c-array-notation.c: New file.
* c-tree.h (is_cilkplus_reduce_builtin): Protoize.
-
+
2013-05-23 Mike Stump <mikestump@comcast.net>
* c-typeck.c (convert_for_assignment): Handle references to memory
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 0d107ad..31116b2 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -605,7 +605,7 @@ static tree grokparms (struct c_arg_info *, bool);
static void layout_array_type (tree);
static void warn_defaults_to (location_t, int, const char *, ...)
ATTRIBUTE_GCC_DIAG(3,4);
-static const char *header_for_builtin_fn (enum built_in_function);
+static const char *header_for_builtin_fn (tree);
/* T is a statement. Add it to the statement-tree. This is the
C/ObjC version--C++ has a slightly different version of this
@@ -1953,7 +1953,8 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
if (!comptypes (oldtype, newtype))
{
if (TREE_CODE (olddecl) == FUNCTION_DECL
- && fndecl_built_in_p (olddecl) && !C_DECL_DECLARED_BUILTIN (olddecl))
+ && fndecl_built_in_p (olddecl, BUILT_IN_NORMAL)
+ && !C_DECL_DECLARED_BUILTIN (olddecl))
{
/* Accept "harmless" mismatches in function types such
as missing qualifiers or pointer vs same size integer
@@ -1975,8 +1976,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
/* If types don't match for a built-in, throw away the
built-in. No point in calling locate_old_decl here, it
won't print anything. */
- const char *header
- = header_for_builtin_fn (DECL_FUNCTION_CODE (olddecl));
+ const char *header = header_for_builtin_fn (olddecl);
location_t loc = DECL_SOURCE_LOCATION (newdecl);
if (warning_at (loc, OPT_Wbuiltin_declaration_mismatch,
"conflicting types for built-in function %q+D; "
@@ -2639,7 +2639,10 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
|= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl);
DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
- DECL_IS_OPERATOR_NEW (newdecl) |= DECL_IS_OPERATOR_NEW (olddecl);
+ if (DECL_IS_OPERATOR_NEW_P (olddecl))
+ DECL_SET_IS_OPERATOR_NEW (newdecl, true);
+ if (DECL_IS_OPERATOR_DELETE_P (olddecl))
+ DECL_SET_IS_OPERATOR_DELETE (newdecl, true);
TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
DECL_PURE_P (newdecl) |= DECL_PURE_P (olddecl);
DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl);
@@ -2733,8 +2736,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
{
/* If redeclaring a builtin function, it stays built in.
But it gets tagged as having been declared. */
- DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
- DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
+ copy_decl_built_in_function (newdecl, olddecl);
C_DECL_DECLARED_BUILTIN (newdecl) = 1;
if (new_is_prototype)
{
@@ -3336,13 +3338,17 @@ implicit_decl_warning (location_t loc, tree id, tree olddecl)
hint.suppress ();
}
-/* This function represents mapping of a function code FCODE
- to its respective header. */
+/* Return the name of the header file that declares built-in function
+ FNDECL, or null if either we don't know or don't expect to see an
+ explicit declaration. */
static const char *
-header_for_builtin_fn (enum built_in_function fcode)
+header_for_builtin_fn (tree fndecl)
{
- switch (fcode)
+ if (DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
+ return NULL;
+
+ switch (DECL_FUNCTION_CODE (fndecl))
{
CASE_FLT_FN (BUILT_IN_ACOS):
CASE_FLT_FN (BUILT_IN_ACOSH):
@@ -3592,8 +3598,7 @@ implicitly_declare (location_t loc, tree functionid)
"declaration of built-in "
"function %qD", decl);
/* See if we can hint which header to include. */
- const char *header
- = header_for_builtin_fn (DECL_FUNCTION_CODE (decl));
+ const char *header = header_for_builtin_fn (decl);
if (header != NULL && warned)
{
rich_location richloc (line_table, loc);
@@ -8778,6 +8783,8 @@ finish_enum (tree enumtype, tree values, tree attributes)
&& !in_sizeof && !in_typeof && !in_alignof)
struct_parse_info->struct_types.safe_push (enumtype);
+ C_TYPE_BEING_DEFINED (enumtype) = 0;
+
return enumtype;
}
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 6721049..81919a8 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -7477,8 +7477,9 @@ c_parser_sizeof_expression (c_parser *parser)
error_at (expr_loc, "%<sizeof%> applied to a bit-field");
result = c_expr_sizeof_expr (expr_loc, expr);
}
- if (finish != UNKNOWN_LOCATION)
- set_c_expr_source_range (&result, start, finish);
+ if (finish == UNKNOWN_LOCATION)
+ finish = start;
+ set_c_expr_source_range (&result, start, finish);
return result;
}
@@ -11719,6 +11720,8 @@ c_parser_omp_clause_name (c_parser *parser)
result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
else if (!strcmp ("device_resident", p))
result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
+ else if (!strcmp ("device_type", p))
+ result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
else if (!strcmp ("dist_schedule", p))
result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
break;
@@ -11865,6 +11868,8 @@ c_parser_omp_clause_name (c_parser *parser)
result = PRAGMA_OMP_CLAUSE_UNTIED;
else if (!strcmp ("use_device", p))
result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
+ else if (!strcmp ("use_device_addr", p))
+ result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
else if (!strcmp ("use_device_ptr", p))
result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
break;
@@ -11895,15 +11900,8 @@ static void
check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
const char *name)
{
- tree c;
-
- for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
- if (OMP_CLAUSE_CODE (c) == code)
- {
- location_t loc = OMP_CLAUSE_LOCATION (c);
- error_at (loc, "too many %qs clauses", name);
- break;
- }
+ if (tree c = omp_find_clause (clauses, code))
+ error_at (OMP_CLAUSE_LOCATION (c), "too many %qs clauses", name);
}
/* OpenACC 2.0
@@ -12613,8 +12611,8 @@ c_parser_omp_clause_if (c_parser *parser, tree list, bool is_omp)
case OMP_TARGET_DATA: p = "target data"; break;
case OMP_TARGET: p = "target"; break;
case OMP_TARGET_UPDATE: p = "target update"; break;
- case OMP_TARGET_ENTER_DATA: p = "enter data"; break;
- case OMP_TARGET_EXIT_DATA: p = "exit data"; break;
+ case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
+ case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
default: gcc_unreachable ();
}
error_at (location, "too many %<if%> clauses with %qs modifier",
@@ -13120,6 +13118,16 @@ c_parser_omp_clause_use_device_ptr (c_parser *parser, tree list)
list);
}
+/* OpenMP 5.0:
+ use_device_addr ( variable-list ) */
+
+static tree
+c_parser_omp_clause_use_device_addr (c_parser *parser, tree list)
+{
+ return c_parser_omp_var_list_parens (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
+ list);
+}
+
/* OpenMP 4.5:
is_device_ptr ( variable-list ) */
@@ -14798,7 +14806,10 @@ c_parser_omp_clause_dist_schedule (c_parser *parser, tree list)
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
"expected %<,%> or %<)%>");
- check_no_duplicate_clause (list, OMP_CLAUSE_SCHEDULE, "schedule");
+ /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
+ "dist_schedule"); */
+ if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
+ warning_at (loc, 0, "too many %qs clauses", "dist_schedule");
if (t == error_mark_node)
return list;
@@ -14840,6 +14851,7 @@ c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
else
goto invalid_kind;
+ check_no_duplicate_clause (list, OMP_CLAUSE_PROC_BIND, "proc_bind");
c_parser_consume_token (parser);
parens.skip_until_found_close (parser);
c = build_omp_clause (clause_loc, OMP_CLAUSE_PROC_BIND);
@@ -14853,6 +14865,50 @@ c_parser_omp_clause_proc_bind (c_parser *parser, tree list)
return list;
}
+/* OpenMP 5.0:
+ device_type ( host | nohost | any ) */
+
+static tree
+c_parser_omp_clause_device_type (c_parser *parser, tree list)
+{
+ location_t clause_loc = c_parser_peek_token (parser)->location;
+ enum omp_clause_device_type_kind kind;
+ tree c;
+
+ matching_parens parens;
+ if (!parens.require_open (parser))
+ return list;
+
+ if (c_parser_next_token_is (parser, CPP_NAME))
+ {
+ const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ if (strcmp ("host", p) == 0)
+ kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
+ else if (strcmp ("nohost", p) == 0)
+ kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
+ else if (strcmp ("any", p) == 0)
+ kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
+ else
+ goto invalid_kind;
+ }
+ else
+ goto invalid_kind;
+
+ /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE,
+ "device_type"); */
+ c_parser_consume_token (parser);
+ parens.skip_until_found_close (parser);
+ c = build_omp_clause (clause_loc, OMP_CLAUSE_DEVICE_TYPE);
+ OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+
+ invalid_kind:
+ c_parser_error (parser, "expected %<host%>, %<nohost%> or %<any%>");
+ parens.skip_until_found_close (parser);
+ return list;
+}
+
/* OpenMP 4.0:
to ( variable-list ) */
@@ -15320,6 +15376,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
clauses = c_parser_omp_clause_use_device_ptr (parser, clauses);
c_name = "use_device_ptr";
break;
+ case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
+ clauses = c_parser_omp_clause_use_device_addr (parser, clauses);
+ c_name = "use_device_addr";
+ break;
case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
clauses = c_parser_omp_clause_is_device_ptr (parser, clauses);
c_name = "is_device_ptr";
@@ -15336,6 +15396,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
clauses = c_parser_omp_clause_proc_bind (parser, clauses);
c_name = "proc_bind";
break;
+ case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
+ clauses = c_parser_omp_clause_device_type (parser, clauses);
+ c_name = "device_type";
+ break;
case PRAGMA_OMP_CLAUSE_SAFELEN:
clauses = c_parser_omp_clause_safelen (parser, clauses);
c_name = "safelen";
@@ -18287,7 +18351,8 @@ c_parser_omp_teams (location_t loc, c_parser *parser,
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
static tree
c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
@@ -18322,7 +18387,8 @@ c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
*pc = OMP_CLAUSE_CHAIN (*pc);
continue;
}
- else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR)
+ else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
+ || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
map_seen = 3;
pc = &OMP_CLAUSE_CHAIN (*pc);
}
@@ -18332,7 +18398,8 @@ c_parser_omp_target_data (location_t loc, c_parser *parser, bool *if_p)
if (map_seen == 0)
error_at (loc,
"%<#pragma omp target data%> must contain at least "
- "one %<map%> or %<use_device_ptr%> clause");
+ "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
+ "clause");
return NULL_TREE;
}
@@ -18980,13 +19047,15 @@ c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
#define OMP_DECLARE_TARGET_CLAUSE_MASK \
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
static void
c_parser_omp_declare_target (c_parser *parser)
{
- location_t loc = c_parser_peek_token (parser)->location;
tree clauses = NULL_TREE;
+ int device_type = 0;
+ bool only_device_type = true;
if (c_parser_next_token_is (parser, CPP_NAME))
clauses = c_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
"#pragma omp declare target");
@@ -19003,16 +19072,18 @@ c_parser_omp_declare_target (c_parser *parser)
current_omp_declare_target_attribute++;
return;
}
- if (current_omp_declare_target_attribute)
- error_at (loc, "%<#pragma omp declare target%> with clauses in between "
- "%<#pragma omp declare target%> without clauses and "
- "%<#pragma omp end declare target%>");
+ for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+ device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
{
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+ continue;
tree t = OMP_CLAUSE_DECL (c), id;
tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
tree at2 = lookup_attribute ("omp declare target link",
DECL_ATTRIBUTES (t));
+ only_device_type = false;
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
{
id = get_identifier ("omp declare target link");
@@ -19045,7 +19116,34 @@ c_parser_omp_declare_target (c_parser *parser)
}
}
}
+ if (TREE_CODE (t) != FUNCTION_DECL)
+ continue;
+ if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
+ {
+ tree at3 = lookup_attribute ("omp declare target host",
+ DECL_ATTRIBUTES (t));
+ if (at3 == NULL_TREE)
+ {
+ id = get_identifier ("omp declare target host");
+ DECL_ATTRIBUTES (t)
+ = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+ }
+ }
+ if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
+ {
+ tree at3 = lookup_attribute ("omp declare target nohost",
+ DECL_ATTRIBUTES (t));
+ if (at3 == NULL_TREE)
+ {
+ id = get_identifier ("omp declare target nohost");
+ DECL_ATTRIBUTES (t)
+ = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+ }
+ }
}
+ if (device_type && only_device_type)
+ warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
+ "directive with only %<device_type%> clauses ignored");
}
static void
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 9a1a910..2bbf0e2 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -13680,7 +13680,8 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
/* If ort == C_ORT_OMP_DECLARE_SIMD used as uniform_head instead. */
bitmap_initialize (&map_head, &bitmap_default_obstack);
bitmap_initialize (&map_field_head, &bitmap_default_obstack);
- /* If ort == C_ORT_OMP used as nontemporal_head instead. */
+ /* If ort == C_ORT_OMP used as nontemporal_head or use_device_xxx_head
+ instead. */
bitmap_initialize (&oacc_reduction_head, &bitmap_default_obstack);
if (ort & C_ORT_ACC)
@@ -14072,13 +14073,19 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
remove = true;
}
- else if (ort == C_ORT_ACC
- && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
+ else if ((ort == C_ORT_ACC
+ && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
+ || (ort == C_ORT_OMP
+ && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
+ || (OMP_CLAUSE_CODE (c)
+ == OMP_CLAUSE_USE_DEVICE_ADDR))))
{
if (bitmap_bit_p (&oacc_reduction_head, DECL_UID (t)))
{
error_at (OMP_CLAUSE_LOCATION (c),
- "%qD appears more than once in reduction clauses",
+ ort == C_ORT_ACC
+ ? "%qD appears more than once in reduction clauses"
+ : "%qD appears more than once in data clauses",
t);
remove = true;
}
@@ -14609,16 +14616,32 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
case OMP_CLAUSE_IS_DEVICE_PTR:
case OMP_CLAUSE_USE_DEVICE_PTR:
t = OMP_CLAUSE_DECL (c);
- if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE
- && TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE)
+ if (TREE_CODE (TREE_TYPE (t)) != POINTER_TYPE)
{
- error_at (OMP_CLAUSE_LOCATION (c),
- "%qs variable is neither a pointer nor an array",
- omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
- remove = true;
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
+ && ort == C_ORT_OMP)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qs variable is not a pointer",
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ }
+ else if (TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qs variable is neither a pointer nor an array",
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ }
}
goto check_dup_generic;
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
+ t = OMP_CLAUSE_DECL (c);
+ if (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
+ c_mark_addressable (t);
+ goto check_dup_generic;
+
case OMP_CLAUSE_NOWAIT:
if (copyprivate_seen)
{
@@ -14667,6 +14690,7 @@ c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
case OMP_CLAUSE_SECTIONS:
case OMP_CLAUSE_TASKGROUP:
case OMP_CLAUSE_PROC_BIND:
+ case OMP_CLAUSE_DEVICE_TYPE:
case OMP_CLAUSE_PRIORITY:
case OMP_CLAUSE_GRAINSIZE:
case OMP_CLAUSE_NUM_TASKS:
diff --git a/gcc/calls.c b/gcc/calls.c
index 6ab138e..54e30e6 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1350,7 +1350,6 @@ maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2])
location_t loc = EXPR_LOCATION (exp);
tree fntype = fn ? TREE_TYPE (fn) : TREE_TYPE (TREE_TYPE (exp));
- built_in_function fncode = fn ? DECL_FUNCTION_CODE (fn) : BUILT_IN_NONE;
bool warned = false;
/* Validate each argument individually. */
@@ -1376,11 +1375,10 @@ maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2])
friends.
Also avoid issuing the warning for calls to function named
"alloca". */
- if ((fncode == BUILT_IN_ALLOCA
- && IDENTIFIER_LENGTH (DECL_NAME (fn)) != 6)
- || (fncode != BUILT_IN_ALLOCA
- && !lookup_attribute ("returns_nonnull",
- TYPE_ATTRIBUTES (fntype))))
+ if (fn && fndecl_built_in_p (fn, BUILT_IN_ALLOCA)
+ ? IDENTIFIER_LENGTH (DECL_NAME (fn)) != 6
+ : !lookup_attribute ("returns_nonnull",
+ TYPE_ATTRIBUTES (fntype)))
warned = warning_at (loc, OPT_Walloc_zero,
"%Kargument %i value is zero",
exp, idx[i] + 1);
@@ -1395,7 +1393,7 @@ maybe_warn_alloc_args_overflow (tree fn, tree exp, tree args[2], int idx[2])
&& fn
&& !args[1]
&& lang_GNU_CXX ()
- && DECL_IS_OPERATOR_NEW (fn)
+ && DECL_IS_OPERATOR_NEW_P (fn)
&& integer_all_onesp (args[i]))
continue;
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index bdef400..39fc7aa 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -1214,10 +1214,7 @@ patch_jump_insn (rtx_insn *insn, rtx_insn *old_label, basic_block new_bb)
}
/* Handle casesi dispatch insns. */
- if ((tmp = single_set (insn)) != NULL
- && SET_DEST (tmp) == pc_rtx
- && GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE
- && GET_CODE (XEXP (SET_SRC (tmp), 2)) == LABEL_REF
+ if ((tmp = tablejump_casesi_pattern (insn)) != NULL_RTX
&& label_ref_label (XEXP (SET_SRC (tmp), 2)) == old_label)
{
XEXP (SET_SRC (tmp), 2) = gen_rtx_LABEL_REF (Pmode,
@@ -3703,13 +3700,13 @@ relink_block_chain (bool stay_in_cfglayout_mode)
{
fprintf (dump_file, " %i ", index);
if (get_bb_original (bb))
- fprintf (dump_file, "duplicate of %i ",
+ fprintf (dump_file, "duplicate of %i\n",
get_bb_original (bb)->index);
else if (forwarder_block_p (bb)
&& !LABEL_P (BB_HEAD (bb)))
- fprintf (dump_file, "compensation ");
+ fprintf (dump_file, "compensation\n");
else
- fprintf (dump_file, "bb %i ", bb->index);
+ fprintf (dump_file, "bb %i\n", bb->index);
}
}
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 477db38..ea8ab38 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -846,17 +846,8 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee,
gcc_assert (is_gimple_call (call_stmt));
}
- if (free_edges)
- {
- edge = free_edges;
- free_edges = NEXT_FREE_EDGE (edge);
- }
- else
- {
- edge = ggc_alloc<cgraph_edge> ();
- edge->m_summary_id = -1;
- }
-
+ edge = ggc_alloc<cgraph_edge> ();
+ edge->m_summary_id = -1;
edges_count++;
gcc_assert (++edges_max_uid != 0);
@@ -1013,16 +1004,13 @@ cgraph_edge::remove_caller (void)
void
symbol_table::free_edge (cgraph_edge *e)
{
+ edges_count--;
+ if (e->m_summary_id != -1)
+ edge_released_summary_ids.safe_push (e->m_summary_id);
+
if (e->indirect_info)
ggc_free (e->indirect_info);
-
- /* Clear out the edge so we do not dangle pointers. */
- int summary_id = e->m_summary_id;
- memset (e, 0, sizeof (*e));
- e->m_summary_id = summary_id;
- NEXT_FREE_EDGE (e) = free_edges;
- free_edges = e;
- edges_count--;
+ ggc_free (e);
}
/* Remove the edge in the cgraph. */
@@ -1227,7 +1215,7 @@ cgraph_edge::make_direct (cgraph_node *callee)
edge = edge->resolve_speculation (callee->decl);
/* On successful speculation just return the pre existing direct edge. */
- if (!indirect_unknown_callee)
+ if (!edge->indirect_unknown_callee)
return edge;
}
@@ -1779,8 +1767,6 @@ cgraph_node::release_body (bool keep_arguments)
void
cgraph_node::remove (void)
{
- cgraph_node *n;
-
if (symtab->ipa_clones_dump_file && symtab->cloned_nodes.contains (this))
fprintf (symtab->ipa_clones_dump_file,
"Callgraph removal;%s;%d;%s;%d;%d\n", asm_name (), order,
@@ -1797,8 +1783,13 @@ cgraph_node::remove (void)
*/
force_output = false;
forced_by_abi = false;
- for (n = nested; n; n = n->next_nested)
+ cgraph_node *next = nested;
+ for (cgraph_node *n = nested; n; n = next)
+ {
+ next = n->next_nested;
n->origin = NULL;
+ n->next_nested = NULL;
+ }
nested = NULL;
if (origin)
{
@@ -1852,7 +1843,7 @@ cgraph_node::remove (void)
*/
if (symtab->state != LTO_STREAMING)
{
- n = cgraph_node::get (decl);
+ cgraph_node *n = cgraph_node::get (decl);
if (!n
|| (!n->clones && !n->clone_of && !n->global.inlined_to
&& ((symtab->global_info_ready || in_lto_p)
@@ -2092,6 +2083,11 @@ cgraph_node::dump (FILE *f)
fprintf (f, " optimize_size");
if (parallelized_function)
fprintf (f, " parallelized_function");
+ if (DECL_IS_OPERATOR_NEW_P (decl))
+ fprintf (f, " operator_new");
+ if (DECL_IS_OPERATOR_DELETE_P (decl))
+ fprintf (f, " operator_delete");
+
fprintf (f, "\n");
@@ -2771,7 +2767,7 @@ cgraph_edge::cannot_lead_to_return_p (void)
return callee->cannot_return_p ();
}
-/* Return true if the call can be hot. */
+/* Return true if the edge may be considered hot. */
bool
cgraph_edge::maybe_hot_p (void)
@@ -2797,8 +2793,7 @@ cgraph_edge::maybe_hot_p (void)
if (caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE
&& sreal_frequency () * 2 < 3)
return false;
- if (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) == 0
- || sreal_frequency () * PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) <= 1)
+ if (sreal_frequency () * PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) <= 1)
return false;
return true;
}
@@ -3472,6 +3467,30 @@ cgraph_node::verify_node (void)
e->aux = 0;
}
}
+
+ if (nested != NULL)
+ {
+ for (cgraph_node *n = nested; n != NULL; n = n->next_nested)
+ {
+ if (n->origin == NULL)
+ {
+ error ("missing origin for a node in a nested list");
+ error_found = true;
+ }
+ else if (n->origin != this)
+ {
+ error ("origin points to a different parent");
+ error_found = true;
+ break;
+ }
+ }
+ }
+ if (next_nested != NULL && origin == NULL)
+ {
+ error ("missing origin for a node in a nested list");
+ error_found = true;
+ }
+
if (error_found)
{
dump (stderr);
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index a7c97de..4c54210 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1746,7 +1746,7 @@ public:
/* Return true when the edge represents a direct recursion. */
bool recursive_p (void);
- /* Return true if the call can be hot. */
+ /* Return true if the edge may be considered hot. */
bool maybe_hot_p (void);
/* Get unique identifier of the edge. */
@@ -2027,12 +2027,6 @@ is_a_helper <varpool_node *>::test (symtab_node *p)
return p && p->type == SYMTAB_VARIABLE;
}
-/* Macros to access the next item in the list of free cgraph nodes and
- edges. */
-#define NEXT_FREE_NODE(NODE) dyn_cast<cgraph_node *> ((NODE)->next)
-#define SET_NEXT_FREE_NODE(NODE,NODE2) ((NODE))->next = NODE2
-#define NEXT_FREE_EDGE(EDGE) (EDGE)->prev_caller
-
typedef void (*cgraph_edge_hook)(cgraph_edge *, void *);
typedef void (*cgraph_node_hook)(cgraph_node *, void *);
typedef void (*varpool_node_hook)(varpool_node *, void *);
@@ -2088,7 +2082,8 @@ public:
friend struct cgraph_edge;
symbol_table (): cgraph_max_uid (1), cgraph_max_summary_id (0),
- edges_max_uid (1), edges_max_summary_id (0)
+ edges_max_uid (1), edges_max_summary_id (0),
+ cgraph_released_summary_ids (), edge_released_summary_ids ()
{
}
@@ -2297,14 +2292,22 @@ public:
/* Assign a new summary ID for the callgraph NODE. */
inline int assign_summary_id (cgraph_node *node)
{
- node->m_summary_id = cgraph_max_summary_id++;
+ if (!cgraph_released_summary_ids.is_empty ())
+ node->m_summary_id = cgraph_released_summary_ids.pop ();
+ else
+ node->m_summary_id = cgraph_max_summary_id++;
+
return node->m_summary_id;
}
/* Assign a new summary ID for the callgraph EDGE. */
inline int assign_summary_id (cgraph_edge *edge)
{
- edge->m_summary_id = edges_max_summary_id++;
+ if (!edge_released_summary_ids.is_empty ())
+ edge->m_summary_id = edge_released_summary_ids.pop ();
+ else
+ edge->m_summary_id = edges_max_summary_id++;
+
return edge->m_summary_id;
}
@@ -2320,14 +2323,15 @@ public:
int edges_max_uid;
int edges_max_summary_id;
+ /* Vector of released summary IDS for cgraph nodes. */
+ vec<int> GTY ((skip)) cgraph_released_summary_ids;
+
+ /* Vector of released summary IDS for cgraph nodes. */
+ vec<int> GTY ((skip)) edge_released_summary_ids;
+
symtab_node* GTY(()) nodes;
asm_node* GTY(()) asmnodes;
asm_node* GTY(()) asm_last_node;
- cgraph_node* GTY(()) free_nodes;
-
- /* Head of a linked list of unused (freed) call graph edges.
- Do not GTY((delete)) this list so UIDs gets reliably recycled. */
- cgraph_edge * GTY(()) free_edges;
/* The order index of the next symtab node to be created. This is
used so that we can sort the cgraph nodes in order by when we saw
@@ -2687,15 +2691,9 @@ inline void
symbol_table::release_symbol (cgraph_node *node)
{
cgraph_count--;
-
- /* Clear out the node to NULL all pointers and add the node to the free
- list. */
- int summary_id = node->m_summary_id;
- memset (node, 0, sizeof (*node));
- node->type = SYMTAB_FUNCTION;
- node->m_summary_id = summary_id;
- SET_NEXT_FREE_NODE (node, free_nodes);
- free_nodes = node;
+ if (node->m_summary_id != -1)
+ cgraph_released_summary_ids.safe_push (node->m_summary_id);
+ ggc_free (node);
}
/* Allocate new callgraph node. */
@@ -2705,17 +2703,9 @@ symbol_table::allocate_cgraph_symbol (void)
{
cgraph_node *node;
- if (free_nodes)
- {
- node = free_nodes;
- free_nodes = NEXT_FREE_NODE (node);
- }
- else
- {
- node = ggc_cleared_alloc<cgraph_node> ();
- node->m_summary_id = -1;
- }
-
+ node = ggc_cleared_alloc<cgraph_node> ();
+ node->type = SYMTAB_FUNCTION;
+ node->m_summary_id = -1;
node->m_uid = cgraph_max_uid++;
return node;
}
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index fd867ec..fa75369 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -225,10 +225,7 @@ build_function_decl_skip_args (tree orig_decl, bitmap args_to_skip,
if (fndecl_built_in_p (new_decl)
&& args_to_skip
&& !bitmap_empty_p (args_to_skip))
- {
- DECL_BUILT_IN_CLASS (new_decl) = NOT_BUILT_IN;
- DECL_FUNCTION_CODE (new_decl) = (enum built_in_function) 0;
- }
+ set_decl_built_in_function (new_decl, NOT_BUILT_IN, 0);
/* The FE might have information and assumptions about the other
arguments. */
DECL_LANG_SPECIFIC (new_decl) = NULL;
@@ -248,6 +245,8 @@ set_new_clone_decl_and_node_flags (cgraph_node *new_node)
DECL_VIRTUAL_P (new_node->decl) = 0;
DECL_STATIC_CONSTRUCTOR (new_node->decl) = 0;
DECL_STATIC_DESTRUCTOR (new_node->decl) = 0;
+ DECL_SET_IS_OPERATOR_NEW (new_node->decl, 0);
+ DECL_SET_IS_OPERATOR_DELETE (new_node->decl, 0);
new_node->externally_visible = 0;
new_node->local.local = 1;
@@ -1065,6 +1064,8 @@ cgraph_node::create_version_clone_with_body
/* When the old decl was a con-/destructor make sure the clone isn't. */
DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
DECL_STATIC_DESTRUCTOR (new_decl) = 0;
+ DECL_SET_IS_OPERATOR_NEW (new_decl, 0);
+ DECL_SET_IS_OPERATOR_DELETE (new_decl, 0);
/* Create the new version's call-graph node.
and update the edges of the new node. */
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 5999b9e..cb08efe 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -2613,8 +2613,11 @@ symbol_table::compile (void)
/* Don't run the IPA passes if there was any error or sorry messages. */
if (!seen_error ())
+ {
+ timevar_start (TV_CGRAPH_IPA_PASSES);
ipa_passes ();
-
+ timevar_stop (TV_CGRAPH_IPA_PASSES);
+ }
/* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */
if (seen_error ()
|| ((!in_lto_p || flag_incremental_link == INCREMENTAL_LINK_LTO)
@@ -2680,7 +2683,11 @@ symbol_table::compile (void)
/* Output first asm statements and anything ordered. The process
flag is cleared for these nodes, so we skip them later. */
output_in_order ();
+
+ timevar_start (TV_CGRAPH_FUNC_EXPANSION);
expand_all_functions ();
+ timevar_stop (TV_CGRAPH_FUNC_EXPANSION);
+
output_variables ();
process_new_functions ();
diff --git a/gcc/cif-code.def b/gcc/cif-code.def
index cee16cf..ccd08e2 100644
--- a/gcc/cif-code.def
+++ b/gcc/cif-code.def
@@ -83,6 +83,10 @@ DEFCIFCODE(RECURSIVE_INLINING, CIF_FINAL_NORMAL,
DEFCIFCODE(UNLIKELY_CALL, CIF_FINAL_NORMAL,
N_("call is unlikely and code size would grow"))
+/* Call is considered never executed. */
+DEFCIFCODE(NEVER_CALL, CIF_FINAL_NORMAL,
+ N_("call is considered never executed and code size would grow"))
+
/* Function is not declared as inline. */
DEFCIFCODE(NOT_DECLARED_INLINED, CIF_FINAL_NORMAL,
N_("function not declared inline and code size would grow"))
diff --git a/gcc/common.opt b/gcc/common.opt
index b998b25..c160538 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1955,7 +1955,7 @@ Common Var(flag_dce) Init(1) Optimization
Use the RTL dead code elimination pass.
fdse
-Common Var(flag_dse) Init(1) Optimization
+Common Var(flag_dse) Init(0) Optimization
Use the RTL dead store elimination pass.
freschedule-modulo-scheduled-loops
@@ -2211,6 +2211,10 @@ Enum(live_patching_level) String(inline-only-static) Value(LIVE_PATCHING_INLINE_
EnumValue
Enum(live_patching_level) String(inline-clone) Value(LIVE_PATCHING_INLINE_CLONE)
+fallocation-dce
+Common Report Var(flag_allocation_dce) Init(1) Optimization
+Tell DCE to remove unused C++ allocations.
+
flive-range-shrinkage
Common Report Var(flag_live_range_shrinkage) Init(0) Optimization
Relief of register pressure through live range shrinkage.
diff --git a/gcc/common/config/riscv/riscv-common.c b/gcc/common/config/riscv/riscv-common.c
index eeb7571..a16d6c5 100644
--- a/gcc/common/config/riscv/riscv-common.c
+++ b/gcc/common/config/riscv/riscv-common.c
@@ -513,6 +513,13 @@ riscv_subset_list::parse (const char *arch, location_t loc)
if (p == NULL)
goto fail;
+ if (*p != '\0')
+ {
+ error_at (loc, "%<-march=%s%>: unexpected ISA string at end: %qs",
+ arch, p);
+ goto fail;
+ }
+
return subset_list;
fail:
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 58262e5..40cbc52 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -673,7 +673,7 @@ x86_cpus="generic intel"
# Common parts for widely ported systems.
case ${target} in
*-*-darwin*)
- tmake_file="t-darwin ${cpu_type}/t-darwin"
+ tmake_file="t-darwin "
tm_file="${tm_file} darwin.h"
case ${target} in
*-*-darwin9*)
@@ -1522,6 +1522,14 @@ hppa*-*-openbsd*)
gas=yes
gnu_ld=yes
;;
+hppa*-*-netbsd*)
+ target_cpu_default="MASK_PA_11|MASK_NO_SPACE_REGS"
+ tm_file="${tm_file} dbxelf.h elfos.h ${nbsd_tm_file} \
+ pa/pa-netbsd.h pa/pa32-regs.h pa/pa32-netbsd.h"
+ tmake_file="${tmake_file}"
+ tm_defines="${tm_defines} CHAR_FAST8=1 SHORT_FAST16=1"
+ extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
+ ;;
hppa[12]*-*-hpux10*)
case ${target} in
hppa1.1-*-* | hppa2*-*-*)
@@ -1645,16 +1653,25 @@ hppa[12]*-*-hpux11*)
dwarf2=no
fi
;;
+i[34567]86-*-darwin1[89]*)
+ echo "Error: 32bit target is not supported after Darwin17" 1>&2
+ ;;
i[34567]86-*-darwin*)
need_64bit_isa=yes
# Baseline choice for a machine that allows m64 support.
with_cpu=${with_cpu:-core2}
+ tmake_file="${tmake_file} ${cpu_type}/t-darwin32-biarch t-slibgcc"
+ tm_file="${tm_file} ${cpu_type}/darwin32-biarch.h"
+ ;;
+x86_64-*-darwin1[89]* | x86_64-*-darwin2[01]*)
+ # Only 64b from now
+ with_cpu=${with_cpu:-core2}
tmake_file="${tmake_file} t-slibgcc"
;;
x86_64-*-darwin*)
with_cpu=${with_cpu:-core2}
- tmake_file="${tmake_file} ${cpu_type}/t-darwin64 t-slibgcc"
- tm_file="${tm_file} ${cpu_type}/darwin64.h"
+ tmake_file="${tmake_file} ${cpu_type}/t-darwin64-biarch t-slibgcc"
+ tm_file="${tm_file} ${cpu_type}/darwin64-biarch.h"
;;
i[34567]86-*-elfiamcu)
tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h newlib-stdint.h i386/iamcu.h"
@@ -2502,7 +2519,14 @@ msp430*-*-*)
c_target_objs="msp430-c.o"
cxx_target_objs="msp430-c.o"
tmake_file="${tmake_file} msp430/t-msp430"
- extra_gcc_objs="driver-msp430.o"
+ extra_objs="${extra_objs} msp430-devices.o"
+ extra_gcc_objs="driver-msp430.o msp430-devices.o"
+ # Enable .init_array unless it has been explicitly disabled.
+ # The MSP430 EABI mandates the use of .init_array, and the Newlib CRT
+ # code since mid-2019 expects it.
+ if test x${disable_initfini_array} != xyes; then
+ gcc_cv_initfini_array=yes
+ fi
;;
nds32*-*-*)
target_cpu_default="0"
@@ -2616,24 +2640,31 @@ pdp11-*-*)
# extra_headers=
# ;;
powerpc-*-darwin*)
- extra_options="${extra_options} rs6000/darwin.opt"
+ extra_options="${extra_options} ${cpu_type}/darwin.opt"
case ${target} in
- *-darwin1[0-9]* | *-darwin[8-9]*)
- tmake_file="${tmake_file} rs6000/t-darwin8"
- tm_file="${tm_file} rs6000/darwin8.h"
+ *-darwin1[0-9]* | *-darwin9*)
+ tmake_file="${tmake_file} ${cpu_type}/t-darwin32-biarch"
+ tm_file="${tm_file} ${cpu_type}/darwin32-biarch.h"
+ ;;
+ *-darwin8*)
+ tmake_file="${tmake_file} ${cpu_type}/t-darwin32-biarch"
+ tm_file="${tm_file} ${cpu_type}/darwin32-biarch.h"
+ tm_file="${tm_file} ${cpu_type}/darwin8.h"
;;
*-darwin7*)
- tm_file="${tm_file} rs6000/darwin7.h"
+ tm_file="${tm_file} ${cpu_type}/darwin7.h"
;;
- *-darwin[0-6]*)
+ *-darwin[456]*)
+ # Earlier - ingle arch, with 32b only
+ # OS X 10.0, the first edition is Darwin4
;;
esac
tmake_file="${tmake_file} t-slibgcc"
;;
powerpc64-*-darwin*)
extra_options="${extra_options} ${cpu_type}/darwin.opt"
- tmake_file="${tmake_file} ${cpu_type}/t-darwin64 t-slibgcc"
- tm_file="${tm_file} ${cpu_type}/darwin8.h ${cpu_type}/darwin64.h"
+ tmake_file="${tmake_file} ${cpu_type}/t-darwin64-biarch t-slibgcc"
+ tm_file="${tm_file} ${cpu_type}/darwin64-biarch.h"
;;
powerpc*-*-freebsd*)
tm_file="${tm_file} dbxelf.h elfos.h gnu-user.h ${fbsd_tm_file} rs6000/sysv4.h"
@@ -3880,32 +3911,40 @@ case "${target}" in
sed -e 's/,.*$//'`
fi
+ # Use the pre-processor to strip flatten the options.
+ # This makes the format less rigid than if we use
+ # grep and sed directly here.
+ opt_macro="AARCH64_OPT_EXTENSION(A, B, C, D, E, F)=A, B, C, D, E, F"
+ options_parsed="`$ac_cv_prog_CPP -D"$opt_macro" -x c \
+ ${srcdir}/config/aarch64/aarch64-option-extensions.def`"
+
+ # Match one element inside AARCH64_OPT_EXTENSION, we
+ # consume anything that's not a ,.
+ elem="[ ]*\([^,]\+\)[ ]*"
+
+ # Repeat the pattern for the number of entries in the
+ # AARCH64_OPT_EXTENSION, currently 6 times.
+ sed_patt="^$elem,$elem,$elem,$elem,$elem,$elem"
+
while [ x"$ext_val" != x ]
do
ext_val=`echo $ext_val | sed -e 's/\+//'`
ext=`echo $ext_val | sed -e 's/\+.*//'`
base_ext=`echo $ext | sed -e 's/^no//'`
+ opt_line=`echo -e "$options_parsed" | \
+ grep "^\"$base_ext\""`
if [ x"$base_ext" = x ] \
- || grep "^AARCH64_OPT_EXTENSION(\"$base_ext\"," \
- ${srcdir}/config/aarch64/aarch64-option-extensions.def \
- > /dev/null; then
-
- ext_canon=`grep "^AARCH64_OPT_EXTENSION(\"$base_ext\"," \
- ${srcdir}/config/aarch64/aarch64-option-extensions.def | \
- sed -e 's/^[^,]*,[ ]*//' | \
- sed -e 's/,.*$//'`
- ext_on=`grep "^AARCH64_OPT_EXTENSION(\"$base_ext\"," \
- ${srcdir}/config/aarch64/aarch64-option-extensions.def | \
- sed -e 's/^[^,]*,[ ]*[^,]*,[ ]*//' | \
- sed -e 's/,.*$//' | \
- sed -e 's/).*$//'`
- ext_off=`grep "^AARCH64_OPT_EXTENSION(\"$base_ext\"," \
- ${srcdir}/config/aarch64/aarch64-option-extensions.def | \
- sed -e 's/^[^,]*,[ ]*[^,]*,[ ]*[^,]*,[ ]*//' | \
- sed -e 's/,.*$//' | \
- sed -e 's/).*$//'`
-
+ || [[ -n $opt_line ]]; then
+
+ # These regexp extract the elements based on
+ # their group match index in the regexp.
+ ext_canon=`echo -e "$opt_line" | \
+ sed -e "s/$sed_patt/\2/"`
+ ext_on=`echo -e "$opt_line" | \
+ sed -e "s/$sed_patt/\3/"`
+ ext_off=`echo -e "$opt_line" | \
+ sed -e "s/$sed_patt/\4/"`
if [ $ext = $base_ext ]; then
# Adding extension
diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
index 549a6c2..2fc5cf7 100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -438,6 +438,11 @@ enum aarch64_builtins
/* Special cased Armv8.3-A Complex FMA by Lane quad Builtins. */
AARCH64_SIMD_FCMLA_LANEQ_BUILTIN_BASE,
AARCH64_SIMD_FCMLA_LANEQ_BUILTINS
+ /* TME builtins. */
+ AARCH64_TME_BUILTIN_TSTART,
+ AARCH64_TME_BUILTIN_TCOMMIT,
+ AARCH64_TME_BUILTIN_TTEST,
+ AARCH64_TME_BUILTIN_TCANCEL,
AARCH64_BUILTIN_MAX
};
@@ -1067,6 +1072,35 @@ aarch64_init_pauth_hint_builtins (void)
NULL_TREE);
}
+/* Initialize the transactional memory extension (TME) builtins. */
+static void
+aarch64_init_tme_builtins (void)
+{
+ tree ftype_uint64_void
+ = build_function_type_list (uint64_type_node, NULL);
+ tree ftype_void_void
+ = build_function_type_list (void_type_node, NULL);
+ tree ftype_void_uint64
+ = build_function_type_list (void_type_node, uint64_type_node, NULL);
+
+ aarch64_builtin_decls[AARCH64_TME_BUILTIN_TSTART]
+ = add_builtin_function ("__builtin_aarch64_tstart", ftype_uint64_void,
+ AARCH64_TME_BUILTIN_TSTART, BUILT_IN_MD,
+ NULL, NULL_TREE);
+ aarch64_builtin_decls[AARCH64_TME_BUILTIN_TTEST]
+ = add_builtin_function ("__builtin_aarch64_ttest", ftype_uint64_void,
+ AARCH64_TME_BUILTIN_TTEST, BUILT_IN_MD,
+ NULL, NULL_TREE);
+ aarch64_builtin_decls[AARCH64_TME_BUILTIN_TCOMMIT]
+ = add_builtin_function ("__builtin_aarch64_tcommit", ftype_void_void,
+ AARCH64_TME_BUILTIN_TCOMMIT, BUILT_IN_MD,
+ NULL, NULL_TREE);
+ aarch64_builtin_decls[AARCH64_TME_BUILTIN_TCANCEL]
+ = add_builtin_function ("__builtin_aarch64_tcancel", ftype_void_uint64,
+ AARCH64_TME_BUILTIN_TCANCEL, BUILT_IN_MD,
+ NULL, NULL_TREE);
+}
+
void
aarch64_init_builtins (void)
{
@@ -1104,6 +1138,9 @@ aarch64_init_builtins (void)
register them. */
if (!TARGET_ILP32)
aarch64_init_pauth_hint_builtins ();
+
+ if (TARGET_TME)
+ aarch64_init_tme_builtins ();
}
tree
@@ -1507,6 +1544,47 @@ aarch64_expand_fcmla_builtin (tree exp, rtx target, int fcode)
return target;
}
+/* Function to expand an expression EXP which calls one of the Transactional
+ Memory Extension (TME) builtins FCODE with the result going to TARGET. */
+static rtx
+aarch64_expand_builtin_tme (int fcode, tree exp, rtx target)
+{
+ switch (fcode)
+ {
+ case AARCH64_TME_BUILTIN_TSTART:
+ target = gen_reg_rtx (DImode);
+ emit_insn (GEN_FCN (CODE_FOR_tstart) (target));
+ break;
+
+ case AARCH64_TME_BUILTIN_TTEST:
+ target = gen_reg_rtx (DImode);
+ emit_insn (GEN_FCN (CODE_FOR_ttest) (target));
+ break;
+
+ case AARCH64_TME_BUILTIN_TCOMMIT:
+ emit_insn (GEN_FCN (CODE_FOR_tcommit) ());
+ break;
+
+ case AARCH64_TME_BUILTIN_TCANCEL:
+ {
+ tree arg0 = CALL_EXPR_ARG (exp, 0);
+ rtx op0 = expand_normal (arg0);
+ if (CONST_INT_P (op0) && UINTVAL (op0) <= 65536)
+ emit_insn (GEN_FCN (CODE_FOR_tcancel) (op0));
+ else
+ {
+ error ("%Kargument must be a 16-bit constant immediate", exp);
+ return const0_rtx;
+ }
+ }
+ break;
+
+ default :
+ gcc_unreachable ();
+ }
+ return target;
+}
+
/* Expand an expression EXP that calls a built-in function,
with result going to TARGET if that's convenient. */
rtx
@@ -1517,7 +1595,7 @@ aarch64_expand_builtin (tree exp,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- int fcode = DECL_FUNCTION_CODE (fndecl);
+ int fcode = DECL_MD_FUNCTION_CODE (fndecl);
int icode;
rtx pat, op0;
tree arg0;
@@ -1627,6 +1705,12 @@ aarch64_expand_builtin (tree exp,
|| fcode == AARCH64_BUILTIN_RSQRT_V4SF)
return aarch64_expand_builtin_rsqrt (fcode, exp, target);
+ if (fcode == AARCH64_TME_BUILTIN_TSTART
+ || fcode == AARCH64_TME_BUILTIN_TCOMMIT
+ || fcode == AARCH64_TME_BUILTIN_TTEST
+ || fcode == AARCH64_TME_BUILTIN_TCANCEL)
+ return aarch64_expand_builtin_tme (fcode, exp, target);
+
gcc_unreachable ();
}
@@ -1797,7 +1881,7 @@ tree
aarch64_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args,
bool ignore ATTRIBUTE_UNUSED)
{
- int fcode = DECL_FUNCTION_CODE (fndecl);
+ int fcode = DECL_MD_FUNCTION_CODE (fndecl);
tree type = TREE_TYPE (TREE_TYPE (fndecl));
switch (fcode)
@@ -1829,7 +1913,7 @@ aarch64_gimple_fold_builtin (gimple_stmt_iterator *gsi)
fndecl = gimple_call_fndecl (stmt);
if (fndecl)
{
- int fcode = DECL_FUNCTION_CODE (fndecl);
+ int fcode = DECL_MD_FUNCTION_CODE (fndecl);
unsigned nargs = gimple_call_num_args (stmt);
tree *args = (nargs > 0
? gimple_call_arg_ptr (stmt, 0)
diff --git a/gcc/config/aarch64/aarch64-c.c b/gcc/config/aarch64/aarch64-c.c
index 5af65b1..e532c6c 100644
--- a/gcc/config/aarch64/aarch64-c.c
+++ b/gcc/config/aarch64/aarch64-c.c
@@ -157,6 +157,8 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
aarch64_def_or_undef (TARGET_SM4, "__ARM_FEATURE_SM4", pfile);
aarch64_def_or_undef (TARGET_F16FML, "__ARM_FEATURE_FP16_FML", pfile);
+ aarch64_def_or_undef (TARGET_TME, "__ARM_FEATURE_TME", pfile);
+
/* Not for ACLE, but required to keep "float.h" correct if we switch
target between implementations that do or do not support ARMv8.2-A
16-bit floating-point extensions. */
diff --git a/gcc/config/aarch64/aarch64-cores.def b/gcc/config/aarch64/aarch64-cores.def
index 82d91d62..bd257ae 100644
--- a/gcc/config/aarch64/aarch64-cores.def
+++ b/gcc/config/aarch64/aarch64-cores.def
@@ -99,7 +99,7 @@ AARCH64_CORE("thunderx2t99", thunderx2t99, thunderx2t99, 8_1A, AARCH64_FL_FOR
/* ARM ('A') cores. */
AARCH64_CORE("cortex-a55", cortexa55, cortexa53, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, cortexa53, 0x41, 0xd05, -1)
AARCH64_CORE("cortex-a75", cortexa75, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, cortexa73, 0x41, 0xd0a, -1)
-AARCH64_CORE("cortex-a76", cortexa76, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, cortexa72, 0x41, 0xd0b, -1)
+AARCH64_CORE("cortex-a76", cortexa76, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD, neoversen1, 0x41, 0xd0b, -1)
AARCH64_CORE("ares", ares, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_PROFILE, neoversen1, 0x41, 0xd0c, -1)
AARCH64_CORE("neoverse-n1", neoversen1, cortexa57, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_PROFILE, neoversen1, 0x41, 0xd0c, -1)
AARCH64_CORE("neoverse-e1", neoversee1, cortexa53, 8_2A, AARCH64_FL_FOR_ARCH8_2 | AARCH64_FL_F16 | AARCH64_FL_RCPC | AARCH64_FL_DOTPROD | AARCH64_FL_SSBS, cortexa53, 0x41, 0xd4a, -1)
diff --git a/gcc/config/aarch64/aarch64-option-extensions.def b/gcc/config/aarch64/aarch64-option-extensions.def
index 403a694..9919edd 100644
--- a/gcc/config/aarch64/aarch64-option-extensions.def
+++ b/gcc/config/aarch64/aarch64-option-extensions.def
@@ -45,32 +45,43 @@
entries: aes, pmull, sha1, sha2 being present). In that case this field
should contain a space (" ") separated list of the strings in 'Features'
that are required. Their order is not important. An empty string means
- do not detect this feature during auto detection. */
+ do not detect this feature during auto detection.
-/* NOTE: This file is being parsed by config.gcc and so the
- AARCH64_OPT_EXTENSION must adhere to a strict format:
- 1) No space between the AARCH64_OPT_EXTENSION and the opening (.
- 2) No space between the opening ( and the extension name.
- 3) No space after the extension name before the ,.
- 4) Spaces are only allowed after a , and around |.
- 5) Everything must be on one line. */
+ NOTE: Any changes to the AARCH64_OPT_EXTENSION macro need to be mirrored in
+ config.gcc. */
/* Enabling "fp" just enables "fp".
Disabling "fp" also disables "simd", "crypto", "fp16", "aes", "sha2",
"sha3", sm3/sm4, "sve", "sve2", "sve2-aes", "sve2-sha3", "sve2-sm4", and
"sve2-bitperm". */
-AARCH64_OPT_EXTENSION("fp", AARCH64_FL_FP, 0, AARCH64_FL_SIMD | AARCH64_FL_CRYPTO | AARCH64_FL_F16 | AARCH64_FL_AES | AARCH64_FL_SHA2 | AARCH64_FL_SHA3 | AARCH64_FL_SM4 | AARCH64_FL_SVE | AARCH64_FL_SVE2 | AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, "fp")
+AARCH64_OPT_EXTENSION("fp", AARCH64_FL_FP, 0, AARCH64_FL_SIMD | \
+ AARCH64_FL_CRYPTO | AARCH64_FL_F16 | AARCH64_FL_AES | \
+ AARCH64_FL_SHA2 | AARCH64_FL_SHA3 | AARCH64_FL_SM4 | \
+ AARCH64_FL_SVE | AARCH64_FL_SVE2 | AARCH64_FL_SVE2_AES | \
+ AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | \
+ AARCH64_FL_SVE2_BITPERM, false, "fp")
/* Enabling "simd" also enables "fp".
Disabling "simd" also disables "crypto", "dotprod", "aes", "sha2", "sha3",
"sm3/sm4", "sve", "sve2", "sve2-aes", "sve2-sha3", "sve2-sm4", and
"sve2-bitperm". */
-AARCH64_OPT_EXTENSION("simd", AARCH64_FL_SIMD, AARCH64_FL_FP, AARCH64_FL_CRYPTO | AARCH64_FL_DOTPROD | AARCH64_FL_AES | AARCH64_FL_SHA2 | AARCH64_FL_SHA3 | AARCH64_FL_SM4 | AARCH64_FL_SVE | AARCH64_FL_SVE2 | AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, "asimd")
+AARCH64_OPT_EXTENSION("simd", AARCH64_FL_SIMD, AARCH64_FL_FP, \
+ AARCH64_FL_CRYPTO | AARCH64_FL_DOTPROD | \
+ AARCH64_FL_AES | AARCH64_FL_SHA2 | AARCH64_FL_SHA3 | \
+ AARCH64_FL_SM4 | AARCH64_FL_SVE | AARCH64_FL_SVE2 | \
+ AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | \
+ AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, \
+ "asimd")
/* Enabling "crypto" also enables "fp", "simd", "aes" and "sha2".
Disabling "crypto" disables "crypto", "aes", "sha2", "sha3" and "sm3/sm4",
"sve2-aes", "sve2-sha3", "sve2-sm4". */
-AARCH64_OPT_EXTENSION("crypto", AARCH64_FL_CRYPTO, AARCH64_FL_FP | AARCH64_FL_SIMD | AARCH64_FL_AES | AARCH64_FL_SHA2, AARCH64_FL_AES | AARCH64_FL_SHA2 | AARCH64_FL_SHA3 | AARCH64_FL_SM4 | AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4, true, "aes pmull sha1 sha2")
+AARCH64_OPT_EXTENSION("crypto", AARCH64_FL_CRYPTO, AARCH64_FL_FP | \
+ AARCH64_FL_SIMD | AARCH64_FL_AES | AARCH64_FL_SHA2, \
+ AARCH64_FL_AES | AARCH64_FL_SHA2 | AARCH64_FL_SHA3 | \
+ AARCH64_FL_SM4 | AARCH64_FL_SVE2_AES | \
+ AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4, true, \
+ "aes pmull sha1 sha2")
/* Enabling or disabling "crc" only changes "crc". */
AARCH64_OPT_EXTENSION("crc", AARCH64_FL_CRC, 0, 0, false, "crc32")
@@ -80,44 +91,59 @@ AARCH64_OPT_EXTENSION("lse", AARCH64_FL_LSE, 0, 0, false, "atomics")
/* Enabling "fp16" also enables "fp".
Disabling "fp16" disables "fp16", "fp16fml", "sve", "sve2", "sve2-aes",
- "sve2-sha3", "sve2-sm4", and "sve2-bitperm". */
-AARCH64_OPT_EXTENSION("fp16", AARCH64_FL_F16, AARCH64_FL_FP, AARCH64_FL_F16FML | AARCH64_FL_SVE | AARCH64_FL_SVE2 | AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, "fphp asimdhp")
+ "sve2-sha3", "sve2-sm4", and "bitperm". */
+AARCH64_OPT_EXTENSION("fp16", AARCH64_FL_F16, AARCH64_FL_FP, \
+ AARCH64_FL_F16FML | AARCH64_FL_SVE | AARCH64_FL_SVE2 | \
+ AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | \
+ AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, \
+ "fphp asimdhp")
/* Enabling or disabling "rcpc" only changes "rcpc". */
AARCH64_OPT_EXTENSION("rcpc", AARCH64_FL_RCPC, 0, 0, false, "lrcpc")
/* Enabling "rdma" also enables "fp", "simd".
Disabling "rdma" just disables "rdma". */
-AARCH64_OPT_EXTENSION("rdma", AARCH64_FL_RDMA, AARCH64_FL_FP | AARCH64_FL_SIMD, 0, false, "asimdrdm")
+AARCH64_OPT_EXTENSION("rdma", AARCH64_FL_RDMA, \
+ AARCH64_FL_FP | AARCH64_FL_SIMD, 0, false, "asimdrdm")
/* Enabling "dotprod" also enables "simd".
Disabling "dotprod" only disables "dotprod". */
-AARCH64_OPT_EXTENSION("dotprod", AARCH64_FL_DOTPROD, AARCH64_FL_SIMD, 0, false, "asimddp")
+AARCH64_OPT_EXTENSION("dotprod", AARCH64_FL_DOTPROD, AARCH64_FL_SIMD, 0, \
+ false, "asimddp")
/* Enabling "aes" also enables "simd".
Disabling "aes" disables "aes" and "sve2-aes'. */
-AARCH64_OPT_EXTENSION("aes", AARCH64_FL_AES, AARCH64_FL_SIMD, AARCH64_FL_SVE2_AES, false, "aes")
+AARCH64_OPT_EXTENSION("aes", AARCH64_FL_AES, AARCH64_FL_SIMD, \
+ AARCH64_FL_SVE2_AES, false, "aes")
/* Enabling "sha2" also enables "simd".
Disabling "sha2" just disables "sha2". */
-AARCH64_OPT_EXTENSION("sha2", AARCH64_FL_SHA2, AARCH64_FL_SIMD, 0, false, "sha1 sha2")
+AARCH64_OPT_EXTENSION("sha2", AARCH64_FL_SHA2, AARCH64_FL_SIMD, 0, false, \
+ "sha1 sha2")
/* Enabling "sha3" enables "simd" and "sha2".
Disabling "sha3" disables "sha3" and "sve2-sha3". */
-AARCH64_OPT_EXTENSION("sha3", AARCH64_FL_SHA3, AARCH64_FL_SIMD | AARCH64_FL_SHA2, AARCH64_FL_SVE2_SHA3, false, "sha3 sha512")
+AARCH64_OPT_EXTENSION("sha3", AARCH64_FL_SHA3, AARCH64_FL_SIMD | \
+ AARCH64_FL_SHA2, AARCH64_FL_SVE2_SHA3, false, \
+ "sha3 sha512")
/* Enabling "sm4" also enables "simd".
Disabling "sm4" disables "sm4" and "sve2-sm4". */
-AARCH64_OPT_EXTENSION("sm4", AARCH64_FL_SM4, AARCH64_FL_SIMD, AARCH64_FL_SVE2_SM4, false, "sm3 sm4")
+AARCH64_OPT_EXTENSION("sm4", AARCH64_FL_SM4, AARCH64_FL_SIMD, \
+ AARCH64_FL_SVE2_SM4, false, "sm3 sm4")
/* Enabling "fp16fml" also enables "fp" and "fp16".
Disabling "fp16fml" just disables "fp16fml". */
-AARCH64_OPT_EXTENSION("fp16fml", AARCH64_FL_F16FML, AARCH64_FL_FP | AARCH64_FL_F16, 0, false, "asimdfml")
+AARCH64_OPT_EXTENSION("fp16fml", AARCH64_FL_F16FML, \
+ AARCH64_FL_FP | AARCH64_FL_F16, 0, false, "asimdfml")
/* Enabling "sve" also enables "fp16", "fp" and "simd".
Disabling "sve" disables "sve", "sve2", "sve2-aes", "sve2-sha3", "sve2-sm4"
and "sve2-bitperm". */
-AARCH64_OPT_EXTENSION("sve", AARCH64_FL_SVE, AARCH64_FL_FP | AARCH64_FL_SIMD | AARCH64_FL_F16, AARCH64_FL_SVE2 | AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, "sve")
+AARCH64_OPT_EXTENSION("sve", AARCH64_FL_SVE, AARCH64_FL_FP | AARCH64_FL_SIMD | \
+ AARCH64_FL_F16, AARCH64_FL_SVE2 | AARCH64_FL_SVE2_AES | \
+ AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | \
+ AARCH64_FL_SVE2_BITPERM, false, "sve")
/* Enabling/Disabling "profile" does not enable/disable any other feature. */
AARCH64_OPT_EXTENSION("profile", AARCH64_FL_PROFILE, 0, 0, false, "")
@@ -140,22 +166,36 @@ AARCH64_OPT_EXTENSION("predres", AARCH64_FL_PREDRES, 0, 0, false, "")
/* Enabling "sve2" also enables "sve", "fp16", "fp", and "simd".
Disabling "sve2" disables "sve2", "sve2-aes", "sve2-sha3", "sve2-sm4", and
"sve2-bitperm". */
-AARCH64_OPT_EXTENSION("sve2", AARCH64_FL_SVE2, AARCH64_FL_SVE | AARCH64_FL_FP | AARCH64_FL_SIMD | AARCH64_FL_F16, AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, "")
+AARCH64_OPT_EXTENSION("sve2", AARCH64_FL_SVE2, AARCH64_FL_SVE | \
+ AARCH64_FL_FP | AARCH64_FL_SIMD | AARCH64_FL_F16, \
+ AARCH64_FL_SVE2_AES | AARCH64_FL_SVE2_SHA3 | \
+ AARCH64_FL_SVE2_SM4 | AARCH64_FL_SVE2_BITPERM, false, "")
/* Enabling "sve2-sm4" also enables "sm4", "simd", "fp16", "fp", "sve", and
"sve2". Disabling "sve2-sm4" just disables "sve2-sm4". */
-AARCH64_OPT_EXTENSION("sve2-sm4", AARCH64_FL_SVE2_SM4, AARCH64_FL_SM4 | AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "")
+AARCH64_OPT_EXTENSION("sve2-sm4", AARCH64_FL_SVE2_SM4, AARCH64_FL_SM4 | \
+ AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | \
+ AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "")
/* Enabling "sve2-aes" also enables "aes", "simd", "fp16", "fp", "sve", and
"sve2". Disabling "sve2-aes" just disables "sve2-aes". */
-AARCH64_OPT_EXTENSION("sve2-aes", AARCH64_FL_SVE2_AES, AARCH64_FL_AES | AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "")
+AARCH64_OPT_EXTENSION("sve2-aes", AARCH64_FL_SVE2_AES, AARCH64_FL_AES | \
+ AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | \
+ AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "")
/* Enabling "sve2-sha3" also enables "sha3", "simd", "fp16", "fp", "sve", and
"sve2". Disabling "sve2-sha3" just disables "sve2-sha3". */
-AARCH64_OPT_EXTENSION("sve2-sha3", AARCH64_FL_SVE2_SHA3, AARCH64_FL_SHA3 | AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "")
+AARCH64_OPT_EXTENSION("sve2-sha3", AARCH64_FL_SVE2_SHA3, AARCH64_FL_SHA3 | \
+ AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | \
+ AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "")
/* Enabling "sve2-bitperm" also enables "simd", "fp16", "fp", "sve", and
"sve2". Disabling "sve2-bitperm" just disables "sve2-bitperm". */
-AARCH64_OPT_EXTENSION("sve2-bitperm", AARCH64_FL_SVE2_BITPERM, AARCH64_FL_SIMD | AARCH64_FL_F16 | AARCH64_FL_FP | AARCH64_FL_SVE | AARCH64_FL_SVE2, 0, false, "")
+AARCH64_OPT_EXTENSION("sve2-bitperm", AARCH64_FL_SVE2_BITPERM, AARCH64_FL_SIMD | \
+ AARCH64_FL_F16 | AARCH64_FL_FP | AARCH64_FL_SVE | \
+ AARCH64_FL_SVE2, 0, false, "")
+
+/* Enabling or disabling "tme" only changes "tme". */
+AARCH64_OPT_EXTENSION("tme", AARCH64_FL_TME, 0, 0, false, "")
#undef AARCH64_OPT_EXTENSION
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index e2f4cc1..c4b73d2 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -406,6 +406,33 @@ extern enum aarch64_key_type aarch64_ra_sign_key;
extern struct tune_params aarch64_tune_params;
+/* The available SVE predicate patterns, known in the ACLE as "svpattern". */
+#define AARCH64_FOR_SVPATTERN(T) \
+ T (POW2, pow2, 0) \
+ T (VL1, vl1, 1) \
+ T (VL2, vl2, 2) \
+ T (VL3, vl3, 3) \
+ T (VL4, vl4, 4) \
+ T (VL5, vl5, 5) \
+ T (VL6, vl6, 6) \
+ T (VL7, vl7, 7) \
+ T (VL8, vl8, 8) \
+ T (VL16, vl16, 9) \
+ T (VL32, vl32, 10) \
+ T (VL64, vl64, 11) \
+ T (VL128, vl128, 12) \
+ T (VL256, vl256, 13) \
+ T (MUL4, mul4, 29) \
+ T (MUL3, mul3, 30) \
+ T (ALL, all, 31)
+
+#define AARCH64_SVENUM(UPPER, LOWER, VALUE) AARCH64_SV_##UPPER = VALUE,
+enum aarch64_svpattern {
+ AARCH64_FOR_SVPATTERN (AARCH64_SVENUM)
+ AARCH64_NUM_SVPATTERNS
+};
+#undef AARCH64_SVENUM
+
void aarch64_post_cfi_startproc (void);
poly_int64 aarch64_initial_elimination_offset (unsigned, unsigned);
int aarch64_get_condition_code (rtx);
@@ -416,6 +443,8 @@ unsigned HOST_WIDE_INT aarch64_and_split_imm2 (HOST_WIDE_INT val_in);
bool aarch64_and_bitmask_imm (unsigned HOST_WIDE_INT val_in, machine_mode mode);
int aarch64_branch_cost (bool, bool);
enum aarch64_symbol_type aarch64_classify_symbolic_expression (rtx);
+opt_machine_mode aarch64_vq_mode (scalar_mode);
+opt_machine_mode aarch64_full_sve_mode (scalar_mode);
bool aarch64_can_const_movi_rtx_p (rtx x, machine_mode mode);
bool aarch64_const_vec_all_same_int_p (rtx, HOST_WIDE_INT);
bool aarch64_const_vec_all_same_in_range_p (rtx, HOST_WIDE_INT,
@@ -446,9 +475,11 @@ bool aarch64_masks_and_shift_for_bfi_p (scalar_int_mode, unsigned HOST_WIDE_INT,
bool aarch64_zero_extend_const_eq (machine_mode, rtx, machine_mode, rtx);
bool aarch64_move_imm (HOST_WIDE_INT, machine_mode);
opt_machine_mode aarch64_sve_pred_mode (unsigned int);
+bool aarch64_sve_mode_p (machine_mode);
bool aarch64_sve_cnt_immediate_p (rtx);
+bool aarch64_sve_scalar_inc_dec_immediate_p (rtx);
bool aarch64_sve_addvl_addpl_immediate_p (rtx);
-bool aarch64_sve_inc_dec_immediate_p (rtx);
+bool aarch64_sve_vector_inc_dec_immediate_p (rtx);
int aarch64_add_offset_temporaries (rtx);
void aarch64_split_add_offset (scalar_int_mode, rtx, rtx, rtx, rtx, rtx);
bool aarch64_mov_operand_p (rtx, machine_mode);
@@ -456,13 +487,13 @@ rtx aarch64_reverse_mask (machine_mode, unsigned int);
bool aarch64_offset_7bit_signed_scaled_p (machine_mode, poly_int64);
bool aarch64_offset_9bit_signed_unscaled_p (machine_mode, poly_int64);
char *aarch64_output_sve_cnt_immediate (const char *, const char *, rtx);
-char *aarch64_output_sve_addvl_addpl (rtx, rtx, rtx);
-char *aarch64_output_sve_inc_dec_immediate (const char *, rtx);
+char *aarch64_output_sve_scalar_inc_dec (rtx);
+char *aarch64_output_sve_addvl_addpl (rtx);
+char *aarch64_output_sve_vector_inc_dec (const char *, rtx);
char *aarch64_output_scalar_simd_mov_immediate (rtx, scalar_int_mode);
char *aarch64_output_simd_mov_immediate (rtx, unsigned,
enum simd_immediate_check w = AARCH64_CHECK_MOV);
char *aarch64_output_sve_mov_immediate (rtx);
-char *aarch64_output_ptrue (machine_mode, char);
bool aarch64_pad_reg_upward (machine_mode, const_tree, bool);
bool aarch64_regno_ok_for_base_p (int, bool);
bool aarch64_regno_ok_for_index_p (int, bool);
@@ -494,6 +525,7 @@ enum aarch64_symbol_type aarch64_classify_tls_symbol (rtx);
enum reg_class aarch64_regno_regclass (unsigned);
int aarch64_asm_preferred_eh_data_format (int, int);
int aarch64_fpconst_pow_of_2 (rtx);
+int aarch64_fpconst_pow2_recip (rtx);
machine_mode aarch64_hard_regno_caller_save_mode (unsigned, unsigned,
machine_mode);
int aarch64_uxt_size (int, HOST_WIDE_INT);
@@ -505,9 +537,12 @@ rtx aarch64_return_addr (int, rtx);
rtx aarch64_simd_gen_const_vector_dup (machine_mode, HOST_WIDE_INT);
bool aarch64_simd_mem_operand_p (rtx);
bool aarch64_sve_ld1r_operand_p (rtx);
+bool aarch64_sve_ld1rq_operand_p (rtx);
bool aarch64_sve_ldr_operand_p (rtx);
bool aarch64_sve_struct_memory_operand_p (rtx);
rtx aarch64_simd_vect_par_cnst_half (machine_mode, int, bool);
+rtx aarch64_gen_stepped_int_parallel (unsigned int, int, int);
+bool aarch64_stepped_int_parallel_p (rtx, int);
rtx aarch64_tls_get_addr (void);
tree aarch64_fold_builtin (tree, int, tree *, bool);
unsigned aarch64_dbx_register_number (unsigned);
@@ -519,9 +554,12 @@ const char * aarch64_output_probe_stack_range (rtx, rtx);
const char * aarch64_output_probe_sve_stack_clash (rtx, rtx, rtx, rtx);
void aarch64_err_no_fpadvsimd (machine_mode);
void aarch64_expand_epilogue (bool);
-void aarch64_expand_mov_immediate (rtx, rtx, rtx (*) (rtx, rtx) = 0);
+rtx aarch64_ptrue_all (unsigned int);
+void aarch64_expand_mov_immediate (rtx, rtx);
rtx aarch64_ptrue_reg (machine_mode);
rtx aarch64_pfalse_reg (machine_mode);
+bool aarch64_sve_pred_dominates_p (rtx *, rtx);
+bool aarch64_sve_same_pred_for_ptest_p (rtx *, rtx *);
void aarch64_emit_sve_pred_move (rtx, rtx, rtx);
void aarch64_expand_sve_mem_move (rtx, rtx, machine_mode);
bool aarch64_maybe_expand_sve_subreg_move (rtx, rtx);
@@ -596,6 +634,9 @@ bool aarch64_gen_adjusted_ldpstp (rtx *, bool, scalar_mode, RTX_CODE);
void aarch64_expand_sve_vec_cmp_int (rtx, rtx_code, rtx, rtx);
bool aarch64_expand_sve_vec_cmp_float (rtx, rtx_code, rtx, rtx, bool);
void aarch64_expand_sve_vcond (machine_mode, machine_mode, rtx *);
+
+bool aarch64_prepare_sve_int_fma (rtx *, rtx_code);
+bool aarch64_prepare_sve_cond_int_fma (rtx *, rtx_code);
#endif /* RTX_CODE */
void aarch64_init_builtins (void);
diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def
index 17bb0c4..01518fe 100644
--- a/gcc/config/aarch64/aarch64-simd-builtins.def
+++ b/gcc/config/aarch64/aarch64-simd-builtins.def
@@ -424,7 +424,7 @@
BUILTIN_VB (UNOP, rbit, 0)
/* Implemented by
- aarch64_<PERMUTE:perm_insn><PERMUTE:perm_hilo><mode>. */
+ aarch64_<PERMUTE:perm_insn><mode>. */
BUILTIN_VALL (BINOP, zip1, 0)
BUILTIN_VALL (BINOP, zip2, 0)
BUILTIN_VALL (BINOP, uzp1, 0)
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index c6ccc99..e33a009 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -5781,13 +5781,13 @@
;; This instruction's pattern is generated directly by
;; aarch64_expand_vec_perm_const, so any changes to the pattern would
;; need corresponding changes there.
-(define_insn "aarch64_<PERMUTE:perm_insn><PERMUTE:perm_hilo><mode>"
+(define_insn "aarch64_<PERMUTE:perm_insn><mode>"
[(set (match_operand:VALL_F16 0 "register_operand" "=w")
(unspec:VALL_F16 [(match_operand:VALL_F16 1 "register_operand" "w")
(match_operand:VALL_F16 2 "register_operand" "w")]
PERMUTE))]
"TARGET_SIMD"
- "<PERMUTE:perm_insn><PERMUTE:perm_hilo>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
+ "<PERMUTE:perm_insn>\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
[(set_attr "type" "neon_permute<q>")]
)
diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md
index e489afb..ac65e69 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -18,8 +18,121 @@
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
-;; Note on the handling of big-endian SVE
-;; --------------------------------------
+;; The file is organised into the following sections (search for the full
+;; line):
+;;
+;; == General notes
+;; ---- Note on the handling of big-endian SVE
+;; ---- Description of UNSPEC_PTEST
+;; ---- Description of UNSPEC_PRED_Z
+;; ---- Note on predicated integer arithemtic and UNSPEC_PRED_X
+;; ---- Note on predicated FP arithmetic patterns and GP "strictness"
+;;
+;; == Moves
+;; ---- Moves of single vectors
+;; ---- Moves of multiple vectors
+;; ---- Moves of predicates
+;;
+;; == Loads
+;; ---- Normal contiguous loads
+;; ---- Normal gather loads
+;;
+;; == Stores
+;; ---- Normal contiguous stores
+;; ---- Normal scatter stores
+;;
+;; == Vector creation
+;; ---- [INT,FP] Duplicate element
+;; ---- [INT,FP] Initialize from individual elements
+;; ---- [INT] Linear series
+;; ---- [PRED] Duplicate element
+;;
+;; == Vector decomposition
+;; ---- [INT,FP] Extract index
+;; ---- [INT,FP] Extract active element
+;; ---- [PRED] Extract index
+;;
+;; == Unary arithmetic
+;; ---- [INT] General unary arithmetic corresponding to rtx codes
+;; ---- [INT] General unary arithmetic corresponding to unspecs
+;; ---- [INT] Zero extension
+;; ---- [INT] Logical inverse
+;; ---- [FP] General unary arithmetic corresponding to unspecs
+;; ---- [PRED] Inverse
+
+;; == Binary arithmetic
+;; ---- [INT] General binary arithmetic corresponding to rtx codes
+;; ---- [INT] Addition
+;; ---- [INT] Subtraction
+;; ---- [INT] Take address
+;; ---- [INT] Absolute difference
+;; ---- [INT] Highpart multiplication
+;; ---- [INT] Division
+;; ---- [INT] Binary logical operations
+;; ---- [INT] Binary logical operations (inverted second input)
+;; ---- [INT] Shifts
+;; ---- [FP] General binary arithmetic corresponding to rtx codes
+;; ---- [FP] General binary arithmetic corresponding to unspecs
+;; ---- [FP] Addition
+;; ---- [FP] Subtraction
+;; ---- [FP] Absolute difference
+;; ---- [FP] Multiplication
+;; ---- [FP] Binary logical operations
+;; ---- [FP] Sign copying
+;; ---- [FP] Maximum and minimum
+;; ---- [PRED] Binary logical operations
+;; ---- [PRED] Binary logical operations (inverted second input)
+;; ---- [PRED] Binary logical operations (inverted result)
+;;
+;; == Ternary arithmetic
+;; ---- [INT] MLA and MAD
+;; ---- [INT] MLS and MSB
+;; ---- [INT] Dot product
+;; ---- [INT] Sum of absolute differences
+;; ---- [FP] General ternary arithmetic corresponding to unspecs
+;;
+;; == Comparisons and selects
+;; ---- [INT,FP] Select based on predicates
+;; ---- [INT,FP] Compare and select
+;; ---- [INT] Comparisons
+;; ---- [INT] While tests
+;; ---- [FP] Direct comparisons
+;; ---- [FP] Absolute comparisons
+;; ---- [PRED] Test bits
+;;
+;; == Reductions
+;; ---- [INT,FP] Conditional reductions
+;; ---- [INT] Tree reductions
+;; ---- [FP] Tree reductions
+;; ---- [FP] Left-to-right reductions
+;;
+;; == Permutes
+;; ---- [INT,FP] General permutes
+;; ---- [INT,FP] Special-purpose unary permutes
+;; ---- [INT,FP] Special-purpose binary permutes
+;; ---- [PRED] Special-purpose binary permutes
+;;
+;; == Conversions
+;; ---- [INT<-INT] Packs
+;; ---- [INT<-INT] Unpacks
+;; ---- [INT<-FP] Conversions
+;; ---- [INT<-FP] Packs
+;; ---- [INT<-FP] Unpacks
+;; ---- [FP<-INT] Conversions
+;; ---- [FP<-INT] Packs
+;; ---- [FP<-INT] Unpacks
+;; ---- [FP<-FP] Packs
+;; ---- [FP<-FP] Unpacks
+;; ---- [PRED<-PRED] Packs
+;; ---- [PRED<-PRED] Unpacks
+
+;; =========================================================================
+;; == General notes
+;; =========================================================================
+;;
+;; -------------------------------------------------------------------------
+;; ---- Note on the handling of big-endian SVE
+;; -------------------------------------------------------------------------
;;
;; On big-endian systems, Advanced SIMD mov<mode> patterns act in the
;; same way as movdi or movti would: the first byte of memory goes
@@ -59,9 +172,269 @@
;; the order of the bytes within the elements is different. We instead
;; access spill slots via LD1 and ST1, using secondary reloads to
;; reserve a predicate register.
+;;
+;; -------------------------------------------------------------------------
+;; ---- Description of UNSPEC_PTEST
+;; -------------------------------------------------------------------------
+;;
+;; SVE provides a PTEST instruction for testing the active lanes of a
+;; predicate and setting the flags based on the result. The associated
+;; condition code tests are:
+;;
+;; - any (= ne): at least one active bit is set
+;; - none (= eq): all active bits are clear (*)
+;; - first (= mi): the first active bit is set
+;; - nfrst (= pl): the first active bit is clear (*)
+;; - last (= cc): the last active bit is set
+;; - nlast (= cs): the last active bit is clear (*)
+;;
+;; where the conditions marked (*) are also true when there are no active
+;; lanes (i.e. when the governing predicate is a PFALSE). The flags results
+;; of a PTEST use the condition code mode CC_NZC.
+;;
+;; PTEST is always a .B operation (i.e. it always operates on VNx16BI).
+;; This means that for other predicate modes, we need a governing predicate
+;; in which all bits are defined.
+;;
+;; For example, most predicated .H operations ignore the odd bits of the
+;; governing predicate, so that an active lane is represented by the
+;; bits "1x" and an inactive lane by the bits "0x", where "x" can be
+;; any value. To test a .H predicate, we instead need "10" and "00"
+;; respectively, so that the condition only tests the even bits of the
+;; predicate.
+;;
+;; Several instructions set the flags as a side-effect, in the same way
+;; that a separate PTEST would. It's important for code quality that we
+;; use these flags results as often as possible, particularly in the case
+;; of WHILE* and RDFFR.
+;;
+;; Also, some of the instructions that set the flags are unpredicated
+;; and instead implicitly test all .B, .H, .S or .D elements, as though
+;; they were predicated on a PTRUE of that size. For example, a .S
+;; WHILELO sets the flags in the same way as a PTEST with a .S PTRUE
+;; would.
+;;
+;; We therefore need to represent PTEST operations in a way that
+;; makes it easy to combine them with both predicated and unpredicated
+;; operations, while using a VNx16BI governing predicate for all
+;; predicate modes. We do this using:
+;;
+;; (unspec:CC_NZC [gp cast_gp ptrue_flag op] UNSPEC_PTEST)
+;;
+;; where:
+;;
+;; - GP is the real VNx16BI governing predicate
+;;
+;; - CAST_GP is GP cast to the mode of OP. All bits dropped by casting
+;; GP to CAST_GP are guaranteed to be clear in GP.
+;;
+;; - PTRUE_FLAG is a CONST_INT (conceptually of mode SI) that has the value
+;; SVE_KNOWN_PTRUE if we know that CAST_GP (rather than GP) is all-true and
+;; SVE_MAYBE_NOT_PTRUE otherwise.
+;;
+;; - OP is the predicate we want to test, of the same mode as CAST_GP.
+;;
+;; -------------------------------------------------------------------------
+;; ---- Description of UNSPEC_PRED_Z
+;; -------------------------------------------------------------------------
+;;
+;; SVE integer comparisons are predicated and return zero for inactive
+;; lanes. Sometimes we use them with predicates that are all-true and
+;; sometimes we use them with general predicates.
+;;
+;; The integer comparisons also set the flags and so build-in the effect
+;; of a PTEST. We therefore want to be able to combine integer comparison
+;; patterns with PTESTs of the result. One difficulty with doing this is
+;; that (as noted above) the PTEST is always a .B operation and so can place
+;; stronger requirements on the governing predicate than the comparison does.
+;;
+;; For example, when applying a separate PTEST to the result of a full-vector
+;; .H comparison, the PTEST must be predicated on a .H PTRUE instead of a
+;; .B PTRUE. In constrast, the comparison might be predicated on either
+;; a .H PTRUE or a .B PTRUE, since the values of odd-indexed predicate
+;; bits don't matter for .H operations.
+;;
+;; We therefore can't rely on a full-vector comparison using the same
+;; predicate register as a following PTEST. We instead need to remember
+;; whether a comparison is known to be a full-vector comparison and use
+;; this information in addition to a check for equal predicate registers.
+;; At the same time, it's useful to have a common representation for all
+;; integer comparisons, so that they can be handled by a single set of
+;; patterns.
+;;
+;; We therefore take a similar approach to UNSPEC_PTEST above and use:
+;;
+;; (unspec:<M:VPRED> [gp ptrue_flag (code:M op0 op1)] UNSPEC_PRED_Z)
+;;
+;; where:
+;;
+;; - GP is the governing predicate, of mode <M:VPRED>
+;;
+;; - PTRUE_FLAG is a CONST_INT (conceptually of mode SI) that has the value
+;; SVE_KNOWN_PTRUE if we know that GP is all-true and SVE_MAYBE_NOT_PTRUE
+;; otherwise
+;;
+;; - CODE is the comparison code
+;;
+;; - OP0 and OP1 are the values being compared, of mode M
+;;
+;; The "Z" in UNSPEC_PRED_Z indicates that inactive lanes are zero.
+;;
+;; -------------------------------------------------------------------------
+;; ---- Note on predicated integer arithemtic and UNSPEC_PRED_X
+;; -------------------------------------------------------------------------
+;;
+;; Many SVE integer operations are predicated. We can generate them
+;; from four sources:
+;;
+;; (1) Using normal unpredicated optabs. In this case we need to create
+;; an all-true predicate register to act as the governing predicate
+;; for the SVE instruction. There are no inactive lanes, and thus
+;; the values of inactive lanes don't matter.
+;;
+;; (2) Using _x ACLE functions. In this case the function provides a
+;; specific predicate and some lanes might be inactive. However,
+;; as for (1), the values of the inactive lanes don't matter.
+;; We can make extra lanes active without changing the behavior
+;; (although for code-quality reasons we should avoid doing so
+;; needlessly).
+;;
+;; (3) Using cond_* optabs that correspond to IFN_COND_* internal functions.
+;; These optabs have a predicate operand that specifies which lanes are
+;; active and another operand that provides the values of inactive lanes.
+;;
+;; (4) Using _m and _z ACLE functions. These functions map to the same
+;; patterns as (3), with the _z functions setting inactive lanes to zero
+;; and the _m functions setting the inactive lanes to one of the function
+;; arguments.
+;;
+;; For (1) and (2) we need a way of attaching the predicate to a normal
+;; unpredicated integer operation. We do this using:
+;;
+;; (unspec:M [pred (code:M (op0 op1 ...))] UNSPEC_PRED_X)
+;;
+;; where (code:M (op0 op1 ...)) is the normal integer operation and PRED
+;; is a predicate of mode <M:VPRED>. PRED might or might not be a PTRUE;
+;; it always is for (1), but might not be for (2).
+;;
+;; The unspec as a whole has the same value as (code:M ...) when PRED is
+;; all-true. It is always semantically valid to replace PRED with a PTRUE,
+;; but as noted above, we should only do so if there's a specific benefit.
+;;
+;; (The "_X" in the unspec is named after the ACLE functions in (2).)
+;;
+;; For (3) and (4) we can simply use the SVE port's normal representation
+;; of a predicate-based select:
+;;
+;; (unspec:M [pred (code:M (op0 op1 ...)) inactive] UNSPEC_SEL)
+;;
+;; where INACTIVE specifies the values of inactive lanes.
+;;
+;; We can also use the UNSPEC_PRED_X wrapper in the UNSPEC_SEL rather
+;; than inserting the integer operation directly. This is mostly useful
+;; if we want the combine pass to merge an integer operation with an explicit
+;; vcond_mask (in other words, with a following SEL instruction). However,
+;; it's generally better to merge such operations at the gimple level
+;; using (3).
+;;
+;; -------------------------------------------------------------------------
+;; ---- Note on predicated FP arithmetic patterns and GP "strictness"
+;; -------------------------------------------------------------------------
+;;
+;; Most SVE floating-point operations are predicated. We can generate
+;; them from four sources:
+;;
+;; (1) Using normal unpredicated optabs. In this case we need to create
+;; an all-true predicate register to act as the governing predicate
+;; for the SVE instruction. There are no inactive lanes, and thus
+;; the values of inactive lanes don't matter.
+;;
+;; (2) Using _x ACLE functions. In this case the function provides a
+;; specific predicate and some lanes might be inactive. However,
+;; as for (1), the values of the inactive lanes don't matter.
+;;
+;; The instruction must have the same exception behavior as the
+;; function call unless things like command-line flags specifically
+;; allow otherwise. For example, with -ffast-math, it is OK to
+;; raise exceptions for inactive lanes, but normally it isn't.
+;;
+;; (3) Using cond_* optabs that correspond to IFN_COND_* internal functions.
+;; These optabs have a predicate operand that specifies which lanes are
+;; active and another operand that provides the values of inactive lanes.
+;;
+;; (4) Using _m and _z ACLE functions. These functions map to the same
+;; patterns as (3), with the _z functions setting inactive lanes to zero
+;; and the _m functions setting the inactive lanes to one of the function
+;; arguments.
+;;
+;; So:
+;;
+;; - In (1), the predicate is known to be all true and the pattern can use
+;; unpredicated operations where available.
+;;
+;; - In (2), the predicate might or might not be all true. The pattern can
+;; use unpredicated instructions if the predicate is all-true or if things
+;; like command-line flags allow exceptions for inactive lanes.
+;;
+;; - (3) and (4) represent a native SVE predicated operation. Some lanes
+;; might be inactive and inactive lanes of the result must have specific
+;; values. There is no scope for using unpredicated instructions (and no
+;; reason to want to), so the question about command-line flags doesn't
+;; arise.
+;;
+;; It would be inaccurate to model (2) as an rtx code like (sqrt ...)
+;; in combination with a separate predicate operand, e.g.
+;;
+;; (unspec [(match_operand:<VPRED> 1 "register_operand" "Upl")
+;; (sqrt:SVE_F 2 "register_operand" "w")]
+;; ....)
+;;
+;; because (sqrt ...) can raise an exception for any lane, including
+;; inactive ones. We therefore need to use an unspec instead.
+;;
+;; Also, (2) requires some way of distinguishing the case in which the
+;; predicate might have inactive lanes and cannot be changed from the
+;; case in which the predicate has no inactive lanes or can be changed.
+;; This information is also useful when matching combined FP patterns
+;; in which the predicates might not be equal.
+;;
+;; We therefore model FP operations as an unspec of the form:
+;;
+;; (unspec [pred strictness op0 op1 ...] UNSPEC_COND_<MNEMONIC>)
+;;
+;; where:
+;;
+;; - PRED is the governing predicate.
+;;
+;; - STRICTNESS is a CONST_INT that conceptually has mode SI. It has the
+;; value SVE_STRICT_GP if PRED might have inactive lanes and if those
+;; lanes must remain inactive. It has the value SVE_RELAXED_GP otherwise.
+;;
+;; - OP0 OP1 ... are the normal input operands to the operation.
+;;
+;; - MNEMONIC is the mnemonic of the associated SVE instruction.
+
+;; =========================================================================
+;; == Moves
+;; =========================================================================
+
+;; -------------------------------------------------------------------------
+;; ---- Moves of single vectors
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - MOV (including aliases)
+;; - LD1B (contiguous form)
+;; - LD1D ( " " )
+;; - LD1H ( " " )
+;; - LD1W ( " " )
+;; - LDR
+;; - ST1B (contiguous form)
+;; - ST1D ( " " )
+;; - ST1H ( " " )
+;; - ST1W ( " " )
+;; - STR
+;; -------------------------------------------------------------------------
-
-;; SVE data moves.
(define_expand "mov<mode>"
[(set (match_operand:SVE_ALL 0 "nonimmediate_operand")
(match_operand:SVE_ALL 1 "general_operand"))]
@@ -80,8 +453,7 @@
if (CONSTANT_P (operands[1]))
{
- aarch64_expand_mov_immediate (operands[0], operands[1],
- gen_vec_duplicate<mode>);
+ aarch64_expand_mov_immediate (operands[0], operands[1]);
DONE;
}
@@ -93,22 +465,13 @@
}
)
-;; A pattern for optimizing SUBREGs that have a reinterpreting effect
-;; on big-endian targets; see aarch64_maybe_expand_sve_subreg_move
-;; for details. We use a special predicate for operand 2 to reduce
-;; the number of patterns.
-(define_insn_and_split "*aarch64_sve_mov<mode>_subreg_be"
- [(set (match_operand:SVE_ALL 0 "aarch64_sve_nonimmediate_operand" "=w")
- (unspec:SVE_ALL
- [(match_operand:VNx16BI 1 "register_operand" "Upl")
- (match_operand 2 "aarch64_any_register_operand" "w")]
- UNSPEC_REV_SUBREG))]
- "TARGET_SVE && BYTES_BIG_ENDIAN"
- "#"
- "&& reload_completed"
- [(const_int 0)]
+(define_expand "movmisalign<mode>"
+ [(set (match_operand:SVE_ALL 0 "nonimmediate_operand")
+ (match_operand:SVE_ALL 1 "general_operand"))]
+ "TARGET_SVE"
{
- aarch64_split_sve_subreg_move (operands[0], operands[1], operands[2]);
+ /* Equivalent to a normal move for our purpooses. */
+ emit_move_insn (operands[0], operands[1]);
DONE;
}
)
@@ -167,16 +530,15 @@
}
)
-;; A predicated load or store for which the predicate is known to be
-;; all-true. Note that this pattern is generated directly by
-;; aarch64_emit_sve_pred_move, so changes to this pattern will
-;; need changes there as well.
+;; A predicated move in which the predicate is known to be all-true.
+;; Note that this pattern is generated directly by aarch64_emit_sve_pred_move,
+;; so changes to this pattern will need changes there as well.
(define_insn_and_split "@aarch64_pred_mov<mode>"
[(set (match_operand:SVE_ALL 0 "nonimmediate_operand" "=w, w, m")
(unspec:SVE_ALL
[(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
(match_operand:SVE_ALL 2 "nonimmediate_operand" "w, m, w")]
- UNSPEC_MERGE_PTRUE))]
+ UNSPEC_PRED_X))]
"TARGET_SVE
&& (register_operand (operands[0], <MODE>mode)
|| register_operand (operands[2], <MODE>mode))"
@@ -189,17 +551,231 @@
[(set (match_dup 0) (match_dup 2))]
)
-(define_expand "movmisalign<mode>"
- [(set (match_operand:SVE_ALL 0 "nonimmediate_operand")
- (match_operand:SVE_ALL 1 "general_operand"))]
+;; A pattern for optimizing SUBREGs that have a reinterpreting effect
+;; on big-endian targets; see aarch64_maybe_expand_sve_subreg_move
+;; for details. We use a special predicate for operand 2 to reduce
+;; the number of patterns.
+(define_insn_and_split "*aarch64_sve_mov<mode>_subreg_be"
+ [(set (match_operand:SVE_ALL 0 "aarch64_sve_nonimmediate_operand" "=w")
+ (unspec:SVE_ALL
+ [(match_operand:VNx16BI 1 "register_operand" "Upl")
+ (match_operand 2 "aarch64_any_register_operand" "w")]
+ UNSPEC_REV_SUBREG))]
+ "TARGET_SVE && BYTES_BIG_ENDIAN"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ {
+ aarch64_split_sve_subreg_move (operands[0], operands[1], operands[2]);
+ DONE;
+ }
+)
+
+;; Reinterpret operand 1 in operand 0's mode, without changing its contents.
+;; This is equivalent to a subreg on little-endian targets but not for
+;; big-endian; see the comment at the head of the file for details.
+(define_expand "@aarch64_sve_reinterpret<mode>"
+ [(set (match_operand:SVE_ALL 0 "register_operand")
+ (unspec:SVE_ALL [(match_operand 1 "aarch64_any_register_operand")]
+ UNSPEC_REINTERPRET))]
"TARGET_SVE"
{
- /* Equivalent to a normal move for our purpooses. */
- emit_move_insn (operands[0], operands[1]);
+ if (!BYTES_BIG_ENDIAN)
+ {
+ emit_move_insn (operands[0], gen_lowpart (<MODE>mode, operands[1]));
+ DONE;
+ }
+ }
+)
+
+;; A pattern for handling type punning on big-endian targets. We use a
+;; special predicate for operand 1 to reduce the number of patterns.
+(define_insn_and_split "*aarch64_sve_reinterpret<mode>"
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
+ (unspec:SVE_ALL [(match_operand 1 "aarch64_any_register_operand" "0")]
+ UNSPEC_REINTERPRET))]
+ "TARGET_SVE"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (match_dup 1))]
+ {
+ emit_note (NOTE_INSN_DELETED);
+ DONE;
+ }
+)
+
+;; -------------------------------------------------------------------------
+;; ---- Moves of multiple vectors
+;; -------------------------------------------------------------------------
+;; All patterns in this section are synthetic and split to real
+;; instructions after reload.
+;; -------------------------------------------------------------------------
+
+(define_expand "mov<mode>"
+ [(set (match_operand:SVE_STRUCT 0 "nonimmediate_operand")
+ (match_operand:SVE_STRUCT 1 "general_operand"))]
+ "TARGET_SVE"
+ {
+ /* Big-endian loads and stores need to be done via LD1 and ST1;
+ see the comment at the head of the file for details. */
+ if ((MEM_P (operands[0]) || MEM_P (operands[1]))
+ && BYTES_BIG_ENDIAN)
+ {
+ gcc_assert (can_create_pseudo_p ());
+ aarch64_expand_sve_mem_move (operands[0], operands[1], <VPRED>mode);
+ DONE;
+ }
+
+ if (CONSTANT_P (operands[1]))
+ {
+ aarch64_expand_mov_immediate (operands[0], operands[1]);
+ DONE;
+ }
+ }
+)
+
+;; Unpredicated structure moves (little-endian).
+(define_insn "*aarch64_sve_mov<mode>_le"
+ [(set (match_operand:SVE_STRUCT 0 "aarch64_sve_nonimmediate_operand" "=w, Utr, w, w")
+ (match_operand:SVE_STRUCT 1 "aarch64_sve_general_operand" "Utr, w, w, Dn"))]
+ "TARGET_SVE && !BYTES_BIG_ENDIAN"
+ "#"
+ [(set_attr "length" "<insn_length>")]
+)
+
+;; Unpredicated structure moves (big-endian). Memory accesses require
+;; secondary reloads.
+(define_insn "*aarch64_sve_mov<mode>_be"
+ [(set (match_operand:SVE_STRUCT 0 "register_operand" "=w, w")
+ (match_operand:SVE_STRUCT 1 "aarch64_nonmemory_operand" "w, Dn"))]
+ "TARGET_SVE && BYTES_BIG_ENDIAN"
+ "#"
+ [(set_attr "length" "<insn_length>")]
+)
+
+;; Split unpredicated structure moves into pieces. This is the same
+;; for both big-endian and little-endian code, although it only needs
+;; to handle memory operands for little-endian code.
+(define_split
+ [(set (match_operand:SVE_STRUCT 0 "aarch64_sve_nonimmediate_operand")
+ (match_operand:SVE_STRUCT 1 "aarch64_sve_general_operand"))]
+ "TARGET_SVE && reload_completed"
+ [(const_int 0)]
+ {
+ rtx dest = operands[0];
+ rtx src = operands[1];
+ if (REG_P (dest) && REG_P (src))
+ aarch64_simd_emit_reg_reg_move (operands, <VSINGLE>mode, <vector_count>);
+ else
+ for (unsigned int i = 0; i < <vector_count>; ++i)
+ {
+ rtx subdest = simplify_gen_subreg (<VSINGLE>mode, dest, <MODE>mode,
+ i * BYTES_PER_SVE_VECTOR);
+ rtx subsrc = simplify_gen_subreg (<VSINGLE>mode, src, <MODE>mode,
+ i * BYTES_PER_SVE_VECTOR);
+ emit_insn (gen_rtx_SET (subdest, subsrc));
+ }
+ DONE;
+ }
+)
+
+;; Predicated structure moves. This works for both endiannesses but in
+;; practice is only useful for big-endian.
+(define_insn_and_split "@aarch64_pred_mov<mode>"
+ [(set (match_operand:SVE_STRUCT 0 "aarch64_sve_struct_nonimmediate_operand" "=w, w, Utx")
+ (unspec:SVE_STRUCT
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (match_operand:SVE_STRUCT 2 "aarch64_sve_struct_nonimmediate_operand" "w, Utx, w")]
+ UNSPEC_PRED_X))]
+ "TARGET_SVE
+ && (register_operand (operands[0], <MODE>mode)
+ || register_operand (operands[2], <MODE>mode))"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+ {
+ for (unsigned int i = 0; i < <vector_count>; ++i)
+ {
+ rtx subdest = simplify_gen_subreg (<VSINGLE>mode, operands[0],
+ <MODE>mode,
+ i * BYTES_PER_SVE_VECTOR);
+ rtx subsrc = simplify_gen_subreg (<VSINGLE>mode, operands[2],
+ <MODE>mode,
+ i * BYTES_PER_SVE_VECTOR);
+ aarch64_emit_sve_pred_move (subdest, operands[1], subsrc);
+ }
DONE;
}
+ [(set_attr "length" "<insn_length>")]
+)
+
+;; -------------------------------------------------------------------------
+;; ---- Moves of predicates
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - MOV
+;; - LDR
+;; - PFALSE
+;; - PTRUE
+;; - STR
+;; -------------------------------------------------------------------------
+
+(define_expand "mov<mode>"
+ [(set (match_operand:PRED_ALL 0 "nonimmediate_operand")
+ (match_operand:PRED_ALL 1 "general_operand"))]
+ "TARGET_SVE"
+ {
+ if (GET_CODE (operands[0]) == MEM)
+ operands[1] = force_reg (<MODE>mode, operands[1]);
+
+ if (CONSTANT_P (operands[1]))
+ {
+ aarch64_expand_mov_immediate (operands[0], operands[1]);
+ DONE;
+ }
+ }
)
+(define_insn "*aarch64_sve_mov<mode>"
+ [(set (match_operand:PRED_ALL 0 "nonimmediate_operand" "=Upa, m, Upa, Upa")
+ (match_operand:PRED_ALL 1 "aarch64_mov_operand" "Upa, Upa, m, Dn"))]
+ "TARGET_SVE
+ && (register_operand (operands[0], <MODE>mode)
+ || register_operand (operands[1], <MODE>mode))"
+ "@
+ mov\t%0.b, %1.b
+ str\t%1, %0
+ ldr\t%0, %1
+ * return aarch64_output_sve_mov_immediate (operands[1]);"
+)
+
+;; =========================================================================
+;; == Loads
+;; =========================================================================
+
+;; -------------------------------------------------------------------------
+;; ---- Normal contiguous loads
+;; -------------------------------------------------------------------------
+;; Includes contiguous forms of:
+;; - LD1B
+;; - LD1D
+;; - LD1H
+;; - LD1W
+;; - LD2B
+;; - LD2D
+;; - LD2H
+;; - LD2W
+;; - LD3B
+;; - LD3D
+;; - LD3H
+;; - LD3W
+;; - LD4B
+;; - LD4D
+;; - LD4H
+;; - LD4W
+;; -------------------------------------------------------------------------
+
+;; Predicated LD1.
(define_insn "maskload<mode><vpred>"
[(set (match_operand:SVE_ALL 0 "register_operand" "=w")
(unspec:SVE_ALL
@@ -210,16 +786,38 @@
"ld1<Vesize>\t%0.<Vetype>, %2/z, %1"
)
-(define_insn "maskstore<mode><vpred>"
- [(set (match_operand:SVE_ALL 0 "memory_operand" "+m")
- (unspec:SVE_ALL [(match_operand:<VPRED> 2 "register_operand" "Upl")
- (match_operand:SVE_ALL 1 "register_operand" "w")
- (match_dup 0)]
- UNSPEC_ST1_SVE))]
+;; Unpredicated LD[234].
+(define_expand "vec_load_lanes<mode><vsingle>"
+ [(set (match_operand:SVE_STRUCT 0 "register_operand")
+ (unspec:SVE_STRUCT
+ [(match_dup 2)
+ (match_operand:SVE_STRUCT 1 "memory_operand")]
+ UNSPEC_LDN))]
"TARGET_SVE"
- "st1<Vesize>\t%1.<Vetype>, %2, %0"
+ {
+ operands[2] = aarch64_ptrue_reg (<VPRED>mode);
+ }
)
+;; Predicated LD[234].
+(define_insn "vec_mask_load_lanes<mode><vsingle>"
+ [(set (match_operand:SVE_STRUCT 0 "register_operand" "=w")
+ (unspec:SVE_STRUCT
+ [(match_operand:<VPRED> 2 "register_operand" "Upl")
+ (match_operand:SVE_STRUCT 1 "memory_operand" "m")]
+ UNSPEC_LDN))]
+ "TARGET_SVE"
+ "ld<vector_count><Vesize>\t%0, %2/z, %1"
+)
+
+;; -------------------------------------------------------------------------
+;; ---- Normal gather loads
+;; -------------------------------------------------------------------------
+;; Includes gather forms of:
+;; - LD1D
+;; - LD1W
+;; -------------------------------------------------------------------------
+
;; Unpredicated gather loads.
(define_expand "gather_load<mode>"
[(set (match_operand:SVE_SD 0 "register_operand")
@@ -277,7 +875,82 @@
ld1d\t%0.d, %5/z, [%1, %2.d, lsl %p4]"
)
-;; Unpredicated scatter store.
+;; =========================================================================
+;; == Stores
+;; =========================================================================
+
+;; -------------------------------------------------------------------------
+;; ---- Normal contiguous stores
+;; -------------------------------------------------------------------------
+;; Includes contiguous forms of:
+;; - ST1B
+;; - ST1D
+;; - ST1H
+;; - ST1W
+;; - ST2B
+;; - ST2D
+;; - ST2H
+;; - ST2W
+;; - ST3B
+;; - ST3D
+;; - ST3H
+;; - ST3W
+;; - ST4B
+;; - ST4D
+;; - ST4H
+;; - ST4W
+;; -------------------------------------------------------------------------
+
+;; Predicated ST1.
+(define_insn "maskstore<mode><vpred>"
+ [(set (match_operand:SVE_ALL 0 "memory_operand" "+m")
+ (unspec:SVE_ALL [(match_operand:<VPRED> 2 "register_operand" "Upl")
+ (match_operand:SVE_ALL 1 "register_operand" "w")
+ (match_dup 0)]
+ UNSPEC_ST1_SVE))]
+ "TARGET_SVE"
+ "st1<Vesize>\t%1.<Vetype>, %2, %0"
+)
+
+;; Unpredicated ST[234]. This is always a full update, so the dependence
+;; on the old value of the memory location (via (match_dup 0)) is redundant.
+;; There doesn't seem to be any obvious benefit to treating the all-true
+;; case differently though. In particular, it's very unlikely that we'll
+;; only find out during RTL that a store_lanes is dead.
+(define_expand "vec_store_lanes<mode><vsingle>"
+ [(set (match_operand:SVE_STRUCT 0 "memory_operand")
+ (unspec:SVE_STRUCT
+ [(match_dup 2)
+ (match_operand:SVE_STRUCT 1 "register_operand")
+ (match_dup 0)]
+ UNSPEC_STN))]
+ "TARGET_SVE"
+ {
+ operands[2] = aarch64_ptrue_reg (<VPRED>mode);
+ }
+)
+
+;; Predicated ST[234].
+(define_insn "vec_mask_store_lanes<mode><vsingle>"
+ [(set (match_operand:SVE_STRUCT 0 "memory_operand" "+m")
+ (unspec:SVE_STRUCT
+ [(match_operand:<VPRED> 2 "register_operand" "Upl")
+ (match_operand:SVE_STRUCT 1 "register_operand" "w")
+ (match_dup 0)]
+ UNSPEC_STN))]
+ "TARGET_SVE"
+ "st<vector_count><Vesize>\t%1, %2, %0"
+)
+
+;; -------------------------------------------------------------------------
+;; ---- Normal scatter stores
+;; -------------------------------------------------------------------------
+;; Includes scatter forms of:
+;; - ST1D
+;; - ST1W
+;; -------------------------------------------------------------------------
+
+;; Unpredicated scatter stores.
(define_expand "scatter_store<mode>"
[(set (mem:BLK (scratch))
(unspec:BLK
@@ -334,148 +1007,238 @@
st1d\t%4.d, %5, [%0, %1.d, lsl %p3]"
)
-;; SVE structure moves.
-(define_expand "mov<mode>"
- [(set (match_operand:SVE_STRUCT 0 "nonimmediate_operand")
- (match_operand:SVE_STRUCT 1 "general_operand"))]
+;; =========================================================================
+;; == Vector creation
+;; =========================================================================
+
+;; -------------------------------------------------------------------------
+;; ---- [INT,FP] Duplicate element
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - MOV
+;; - LD1RB
+;; - LD1RD
+;; - LD1RH
+;; - LD1RW
+;; - LD1RQB
+;; - LD1RQD
+;; - LD1RQH
+;; - LD1RQW
+;; -------------------------------------------------------------------------
+
+(define_expand "vec_duplicate<mode>"
+ [(parallel
+ [(set (match_operand:SVE_ALL 0 "register_operand")
+ (vec_duplicate:SVE_ALL
+ (match_operand:<VEL> 1 "aarch64_sve_dup_operand")))
+ (clobber (scratch:VNx16BI))])]
"TARGET_SVE"
{
- /* Big-endian loads and stores need to be done via LD1 and ST1;
- see the comment at the head of the file for details. */
- if ((MEM_P (operands[0]) || MEM_P (operands[1]))
- && BYTES_BIG_ENDIAN)
+ if (MEM_P (operands[1]))
{
- gcc_assert (can_create_pseudo_p ());
- aarch64_expand_sve_mem_move (operands[0], operands[1], <VPRED>mode);
+ rtx ptrue = aarch64_ptrue_reg (<VPRED>mode);
+ emit_insn (gen_sve_ld1r<mode> (operands[0], ptrue, operands[1],
+ CONST0_RTX (<MODE>mode)));
DONE;
}
+ }
+)
- if (CONSTANT_P (operands[1]))
- {
- aarch64_expand_mov_immediate (operands[0], operands[1]);
- DONE;
- }
+;; Accept memory operands for the benefit of combine, and also in case
+;; the scalar input gets spilled to memory during RA. We want to split
+;; the load at the first opportunity in order to allow the PTRUE to be
+;; optimized with surrounding code.
+(define_insn_and_split "*vec_duplicate<mode>_reg"
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=w, w, w")
+ (vec_duplicate:SVE_ALL
+ (match_operand:<VEL> 1 "aarch64_sve_dup_operand" "r, w, Uty")))
+ (clobber (match_scratch:VNx16BI 2 "=X, X, Upl"))]
+ "TARGET_SVE"
+ "@
+ mov\t%0.<Vetype>, %<vwcore>1
+ mov\t%0.<Vetype>, %<Vetype>1
+ #"
+ "&& MEM_P (operands[1])"
+ [(const_int 0)]
+ {
+ if (GET_CODE (operands[2]) == SCRATCH)
+ operands[2] = gen_reg_rtx (VNx16BImode);
+ emit_move_insn (operands[2], CONSTM1_RTX (VNx16BImode));
+ rtx gp = gen_lowpart (<VPRED>mode, operands[2]);
+ emit_insn (gen_sve_ld1r<mode> (operands[0], gp, operands[1],
+ CONST0_RTX (<MODE>mode)));
+ DONE;
}
+ [(set_attr "length" "4,4,8")]
)
-;; Unpredicated structure moves (little-endian).
-(define_insn "*aarch64_sve_mov<mode>_le"
- [(set (match_operand:SVE_STRUCT 0 "aarch64_sve_nonimmediate_operand" "=w, Utr, w, w")
- (match_operand:SVE_STRUCT 1 "aarch64_sve_general_operand" "Utr, w, w, Dn"))]
+;; Duplicate an Advanced SIMD vector to fill an SVE vector (LE version).
+(define_insn "@aarch64_vec_duplicate_vq<mode>_le"
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
+ (vec_duplicate:SVE_ALL
+ (match_operand:<V128> 1 "register_operand" "w")))]
"TARGET_SVE && !BYTES_BIG_ENDIAN"
- "#"
- [(set_attr "length" "<insn_length>")]
+ {
+ operands[1] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
+ return "dup\t%0.q, %1.q[0]";
+ }
)
-;; Unpredicated structure moves (big-endian). Memory accesses require
-;; secondary reloads.
-(define_insn "*aarch64_sve_mov<mode>_le"
- [(set (match_operand:SVE_STRUCT 0 "register_operand" "=w, w")
- (match_operand:SVE_STRUCT 1 "aarch64_nonmemory_operand" "w, Dn"))]
- "TARGET_SVE && BYTES_BIG_ENDIAN"
- "#"
- [(set_attr "length" "<insn_length>")]
+;; Duplicate an Advanced SIMD vector to fill an SVE vector (BE version).
+;; The SVE register layout puts memory lane N into (architectural)
+;; register lane N, whereas the Advanced SIMD layout puts the memory
+;; lsb into the register lsb. We therefore have to describe this in rtl
+;; terms as a reverse of the V128 vector followed by a duplicate.
+(define_insn "@aarch64_vec_duplicate_vq<mode>_be"
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
+ (vec_duplicate:SVE_ALL
+ (vec_select:<V128>
+ (match_operand:<V128> 1 "register_operand" "w")
+ (match_operand 2 "descending_int_parallel"))))]
+ "TARGET_SVE
+ && BYTES_BIG_ENDIAN
+ && known_eq (INTVAL (XVECEXP (operands[2], 0, 0)),
+ GET_MODE_NUNITS (<V128>mode) - 1)"
+ {
+ operands[1] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
+ return "dup\t%0.q, %1.q[0]";
+ }
)
-;; Split unpredicated structure moves into pieces. This is the same
-;; for both big-endian and little-endian code, although it only needs
-;; to handle memory operands for little-endian code.
-(define_split
- [(set (match_operand:SVE_STRUCT 0 "aarch64_sve_nonimmediate_operand")
- (match_operand:SVE_STRUCT 1 "aarch64_sve_general_operand"))]
- "TARGET_SVE && reload_completed"
- [(const_int 0)]
+;; This is used for vec_duplicate<mode>s from memory, but can also
+;; be used by combine to optimize selects of a a vec_duplicate<mode>
+;; with zero.
+(define_insn "sve_ld1r<mode>"
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
+ (unspec:SVE_ALL
+ [(match_operand:<VPRED> 1 "register_operand" "Upl")
+ (vec_duplicate:SVE_ALL
+ (match_operand:<VEL> 2 "aarch64_sve_ld1r_operand" "Uty"))
+ (match_operand:SVE_ALL 3 "aarch64_simd_imm_zero")]
+ UNSPEC_SEL))]
+ "TARGET_SVE"
+ "ld1r<Vesize>\t%0.<Vetype>, %1/z, %2"
+)
+
+;; Load 128 bits from memory under predicate control and duplicate to
+;; fill a vector.
+(define_insn "@aarch64_sve_ld1rq<mode>"
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
+ (unspec:SVE_ALL
+ [(match_operand:<VPRED> 2 "register_operand" "Upl")
+ (match_operand:<V128> 1 "aarch64_sve_ld1rq_operand" "UtQ")]
+ UNSPEC_LD1RQ))]
+ "TARGET_SVE"
{
- rtx dest = operands[0];
- rtx src = operands[1];
- if (REG_P (dest) && REG_P (src))
- aarch64_simd_emit_reg_reg_move (operands, <VSINGLE>mode, <vector_count>);
- else
- for (unsigned int i = 0; i < <vector_count>; ++i)
- {
- rtx subdest = simplify_gen_subreg (<VSINGLE>mode, dest, <MODE>mode,
- i * BYTES_PER_SVE_VECTOR);
- rtx subsrc = simplify_gen_subreg (<VSINGLE>mode, src, <MODE>mode,
- i * BYTES_PER_SVE_VECTOR);
- emit_insn (gen_rtx_SET (subdest, subsrc));
- }
- DONE;
+ operands[1] = gen_rtx_MEM (<VEL>mode, XEXP (operands[1], 0));
+ return "ld1rq<Vesize>\t%0.<Vetype>, %2/z, %1";
}
)
-;; Predicated structure moves. This works for both endiannesses but in
-;; practice is only useful for big-endian.
-(define_insn_and_split "@aarch64_pred_mov<mode>"
- [(set (match_operand:SVE_STRUCT 0 "aarch64_sve_struct_nonimmediate_operand" "=w, w, Utx")
- (unspec:SVE_STRUCT
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
- (match_operand:SVE_STRUCT 2 "aarch64_sve_struct_nonimmediate_operand" "w, Utx, w")]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE
- && (register_operand (operands[0], <MODE>mode)
- || register_operand (operands[2], <MODE>mode))"
- "#"
- "&& reload_completed"
- [(const_int 0)]
+;; -------------------------------------------------------------------------
+;; ---- [INT,FP] Initialize from individual elements
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - INSR
+;; -------------------------------------------------------------------------
+
+(define_expand "vec_init<mode><Vel>"
+ [(match_operand:SVE_ALL 0 "register_operand")
+ (match_operand 1 "")]
+ "TARGET_SVE"
{
- for (unsigned int i = 0; i < <vector_count>; ++i)
- {
- rtx subdest = simplify_gen_subreg (<VSINGLE>mode, operands[0],
- <MODE>mode,
- i * BYTES_PER_SVE_VECTOR);
- rtx subsrc = simplify_gen_subreg (<VSINGLE>mode, operands[2],
- <MODE>mode,
- i * BYTES_PER_SVE_VECTOR);
- aarch64_emit_sve_pred_move (subdest, operands[1], subsrc);
- }
+ aarch64_sve_expand_vector_init (operands[0], operands[1]);
DONE;
}
- [(set_attr "length" "<insn_length>")]
)
-(define_expand "mov<mode>"
- [(set (match_operand:PRED_ALL 0 "nonimmediate_operand")
- (match_operand:PRED_ALL 1 "general_operand"))]
+;; Shift an SVE vector left and insert a scalar into element 0.
+(define_insn "vec_shl_insert_<mode>"
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=?w, w, ??&w, ?&w")
+ (unspec:SVE_ALL
+ [(match_operand:SVE_ALL 1 "register_operand" "0, 0, w, w")
+ (match_operand:<VEL> 2 "aarch64_reg_or_zero" "rZ, w, rZ, w")]
+ UNSPEC_INSR))]
"TARGET_SVE"
- {
- if (GET_CODE (operands[0]) == MEM)
- operands[1] = force_reg (<MODE>mode, operands[1]);
- }
+ "@
+ insr\t%0.<Vetype>, %<vwcore>2
+ insr\t%0.<Vetype>, %<Vetype>2
+ movprfx\t%0, %1\;insr\t%0.<Vetype>, %<vwcore>2
+ movprfx\t%0, %1\;insr\t%0.<Vetype>, %<Vetype>2"
+ [(set_attr "movprfx" "*,*,yes,yes")]
)
-(define_insn "*aarch64_sve_mov<mode>"
- [(set (match_operand:PRED_ALL 0 "nonimmediate_operand" "=Upa, m, Upa, Upa, Upa")
- (match_operand:PRED_ALL 1 "general_operand" "Upa, Upa, m, Dz, Dm"))]
- "TARGET_SVE
- && (register_operand (operands[0], <MODE>mode)
- || register_operand (operands[1], <MODE>mode))"
+;; -------------------------------------------------------------------------
+;; ---- [INT] Linear series
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - INDEX
+;; -------------------------------------------------------------------------
+
+(define_insn "vec_series<mode>"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, w, w")
+ (vec_series:SVE_I
+ (match_operand:<VEL> 1 "aarch64_sve_index_operand" "Usi, r, r")
+ (match_operand:<VEL> 2 "aarch64_sve_index_operand" "r, Usi, r")))]
+ "TARGET_SVE"
"@
- mov\t%0.b, %1.b
- str\t%1, %0
- ldr\t%0, %1
- pfalse\t%0.b
- * return aarch64_output_ptrue (<MODE>mode, '<Vetype>');"
+ index\t%0.<Vetype>, #%1, %<vw>2
+ index\t%0.<Vetype>, %<vw>1, #%2
+ index\t%0.<Vetype>, %<vw>1, %<vw>2"
)
-;; Handle extractions from a predicate by converting to an integer vector
-;; and extracting from there.
-(define_expand "vec_extract<vpred><Vel>"
- [(match_operand:<VEL> 0 "register_operand")
- (match_operand:<VPRED> 1 "register_operand")
- (match_operand:SI 2 "nonmemory_operand")
- ;; Dummy operand to which we can attach the iterator.
- (reg:SVE_I V0_REGNUM)]
+;; Optimize {x, x, x, x, ...} + {0, n, 2*n, 3*n, ...} if n is in range
+;; of an INDEX instruction.
+(define_insn "*vec_series<mode>_plus"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w")
+ (plus:SVE_I
+ (vec_duplicate:SVE_I
+ (match_operand:<VEL> 1 "register_operand" "r"))
+ (match_operand:SVE_I 2 "immediate_operand")))]
+ "TARGET_SVE && aarch64_check_zero_based_sve_index_immediate (operands[2])"
+ {
+ operands[2] = aarch64_check_zero_based_sve_index_immediate (operands[2]);
+ return "index\t%0.<Vetype>, %<vw>1, #%2";
+ }
+)
+
+;; -------------------------------------------------------------------------
+;; ---- [PRED] Duplicate element
+;; -------------------------------------------------------------------------
+;; The patterns in this section are synthetic.
+;; -------------------------------------------------------------------------
+
+;; Implement a predicate broadcast by shifting the low bit of the scalar
+;; input into the top bit and using a WHILELO. An alternative would be to
+;; duplicate the input and do a compare with zero.
+(define_expand "vec_duplicate<mode>"
+ [(set (match_operand:PRED_ALL 0 "register_operand")
+ (vec_duplicate:PRED_ALL (match_operand 1 "register_operand")))]
"TARGET_SVE"
{
- rtx tmp = gen_reg_rtx (<MODE>mode);
- emit_insn (gen_aarch64_sve_dup<mode>_const (tmp, operands[1],
- CONST1_RTX (<MODE>mode),
- CONST0_RTX (<MODE>mode)));
- emit_insn (gen_vec_extract<mode><Vel> (operands[0], tmp, operands[2]));
+ rtx tmp = gen_reg_rtx (DImode);
+ rtx op1 = gen_lowpart (DImode, operands[1]);
+ emit_insn (gen_ashldi3 (tmp, op1, gen_int_mode (63, DImode)));
+ emit_insn (gen_while_ultdi<mode> (operands[0], const0_rtx, tmp));
DONE;
}
)
+;; =========================================================================
+;; == Vector decomposition
+;; =========================================================================
+
+;; -------------------------------------------------------------------------
+;; ---- [INT,FP] Extract index
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - DUP (Advanced SIMD)
+;; - DUP (SVE)
+;; - EXT (SVE)
+;; - ST1 (Advanced SIMD)
+;; - UMOV (Advanced SIMD)
+;; -------------------------------------------------------------------------
+
(define_expand "vec_extract<mode><Vel>"
[(set (match_operand:<VEL> 0 "register_operand")
(vec_select:<VEL>
@@ -594,18 +1357,28 @@
;; Extract an element outside the range of DUP. This pattern requires the
;; source and destination to be the same.
(define_insn "*vec_extract<mode><Vel>_ext"
- [(set (match_operand:<VEL> 0 "register_operand" "=w")
+ [(set (match_operand:<VEL> 0 "register_operand" "=w, ?&w")
(vec_select:<VEL>
- (match_operand:SVE_ALL 1 "register_operand" "0")
+ (match_operand:SVE_ALL 1 "register_operand" "0, w")
(parallel [(match_operand:SI 2 "const_int_operand")])))]
"TARGET_SVE && INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode) >= 64"
{
operands[0] = gen_rtx_REG (<MODE>mode, REGNO (operands[0]));
operands[2] = GEN_INT (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode));
- return "ext\t%0.b, %0.b, %0.b, #%2";
+ return (which_alternative == 0
+ ? "ext\t%0.b, %0.b, %0.b, #%2"
+ : "movprfx\t%0, %1\;ext\t%0.b, %0.b, %1.b, #%2");
}
+ [(set_attr "movprfx" "*,yes")]
)
+;; -------------------------------------------------------------------------
+;; ---- [INT,FP] Extract active element
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - LASTB
+;; -------------------------------------------------------------------------
+
;; Extract the last active element of operand 1 into operand 0.
;; If no elements are active, extract the last inactive element instead.
(define_insn "extract_last_<mode>"
@@ -620,395 +1393,803 @@
lastb\t%<Vetype>0, %1, %2.<Vetype>"
)
-(define_expand "vec_duplicate<mode>"
- [(parallel
- [(set (match_operand:SVE_ALL 0 "register_operand")
- (vec_duplicate:SVE_ALL
- (match_operand:<VEL> 1 "aarch64_sve_dup_operand")))
- (clobber (scratch:<VPRED>))])]
+;; -------------------------------------------------------------------------
+;; ---- [PRED] Extract index
+;; -------------------------------------------------------------------------
+;; The patterns in this section are synthetic.
+;; -------------------------------------------------------------------------
+
+;; Handle extractions from a predicate by converting to an integer vector
+;; and extracting from there.
+(define_expand "vec_extract<vpred><Vel>"
+ [(match_operand:<VEL> 0 "register_operand")
+ (match_operand:<VPRED> 1 "register_operand")
+ (match_operand:SI 2 "nonmemory_operand")
+ ;; Dummy operand to which we can attach the iterator.
+ (reg:SVE_I V0_REGNUM)]
"TARGET_SVE"
{
- if (MEM_P (operands[1]))
- {
- rtx ptrue = aarch64_ptrue_reg (<VPRED>mode);
- emit_insn (gen_sve_ld1r<mode> (operands[0], ptrue, operands[1],
- CONST0_RTX (<MODE>mode)));
- DONE;
- }
+ rtx tmp = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_vcond_mask_<mode><vpred> (tmp, operands[1],
+ CONST1_RTX (<MODE>mode),
+ CONST0_RTX (<MODE>mode)));
+ emit_insn (gen_vec_extract<mode><Vel> (operands[0], tmp, operands[2]));
+ DONE;
}
)
-;; Accept memory operands for the benefit of combine, and also in case
-;; the scalar input gets spilled to memory during RA. We want to split
-;; the load at the first opportunity in order to allow the PTRUE to be
-;; optimized with surrounding code.
-(define_insn_and_split "*vec_duplicate<mode>_reg"
- [(set (match_operand:SVE_ALL 0 "register_operand" "=w, w, w")
- (vec_duplicate:SVE_ALL
- (match_operand:<VEL> 1 "aarch64_sve_dup_operand" "r, w, Uty")))
- (clobber (match_scratch:<VPRED> 2 "=X, X, Upl"))]
+;; =========================================================================
+;; == Unary arithmetic
+;; =========================================================================
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] General unary arithmetic corresponding to rtx codes
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - ABS
+;; - CLS (= clrsb)
+;; - CLZ
+;; - CNT (= popcount)
+;; - NEG
+;; - NOT
+;; -------------------------------------------------------------------------
+
+;; Unpredicated integer unary arithmetic.
+(define_expand "<optab><mode>2"
+ [(set (match_operand:SVE_I 0 "register_operand")
+ (unspec:SVE_I
+ [(match_dup 2)
+ (SVE_INT_UNARY:SVE_I (match_operand:SVE_I 1 "register_operand"))]
+ UNSPEC_PRED_X))]
"TARGET_SVE"
- "@
- mov\t%0.<Vetype>, %<vwcore>1
- mov\t%0.<Vetype>, %<Vetype>1
- #"
- "&& MEM_P (operands[1])"
- [(const_int 0)]
{
- if (GET_CODE (operands[2]) == SCRATCH)
- operands[2] = gen_reg_rtx (<VPRED>mode);
- emit_move_insn (operands[2], CONSTM1_RTX (<VPRED>mode));
- emit_insn (gen_sve_ld1r<mode> (operands[0], operands[2], operands[1],
- CONST0_RTX (<MODE>mode)));
- DONE;
+ operands[2] = aarch64_ptrue_reg (<VPRED>mode);
}
- [(set_attr "length" "4,4,8")]
)
-;; This is used for vec_duplicate<mode>s from memory, but can also
-;; be used by combine to optimize selects of a a vec_duplicate<mode>
-;; with zero.
-(define_insn "sve_ld1r<mode>"
- [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
- (unspec:SVE_ALL
+;; Integer unary arithmetic predicated with a PTRUE.
+(define_insn "*<optab><mode>2"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w")
+ (unspec:SVE_I
[(match_operand:<VPRED> 1 "register_operand" "Upl")
- (vec_duplicate:SVE_ALL
- (match_operand:<VEL> 2 "aarch64_sve_ld1r_operand" "Uty"))
- (match_operand:SVE_ALL 3 "aarch64_simd_imm_zero")]
+ (SVE_INT_UNARY:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "w"))]
+ UNSPEC_PRED_X))]
+ "TARGET_SVE"
+ "<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+)
+
+;; Predicated integer unary arithmetic, merging with the first input.
+(define_insn "*cond_<optab><mode>_2"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (SVE_INT_UNARY:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "0, w"))
+ (match_dup 2)]
UNSPEC_SEL))]
"TARGET_SVE"
- "ld1r<Vesize>\t%0.<Vetype>, %1/z, %2"
+ "@
+ <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>
+ movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
-;; Load 128 bits from memory and duplicate to fill a vector. Since there
-;; are so few operations on 128-bit "elements", we don't define a VNx1TI
-;; and simply use vectors of bytes instead.
-(define_insn "*sve_ld1rq<Vesize>"
- [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
- (unspec:SVE_ALL
+;; Predicated integer unary arithmetic, merging with an independent value.
+;;
+;; The earlyclobber isn't needed for the first alternative, but omitting
+;; it would only help the case in which operands 2 and 3 are the same,
+;; which is handled above rather than here. Marking all the alternatives
+;; as earlyclobber helps to make the instruction more regular to the
+;; register allocator.
+(define_insn "*cond_<optab><mode>_any"
+ [(set (match_operand:SVE_I 0 "register_operand" "=&w, ?&w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (SVE_INT_UNARY:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "w, w, w"))
+ (match_operand:SVE_I 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE && !rtx_equal_p (operands[2], operands[3])"
+ "@
+ <sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
+ movprfx\t%0, %3\;<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ [(set_attr "movprfx" "*,yes,yes")]
+)
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] General unary arithmetic corresponding to unspecs
+;; -------------------------------------------------------------------------
+;; Includes
+;; - REVB
+;; - REVH
+;; - REVW
+;; -------------------------------------------------------------------------
+
+;; Predicated integer unary operations.
+(define_insn "@aarch64_pred_<optab><mode>"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w")
+ (unspec:SVE_I
[(match_operand:<VPRED> 1 "register_operand" "Upl")
- (match_operand:TI 2 "aarch64_sve_ld1r_operand" "Uty")]
- UNSPEC_LD1RQ))]
- "TARGET_SVE"
- "ld1rq<Vesize>\t%0.<Vetype>, %1/z, %2"
+ (unspec:SVE_I
+ [(match_operand:SVE_I 2 "register_operand" "w")]
+ SVE_INT_UNARY)]
+ UNSPEC_PRED_X))]
+ "TARGET_SVE && <elem_bits> >= <min_elem_bits>"
+ "<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
)
-;; Implement a predicate broadcast by shifting the low bit of the scalar
-;; input into the top bit and using a WHILELO. An alternative would be to
-;; duplicate the input and do a compare with zero.
-(define_expand "vec_duplicate<mode>"
- [(set (match_operand:PRED_ALL 0 "register_operand")
- (vec_duplicate:PRED_ALL (match_operand 1 "register_operand")))]
+;; -------------------------------------------------------------------------
+;; ---- [INT] Zero extension
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - UXTB
+;; - UXTH
+;; - UXTW
+;; -------------------------------------------------------------------------
+
+;; Match UXT[BHW] as a conditional AND of a constant, merging with the
+;; first input.
+(define_insn "*cond_uxt<mode>_2"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (and:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "0, w")
+ (match_operand:SVE_I 3 "aarch64_sve_uxt_immediate"))
+ (match_dup 2)]
+ UNSPEC_SEL))]
"TARGET_SVE"
- {
- rtx tmp = gen_reg_rtx (DImode);
- rtx op1 = gen_lowpart (DImode, operands[1]);
- emit_insn (gen_ashldi3 (tmp, op1, gen_int_mode (63, DImode)));
- emit_insn (gen_while_ultdi<mode> (operands[0], const0_rtx, tmp));
- DONE;
- }
+ "@
+ uxt%e3\t%0.<Vetype>, %1/m, %0.<Vetype>
+ movprfx\t%0, %2\;uxt%e3\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
-(define_insn "vec_series<mode>"
- [(set (match_operand:SVE_I 0 "register_operand" "=w, w, w")
- (vec_series:SVE_I
- (match_operand:<VEL> 1 "aarch64_sve_index_operand" "Usi, r, r")
- (match_operand:<VEL> 2 "aarch64_sve_index_operand" "r, Usi, r")))]
- "TARGET_SVE"
+;; Match UXT[BHW] as a conditional AND of a constant, merging with an
+;; independent value.
+;;
+;; The earlyclobber isn't needed for the first alternative, but omitting
+;; it would only help the case in which operands 2 and 4 are the same,
+;; which is handled above rather than here. Marking all the alternatives
+;; as early-clobber helps to make the instruction more regular to the
+;; register allocator.
+(define_insn "*cond_uxt<mode>_any"
+ [(set (match_operand:SVE_I 0 "register_operand" "=&w, ?&w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (and:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "w, w, w")
+ (match_operand:SVE_I 3 "aarch64_sve_uxt_immediate"))
+ (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero" "0, Dz, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
"@
- index\t%0.<Vetype>, #%1, %<vw>2
- index\t%0.<Vetype>, %<vw>1, #%2
- index\t%0.<Vetype>, %<vw>1, %<vw>2"
+ uxt%e3\t%0.<Vetype>, %1/m, %2.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;uxt%e3\t%0.<Vetype>, %1/m, %2.<Vetype>
+ movprfx\t%0, %4\;uxt%e3\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ [(set_attr "movprfx" "*,yes,yes")]
)
-;; Optimize {x, x, x, x, ...} + {0, n, 2*n, 3*n, ...} if n is in range
-;; of an INDEX instruction.
-(define_insn "*vec_series<mode>_plus"
+;; -------------------------------------------------------------------------
+;; ---- [INT] Logical inverse
+;; -------------------------------------------------------------------------
+
+;; Predicated logical inverse.
+(define_insn "*cnot<mode>"
[(set (match_operand:SVE_I 0 "register_operand" "=w")
- (plus:SVE_I
- (vec_duplicate:SVE_I
- (match_operand:<VEL> 1 "register_operand" "r"))
- (match_operand:SVE_I 2 "immediate_operand")))]
- "TARGET_SVE && aarch64_check_zero_based_sve_index_immediate (operands[2])"
+ (unspec:SVE_I
+ [(unspec:<VPRED>
+ [(match_operand:<VPRED> 1 "register_operand" "Upl")
+ (match_operand:SI 5 "aarch64_sve_ptrue_flag")
+ (eq:<VPRED>
+ (match_operand:SVE_I 2 "register_operand" "w")
+ (match_operand:SVE_I 3 "aarch64_simd_imm_zero"))]
+ UNSPEC_PRED_Z)
+ (match_operand:SVE_I 4 "aarch64_simd_imm_one")
+ (match_dup 3)]
+ UNSPEC_SEL))]
+ "TARGET_SVE"
+ "cnot\t%0.<Vetype>, %1/m, %2.<Vetype>"
+)
+
+;; Predicated logical inverse, merging with the first input.
+(define_insn_and_rewrite "*cond_cnot<mode>_2"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ ;; Logical inverse of operand 2 (as above).
+ (unspec:SVE_I
+ [(unspec:<VPRED>
+ [(match_operand 5)
+ (const_int SVE_KNOWN_PTRUE)
+ (eq:<VPRED>
+ (match_operand:SVE_I 2 "register_operand" "0, w")
+ (match_operand:SVE_I 3 "aarch64_simd_imm_zero"))]
+ UNSPEC_PRED_Z)
+ (match_operand:SVE_I 4 "aarch64_simd_imm_one")
+ (match_dup 3)]
+ UNSPEC_SEL)
+ (match_dup 2)]
+ UNSPEC_SEL))]
+ "TARGET_SVE"
+ "@
+ cnot\t%0.<Vetype>, %1/m, %0.<Vetype>
+ movprfx\t%0, %2\;cnot\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ "&& !CONSTANT_P (operands[5])"
{
- operands[2] = aarch64_check_zero_based_sve_index_immediate (operands[2]);
- return "index\t%0.<Vetype>, %<vw>1, #%2";
+ operands[5] = CONSTM1_RTX (<VPRED>mode);
}
+ [(set_attr "movprfx" "*,yes")]
)
-;; Unpredicated LD[234].
-(define_expand "vec_load_lanes<mode><vsingle>"
- [(set (match_operand:SVE_STRUCT 0 "register_operand")
- (unspec:SVE_STRUCT
+;; Predicated logical inverse, merging with an independent value.
+;;
+;; The earlyclobber isn't needed for the first alternative, but omitting
+;; it would only help the case in which operands 2 and 6 are the same,
+;; which is handled above rather than here. Marking all the alternatives
+;; as earlyclobber helps to make the instruction more regular to the
+;; register allocator.
+(define_insn_and_rewrite "*cond_cnot<mode>_any"
+ [(set (match_operand:SVE_I 0 "register_operand" "=&w, ?&w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ ;; Logical inverse of operand 2 (as above).
+ (unspec:SVE_I
+ [(unspec:<VPRED>
+ [(match_operand 5)
+ (const_int SVE_KNOWN_PTRUE)
+ (eq:<VPRED>
+ (match_operand:SVE_I 2 "register_operand" "w, w, w")
+ (match_operand:SVE_I 3 "aarch64_simd_imm_zero"))]
+ UNSPEC_PRED_Z)
+ (match_operand:SVE_I 4 "aarch64_simd_imm_one")
+ (match_dup 3)]
+ UNSPEC_SEL)
+ (match_operand:SVE_I 6 "aarch64_simd_reg_or_zero" "0, Dz, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE && !rtx_equal_p (operands[2], operands[6])"
+ "@
+ cnot\t%0.<Vetype>, %1/m, %2.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;cnot\t%0.<Vetype>, %1/m, %2.<Vetype>
+ movprfx\t%0, %6\;cnot\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ "&& !CONSTANT_P (operands[5])"
+ {
+ operands[5] = CONSTM1_RTX (<VPRED>mode);
+ }
+ [(set_attr "movprfx" "*,yes,yes")]
+)
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] General unary arithmetic corresponding to unspecs
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - FABS
+;; - FNEG
+;; - FRINTA
+;; - FRINTI
+;; - FRINTM
+;; - FRINTN
+;; - FRINTP
+;; - FRINTX
+;; - FRINTZ
+;; - FSQRT
+;; -------------------------------------------------------------------------
+
+;; Unpredicated floating-point unary operations.
+(define_expand "<optab><mode>2"
+ [(set (match_operand:SVE_F 0 "register_operand")
+ (unspec:SVE_F
[(match_dup 2)
- (match_operand:SVE_STRUCT 1 "memory_operand")]
- UNSPEC_LDN))]
+ (const_int SVE_RELAXED_GP)
+ (match_operand:SVE_F 1 "register_operand")]
+ SVE_COND_FP_UNARY))]
"TARGET_SVE"
{
operands[2] = aarch64_ptrue_reg (<VPRED>mode);
}
)
-;; Predicated LD[234].
-(define_insn "vec_mask_load_lanes<mode><vsingle>"
- [(set (match_operand:SVE_STRUCT 0 "register_operand" "=w")
- (unspec:SVE_STRUCT
- [(match_operand:<VPRED> 2 "register_operand" "Upl")
- (match_operand:SVE_STRUCT 1 "memory_operand" "m")]
- UNSPEC_LDN))]
+;; Predicated floating-point unary operations.
+(define_insn "*<optab><mode>2"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl")
+ (match_operand:SI 3 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "w")]
+ SVE_COND_FP_UNARY))]
"TARGET_SVE"
- "ld<vector_count><Vesize>\t%0, %2/z, %1"
+ "<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
)
-;; Unpredicated ST[234]. This is always a full update, so the dependence
-;; on the old value of the memory location (via (match_dup 0)) is redundant.
-;; There doesn't seem to be any obvious benefit to treating the all-true
-;; case differently though. In particular, it's very unlikely that we'll
-;; only find out during RTL that a store_lanes is dead.
-(define_expand "vec_store_lanes<mode><vsingle>"
- [(set (match_operand:SVE_STRUCT 0 "memory_operand")
- (unspec:SVE_STRUCT
- [(match_dup 2)
- (match_operand:SVE_STRUCT 1 "register_operand")
- (match_dup 0)]
- UNSPEC_STN))]
- "TARGET_SVE"
+;; Predicated floating-point unary arithmetic, merging with the first input.
+(define_insn_and_rewrite "*cond_<optab><mode>_2"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 3)
+ (match_operand:SI 4 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "0, w")]
+ SVE_COND_FP_UNARY)
+ (match_dup 2)]
+ UNSPEC_SEL))]
+ "TARGET_SVE && aarch64_sve_pred_dominates_p (&operands[3], operands[1])"
+ "@
+ <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>
+ movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ "&& !rtx_equal_p (operands[1], operands[3])"
{
- operands[2] = aarch64_ptrue_reg (<VPRED>mode);
+ operands[3] = copy_rtx (operands[1]);
}
+ [(set_attr "movprfx" "*,yes")]
)
-;; Predicated ST[234].
-(define_insn "vec_mask_store_lanes<mode><vsingle>"
- [(set (match_operand:SVE_STRUCT 0 "memory_operand" "+m")
- (unspec:SVE_STRUCT
- [(match_operand:<VPRED> 2 "register_operand" "Upl")
- (match_operand:SVE_STRUCT 1 "register_operand" "w")
- (match_dup 0)]
- UNSPEC_STN))]
- "TARGET_SVE"
- "st<vector_count><Vesize>\t%1, %2, %0"
-)
-
-(define_expand "vec_perm<mode>"
- [(match_operand:SVE_ALL 0 "register_operand")
- (match_operand:SVE_ALL 1 "register_operand")
- (match_operand:SVE_ALL 2 "register_operand")
- (match_operand:<V_INT_EQUIV> 3 "aarch64_sve_vec_perm_operand")]
- "TARGET_SVE && GET_MODE_NUNITS (<MODE>mode).is_constant ()"
+;; Predicated floating-point unary arithmetic, merging with an independent
+;; value.
+;;
+;; The earlyclobber isn't needed for the first alternative, but omitting
+;; it would only help the case in which operands 2 and 3 are the same,
+;; which is handled above rather than here. Marking all the alternatives
+;; as earlyclobber helps to make the instruction more regular to the
+;; register allocator.
+(define_insn_and_rewrite "*cond_<optab><mode>_any"
+ [(set (match_operand:SVE_F 0 "register_operand" "=&w, ?&w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 4)
+ (match_operand:SI 5 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "w, w, w")]
+ SVE_COND_FP_UNARY)
+ (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && !rtx_equal_p (operands[2], operands[3])
+ && aarch64_sve_pred_dominates_p (&operands[4], operands[1])"
+ "@
+ <sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>
+ movprfx\t%0, %3\;<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ "&& !rtx_equal_p (operands[1], operands[4])"
{
- aarch64_expand_sve_vec_perm (operands[0], operands[1],
- operands[2], operands[3]);
- DONE;
+ operands[4] = copy_rtx (operands[1]);
}
+ [(set_attr "movprfx" "*,yes,yes")]
)
-(define_insn "*aarch64_sve_tbl<mode>"
- [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
- (unspec:SVE_ALL
- [(match_operand:SVE_ALL 1 "register_operand" "w")
- (match_operand:<V_INT_EQUIV> 2 "register_operand" "w")]
- UNSPEC_TBL))]
+;; -------------------------------------------------------------------------
+;; ---- [PRED] Inverse
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - NOT
+;; -------------------------------------------------------------------------
+
+;; Unpredicated predicate inverse.
+(define_expand "one_cmpl<mode>2"
+ [(set (match_operand:PRED_ALL 0 "register_operand")
+ (and:PRED_ALL
+ (not:PRED_ALL (match_operand:PRED_ALL 1 "register_operand"))
+ (match_dup 2)))]
"TARGET_SVE"
- "tbl\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
+ {
+ operands[2] = aarch64_ptrue_reg (<MODE>mode);
+ }
)
-(define_insn "*aarch64_sve_<perm_insn><perm_hilo><mode>"
+;; Predicated predicate inverse.
+(define_insn "*one_cmpl<mode>3"
[(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
- (unspec:PRED_ALL [(match_operand:PRED_ALL 1 "register_operand" "Upa")
- (match_operand:PRED_ALL 2 "register_operand" "Upa")]
- PERMUTE))]
+ (and:PRED_ALL
+ (not:PRED_ALL (match_operand:PRED_ALL 2 "register_operand" "Upa"))
+ (match_operand:PRED_ALL 1 "register_operand" "Upa")))]
"TARGET_SVE"
- "<perm_insn><perm_hilo>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
+ "not\t%0.b, %1/z, %2.b"
)
-(define_insn "aarch64_sve_<perm_insn><perm_hilo><mode>"
- [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
- (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "w")
- (match_operand:SVE_ALL 2 "register_operand" "w")]
- PERMUTE))]
+;; =========================================================================
+;; == Binary arithmetic
+;; =========================================================================
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] General binary arithmetic corresponding to rtx codes
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - ADD (merging form only)
+;; - AND (merging form only)
+;; - ASR (merging form only)
+;; - EOR (merging form only)
+;; - LSL (merging form only)
+;; - LSR (merging form only)
+;; - MUL
+;; - ORR (merging form only)
+;; - SMAX
+;; - SMIN
+;; - SUB (merging form only)
+;; - UMAX
+;; - UMIN
+;; -------------------------------------------------------------------------
+
+;; Unpredicated integer binary operations that have an immediate form.
+(define_expand "<optab><mode>3"
+ [(set (match_operand:SVE_I 0 "register_operand")
+ (unspec:SVE_I
+ [(match_dup 3)
+ (SVE_INT_BINARY_IMM:SVE_I
+ (match_operand:SVE_I 1 "register_operand")
+ (match_operand:SVE_I 2 "aarch64_sve_<sve_imm_con>_operand"))]
+ UNSPEC_PRED_X))]
"TARGET_SVE"
- "<perm_insn><perm_hilo>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
+ {
+ operands[3] = aarch64_ptrue_reg (<VPRED>mode);
+ }
)
-(define_insn "*aarch64_sve_rev64<mode>"
- [(set (match_operand:SVE_BHS 0 "register_operand" "=w")
- (unspec:SVE_BHS
- [(match_operand:VNx2BI 1 "register_operand" "Upl")
- (unspec:SVE_BHS [(match_operand:SVE_BHS 2 "register_operand" "w")]
- UNSPEC_REV64)]
- UNSPEC_MERGE_PTRUE))]
+;; Integer binary operations that have an immediate form, predicated
+;; with a PTRUE. We don't actually need the predicate for the first
+;; and third alternatives, but using Upa or X isn't likely to gain much
+;; and would make the instruction seem less uniform to the register
+;; allocator.
+(define_insn_and_split "*<optab><mode>3"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
+ (SVE_INT_BINARY_IMM:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "%0, 0, w, w")
+ (match_operand:SVE_I 3 "aarch64_sve_<sve_imm_con>_operand" "<sve_imm_con>, w, <sve_imm_con>, w"))]
+ UNSPEC_PRED_X))]
"TARGET_SVE"
- "rev<Vesize>\t%0.d, %1/m, %2.d"
+ "@
+ #
+ <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ #
+ movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ ; Split the unpredicated form after reload, so that we don't have
+ ; the unnecessary PTRUE.
+ "&& reload_completed
+ && !register_operand (operands[3], <MODE>mode)"
+ [(set (match_dup 0) (SVE_INT_BINARY_IMM:SVE_I (match_dup 2) (match_dup 3)))]
+ ""
+ [(set_attr "movprfx" "*,*,yes,yes")]
)
-(define_insn "*aarch64_sve_rev32<mode>"
- [(set (match_operand:SVE_BH 0 "register_operand" "=w")
- (unspec:SVE_BH
- [(match_operand:VNx4BI 1 "register_operand" "Upl")
- (unspec:SVE_BH [(match_operand:SVE_BH 2 "register_operand" "w")]
- UNSPEC_REV32)]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "rev<Vesize>\t%0.s, %1/m, %2.s"
+;; Unpredicated binary operations with a constant (post-RA only).
+;; These are generated by splitting a predicated instruction whose
+;; predicate is unused.
+(define_insn "*post_ra_<optab><mode>3"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (SVE_INT_BINARY_IMM:SVE_I
+ (match_operand:SVE_I 1 "register_operand" "0, w")
+ (match_operand:SVE_I 2 "aarch64_sve_<sve_imm_con>_immediate")))]
+ "TARGET_SVE && reload_completed"
+ "@
+ <sve_int_op>\t%0.<Vetype>, %0.<Vetype>, #%<sve_imm_prefix>2
+ movprfx\t%0, %1\;<sve_int_op>\t%0.<Vetype>, %0.<Vetype>, #%<sve_imm_prefix>2"
+ [(set_attr "movprfx" "*,yes")]
)
-(define_insn "*aarch64_sve_rev16vnx16qi"
- [(set (match_operand:VNx16QI 0 "register_operand" "=w")
- (unspec:VNx16QI
- [(match_operand:VNx8BI 1 "register_operand" "Upl")
- (unspec:VNx16QI [(match_operand:VNx16QI 2 "register_operand" "w")]
- UNSPEC_REV16)]
- UNSPEC_MERGE_PTRUE))]
+;; Predicated integer operations with merging.
+(define_expand "@cond_<optab><mode>"
+ [(set (match_operand:SVE_I 0 "register_operand")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand")
+ (SVE_INT_BINARY:SVE_I
+ (match_operand:SVE_I 2 "register_operand")
+ (match_operand:SVE_I 3 "<sve_pred_int_rhs2_operand>"))
+ (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero")]
+ UNSPEC_SEL))]
"TARGET_SVE"
- "revb\t%0.h, %1/m, %2.h"
)
-(define_insn "@aarch64_sve_rev<mode>"
- [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
- (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "w")]
- UNSPEC_REV))]
+;; Predicated integer operations, merging with the first input.
+(define_insn "*cond_<optab><mode>_2"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (SVE_INT_BINARY:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "0, w")
+ (match_operand:SVE_I 3 "register_operand" "w, w"))
+ (match_dup 2)]
+ UNSPEC_SEL))]
"TARGET_SVE"
- "rev\t%0.<Vetype>, %1.<Vetype>")
+ "@
+ <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
+)
-(define_insn "*aarch64_sve_dup_lane<mode>"
- [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
- (vec_duplicate:SVE_ALL
- (vec_select:<VEL>
- (match_operand:SVE_ALL 1 "register_operand" "w")
- (parallel [(match_operand:SI 2 "const_int_operand")]))))]
- "TARGET_SVE
- && IN_RANGE (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode), 0, 63)"
- "dup\t%0.<Vetype>, %1.<Vetype>[%2]"
+;; Predicated integer operations, merging with the second input.
+(define_insn "*cond_<optab><mode>_3"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (SVE_INT_BINARY:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "w, w")
+ (match_operand:SVE_I 3 "register_operand" "0, w"))
+ (match_dup 3)]
+ UNSPEC_SEL))]
+ "TARGET_SVE"
+ "@
+ <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+ movprfx\t%0, %3\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
-;; Note that the immediate (third) operand is the lane index not
-;; the byte index.
-(define_insn "*aarch64_sve_ext<mode>"
- [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
- (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "0")
- (match_operand:SVE_ALL 2 "register_operand" "w")
- (match_operand:SI 3 "const_int_operand")]
- UNSPEC_EXT))]
+;; Predicated integer operations, merging with an independent value.
+(define_insn_and_rewrite "*cond_<optab><mode>_any"
+ [(set (match_operand:SVE_I 0 "register_operand" "=&w, &w, &w, &w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
+ (SVE_INT_BINARY:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "0, w, w, w, w")
+ (match_operand:SVE_I 3 "register_operand" "w, 0, w, w, w"))
+ (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, 0, w")]
+ UNSPEC_SEL))]
"TARGET_SVE
- && IN_RANGE (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode), 0, 255)"
+ && !rtx_equal_p (operands[2], operands[4])
+ && !rtx_equal_p (operands[3], operands[4])"
+ "@
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ #"
+ "&& reload_completed
+ && register_operand (operands[4], <MODE>mode)
+ && !rtx_equal_p (operands[0], operands[4])"
{
- operands[3] = GEN_INT (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode));
- return "ext\\t%0.b, %0.b, %2.b, #%3";
+ emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
+ operands[4], operands[1]));
+ operands[4] = operands[2] = operands[0];
}
+ [(set_attr "movprfx" "yes")]
)
+;; -------------------------------------------------------------------------
+;; ---- [INT] Addition
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - ADD
+;; - DECB
+;; - DECD
+;; - DECH
+;; - DECW
+;; - INCB
+;; - INCD
+;; - INCH
+;; - INCW
+;; - SUB
+;; -------------------------------------------------------------------------
+
(define_insn "add<mode>3"
- [(set (match_operand:SVE_I 0 "register_operand" "=w, w, w, w")
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, w, w, ?w, ?w, w")
(plus:SVE_I
- (match_operand:SVE_I 1 "register_operand" "%0, 0, 0, w")
- (match_operand:SVE_I 2 "aarch64_sve_add_operand" "vsa, vsn, vsi, w")))]
+ (match_operand:SVE_I 1 "register_operand" "%0, 0, 0, w, w, w")
+ (match_operand:SVE_I 2 "aarch64_sve_add_operand" "vsa, vsn, vsi, vsa, vsn, w")))]
"TARGET_SVE"
"@
add\t%0.<Vetype>, %0.<Vetype>, #%D2
sub\t%0.<Vetype>, %0.<Vetype>, #%N2
- * return aarch64_output_sve_inc_dec_immediate (\"%0.<Vetype>\", operands[2]);
+ * return aarch64_output_sve_vector_inc_dec (\"%0.<Vetype>\", operands[2]);
+ movprfx\t%0, %1\;add\t%0.<Vetype>, %0.<Vetype>, #%D2
+ movprfx\t%0, %1\;sub\t%0.<Vetype>, %0.<Vetype>, #%N2
add\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
+ [(set_attr "movprfx" "*,*,*,yes,yes,*")]
)
+;; Merging forms are handled through SVE_INT_BINARY.
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] Subtraction
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - SUB
+;; - SUBR
+;; -------------------------------------------------------------------------
+
(define_insn "sub<mode>3"
- [(set (match_operand:SVE_I 0 "register_operand" "=w, w")
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
(minus:SVE_I
- (match_operand:SVE_I 1 "aarch64_sve_arith_operand" "w, vsa")
- (match_operand:SVE_I 2 "register_operand" "w, 0")))]
+ (match_operand:SVE_I 1 "aarch64_sve_arith_operand" "w, vsa, vsa")
+ (match_operand:SVE_I 2 "register_operand" "w, 0, w")))]
"TARGET_SVE"
"@
sub\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>
- subr\t%0.<Vetype>, %0.<Vetype>, #%D1"
+ subr\t%0.<Vetype>, %0.<Vetype>, #%D1
+ movprfx\t%0, %2\;subr\t%0.<Vetype>, %0.<Vetype>, #%D1"
+ [(set_attr "movprfx" "*,*,yes")]
)
-;; Unpredicated multiplication.
-(define_expand "mul<mode>3"
- [(set (match_operand:SVE_I 0 "register_operand")
- (unspec:SVE_I
- [(match_dup 3)
- (mult:SVE_I
- (match_operand:SVE_I 1 "register_operand")
- (match_operand:SVE_I 2 "aarch64_sve_mul_operand"))]
- UNSPEC_MERGE_PTRUE))]
+;; Merging forms are handled through SVE_INT_BINARY.
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] Take address
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - ADR
+;; -------------------------------------------------------------------------
+
+;; Unshifted ADR, with the offset being zero-extended from the low 32 bits.
+(define_insn "*aarch64_adr_uxtw"
+ [(set (match_operand:VNx2DI 0 "register_operand" "=w")
+ (plus:VNx2DI
+ (and:VNx2DI
+ (match_operand:VNx2DI 2 "register_operand" "w")
+ (match_operand:VNx2DI 3 "aarch64_sve_uxtw_immediate"))
+ (match_operand:VNx2DI 1 "register_operand" "w")))]
"TARGET_SVE"
+ "adr\t%0.d, [%1.d, %2.d, uxtw]"
+)
+
+;; ADR with a nonzero shift.
+(define_insn_and_rewrite "*aarch64_adr<mode>_shift"
+ [(set (match_operand:SVE_SDI 0 "register_operand" "=w")
+ (plus:SVE_SDI
+ (unspec:SVE_SDI
+ [(match_operand 4)
+ (ashift:SVE_SDI
+ (match_operand:SVE_SDI 2 "register_operand" "w")
+ (match_operand:SVE_SDI 3 "const_1_to_3_operand"))]
+ UNSPEC_PRED_X)
+ (match_operand:SVE_SDI 1 "register_operand" "w")))]
+ "TARGET_SVE"
+ "adr\t%0.<Vetype>, [%1.<Vetype>, %2.<Vetype>, lsl %3]"
+ "&& !CONSTANT_P (operands[4])"
{
- operands[3] = aarch64_ptrue_reg (<VPRED>mode);
+ operands[4] = CONSTM1_RTX (<VPRED>mode);
}
)
-;; Multiplication predicated with a PTRUE. We don't actually need the
-;; predicate for the first alternative, but using Upa or X isn't likely
-;; to gain much and would make the instruction seem less uniform to the
-;; register allocator.
-(define_insn_and_split "*mul<mode>3"
- [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
- (unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
- (mult:SVE_I
- (match_operand:SVE_I 2 "register_operand" "%0, 0, w")
- (match_operand:SVE_I 3 "aarch64_sve_mul_operand" "vsm, w, w"))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "@
- #
- mul\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- movprfx\t%0, %2\;mul\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
- ; Split the unpredicated form after reload, so that we don't have
- ; the unnecessary PTRUE.
- "&& reload_completed
- && !register_operand (operands[3], <MODE>mode)"
- [(set (match_dup 0) (mult:SVE_I (match_dup 2) (match_dup 3)))]
- ""
- [(set_attr "movprfx" "*,*,yes")]
+;; Same, but with the index being zero-extended from the low 32 bits.
+(define_insn_and_rewrite "*aarch64_adr_shift_uxtw"
+ [(set (match_operand:VNx2DI 0 "register_operand" "=w")
+ (plus:VNx2DI
+ (unspec:VNx2DI
+ [(match_operand 5)
+ (ashift:VNx2DI
+ (and:VNx2DI
+ (match_operand:VNx2DI 2 "register_operand" "w")
+ (match_operand:VNx2DI 4 "aarch64_sve_uxtw_immediate"))
+ (match_operand:VNx2DI 3 "const_1_to_3_operand"))]
+ UNSPEC_PRED_X)
+ (match_operand:VNx2DI 1 "register_operand" "w")))]
+ "TARGET_SVE"
+ "adr\t%0.d, [%1.d, %2.d, uxtw %3]"
+ "&& !CONSTANT_P (operands[5])"
+ {
+ operands[5] = CONSTM1_RTX (VNx2BImode);
+ }
)
-;; Unpredicated multiplications by a constant (post-RA only).
-;; These are generated by splitting a predicated instruction whose
-;; predicate is unused.
-(define_insn "*post_ra_mul<mode>3"
- [(set (match_operand:SVE_I 0 "register_operand" "=w")
- (mult:SVE_I
- (match_operand:SVE_I 1 "register_operand" "0")
- (match_operand:SVE_I 2 "aarch64_sve_mul_immediate")))]
- "TARGET_SVE && reload_completed"
- "mul\t%0.<Vetype>, %0.<Vetype>, #%2"
+;; -------------------------------------------------------------------------
+;; ---- [INT] Absolute difference
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - SABD
+;; - UABD
+;; -------------------------------------------------------------------------
+
+;; Unpredicated integer absolute difference.
+(define_expand "<su>abd<mode>_3"
+ [(use (match_operand:SVE_I 0 "register_operand"))
+ (USMAX:SVE_I (match_operand:SVE_I 1 "register_operand")
+ (match_operand:SVE_I 2 "register_operand"))]
+ "TARGET_SVE"
+ {
+ rtx pred = aarch64_ptrue_reg (<VPRED>mode);
+ emit_insn (gen_aarch64_<su>abd<mode>_3 (operands[0], pred, operands[1],
+ operands[2]));
+ DONE;
+ }
)
-(define_insn "*madd<mode>"
- [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
- (plus:SVE_I
- (unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
- (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w, w")
- (match_operand:SVE_I 3 "register_operand" "w, w, w"))]
- UNSPEC_MERGE_PTRUE)
- (match_operand:SVE_I 4 "register_operand" "w, 0, w")))]
+;; Predicated integer absolute difference.
+(define_insn "aarch64_<su>abd<mode>_3"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (minus:SVE_I
+ (USMAX:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "%0, w")
+ (match_operand:SVE_I 3 "register_operand" "w, w"))
+ (<max_opp>:SVE_I
+ (match_dup 2)
+ (match_dup 3)))]
+ UNSPEC_PRED_X))]
"TARGET_SVE"
"@
- mad\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
- mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
- movprfx\t%0, %4\;mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
- [(set_attr "movprfx" "*,*,yes")]
+ <su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %2\;<su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
-(define_insn "*msub<mode>3"
- [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
- (minus:SVE_I
- (match_operand:SVE_I 4 "register_operand" "w, 0, w")
- (unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
- (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w, w")
- (match_operand:SVE_I 3 "register_operand" "w, w, w"))]
- UNSPEC_MERGE_PTRUE)))]
+;; Predicated integer absolute difference, merging with the first input.
+(define_insn_and_rewrite "*aarch64_cond_<su>abd<mode>_2"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (minus:SVE_I
+ (unspec:SVE_I
+ [(match_operand 4)
+ (USMAX:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "0, w")
+ (match_operand:SVE_I 3 "register_operand" "w, w"))]
+ UNSPEC_PRED_X)
+ (unspec:SVE_I
+ [(match_operand 5)
+ (<max_opp>:SVE_I
+ (match_dup 2)
+ (match_dup 3))]
+ UNSPEC_PRED_X))
+ (match_dup 2)]
+ UNSPEC_SEL))]
"TARGET_SVE"
"@
- msb\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
- mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
- movprfx\t%0, %4\;mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
- [(set_attr "movprfx" "*,*,yes")]
+ <su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %2\;<su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ "&& (!CONSTANT_P (operands[4]) || !CONSTANT_P (operands[5]))"
+ {
+ operands[4] = operands[5] = CONSTM1_RTX (<VPRED>mode);
+ }
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Predicated integer absolute difference, merging with an independent value.
+(define_insn_and_rewrite "*aarch64_cond_<su>abd<mode>_any"
+ [(set (match_operand:SVE_I 0 "register_operand" "=&w, &w, &w, &w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
+ (minus:SVE_I
+ (unspec:SVE_I
+ [(match_operand 5)
+ (USMAX:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "0, w, w, w, w")
+ (match_operand:SVE_I 3 "register_operand" "w, 0, w, w, w"))]
+ UNSPEC_PRED_X)
+ (unspec:SVE_I
+ [(match_operand 6)
+ (<max_opp>:SVE_I
+ (match_dup 2)
+ (match_dup 3))]
+ UNSPEC_PRED_X))
+ (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, 0, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && !rtx_equal_p (operands[2], operands[4])
+ && !rtx_equal_p (operands[3], operands[4])"
+ "@
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ #"
+ "&& 1"
+ {
+ if (!CONSTANT_P (operands[5]) || !CONSTANT_P (operands[6]))
+ operands[5] = operands[6] = CONSTM1_RTX (<VPRED>mode);
+ else if (reload_completed
+ && register_operand (operands[4], <MODE>mode)
+ && !rtx_equal_p (operands[0], operands[4]))
+ {
+ emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
+ operands[4], operands[1]));
+ operands[4] = operands[2] = operands[0];
+ }
+ else
+ FAIL;
+ }
+ [(set_attr "movprfx" "yes")]
)
+;; -------------------------------------------------------------------------
+;; ---- [INT] Highpart multiplication
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - SMULH
+;; - UMULH
+;; -------------------------------------------------------------------------
+
;; Unpredicated highpart multiplication.
(define_expand "<su>mul<mode>3_highpart"
[(set (match_operand:SVE_I 0 "register_operand")
@@ -1017,7 +2198,7 @@
(unspec:SVE_I [(match_operand:SVE_I 1 "register_operand")
(match_operand:SVE_I 2 "register_operand")]
MUL_HIGHPART)]
- UNSPEC_MERGE_PTRUE))]
+ UNSPEC_PRED_X))]
"TARGET_SVE"
{
operands[3] = aarch64_ptrue_reg (<VPRED>mode);
@@ -1032,7 +2213,7 @@
(unspec:SVE_I [(match_operand:SVE_I 2 "register_operand" "%0, w")
(match_operand:SVE_I 3 "register_operand" "w, w")]
MUL_HIGHPART)]
- UNSPEC_MERGE_PTRUE))]
+ UNSPEC_PRED_X))]
"TARGET_SVE"
"@
<su>mulh\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
@@ -1040,7 +2221,17 @@
[(set_attr "movprfx" "*,yes")]
)
-;; Unpredicated division.
+;; -------------------------------------------------------------------------
+;; ---- [INT] Division
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - SDIV
+;; - SDIVR
+;; - UDIV
+;; - UDIVR
+;; -------------------------------------------------------------------------
+
+;; Unpredicated integer division.
(define_expand "<optab><mode>3"
[(set (match_operand:SVE_SDI 0 "register_operand")
(unspec:SVE_SDI
@@ -1048,22 +2239,22 @@
(SVE_INT_BINARY_SD:SVE_SDI
(match_operand:SVE_SDI 1 "register_operand")
(match_operand:SVE_SDI 2 "register_operand"))]
- UNSPEC_MERGE_PTRUE))]
+ UNSPEC_PRED_X))]
"TARGET_SVE"
{
operands[3] = aarch64_ptrue_reg (<VPRED>mode);
}
)
-;; Division predicated with a PTRUE.
+;; Integer division predicated with a PTRUE.
(define_insn "*<optab><mode>3"
[(set (match_operand:SVE_SDI 0 "register_operand" "=w, w, ?&w")
(unspec:SVE_SDI
[(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
(SVE_INT_BINARY_SD:SVE_SDI
(match_operand:SVE_SDI 2 "register_operand" "0, w, w")
- (match_operand:SVE_SDI 3 "aarch64_sve_mul_operand" "w, 0, w"))]
- UNSPEC_MERGE_PTRUE))]
+ (match_operand:SVE_SDI 3 "register_operand" "w, 0, w"))]
+ UNSPEC_PRED_X))]
"TARGET_SVE"
"@
<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
@@ -1072,44 +2263,931 @@
[(set_attr "movprfx" "*,*,yes")]
)
-;; Unpredicated NEG, NOT and POPCOUNT.
-(define_expand "<optab><mode>2"
+;; Predicated integer division with merging.
+(define_expand "cond_<optab><mode>"
+ [(set (match_operand:SVE_SDI 0 "register_operand")
+ (unspec:SVE_SDI
+ [(match_operand:<VPRED> 1 "register_operand")
+ (SVE_INT_BINARY_SD:SVE_SDI
+ (match_operand:SVE_SDI 2 "register_operand")
+ (match_operand:SVE_SDI 3 "register_operand"))
+ (match_operand:SVE_SDI 4 "aarch64_simd_reg_or_zero")]
+ UNSPEC_SEL))]
+ "TARGET_SVE"
+)
+
+;; Predicated integer division, merging with the first input.
+(define_insn "*cond_<optab><mode>_2"
+ [(set (match_operand:SVE_SDI 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_SDI
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (SVE_INT_BINARY_SD:SVE_SDI
+ (match_operand:SVE_SDI 2 "register_operand" "0, w")
+ (match_operand:SVE_SDI 3 "register_operand" "w, w"))
+ (match_dup 2)]
+ UNSPEC_SEL))]
+ "TARGET_SVE"
+ "@
+ <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Predicated integer division, merging with the second input.
+(define_insn "*cond_<optab><mode>_3"
+ [(set (match_operand:SVE_SDI 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_SDI
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (SVE_INT_BINARY_SD:SVE_SDI
+ (match_operand:SVE_SDI 2 "register_operand" "w, w")
+ (match_operand:SVE_SDI 3 "register_operand" "0, w"))
+ (match_dup 3)]
+ UNSPEC_SEL))]
+ "TARGET_SVE"
+ "@
+ <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+ movprfx\t%0, %3\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Predicated integer division, merging with an independent value.
+(define_insn_and_rewrite "*cond_<optab><mode>_any"
+ [(set (match_operand:SVE_SDI 0 "register_operand" "=&w, &w, &w, &w, ?&w")
+ (unspec:SVE_SDI
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
+ (SVE_INT_BINARY_SD:SVE_SDI
+ (match_operand:SVE_SDI 2 "register_operand" "0, w, w, w, w")
+ (match_operand:SVE_SDI 3 "register_operand" "w, 0, w, w, w"))
+ (match_operand:SVE_SDI 4 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, 0, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && !rtx_equal_p (operands[2], operands[4])
+ && !rtx_equal_p (operands[3], operands[4])"
+ "@
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ #"
+ "&& reload_completed
+ && register_operand (operands[4], <MODE>mode)
+ && !rtx_equal_p (operands[0], operands[4])"
+ {
+ emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
+ operands[4], operands[1]));
+ operands[4] = operands[2] = operands[0];
+ }
+ [(set_attr "movprfx" "yes")]
+)
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] Binary logical operations
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - AND
+;; - EOR
+;; - ORR
+;; -------------------------------------------------------------------------
+
+;; Unpredicated integer binary logical operations.
+(define_insn "<optab><mode>3"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?w, w")
+ (LOGICAL:SVE_I
+ (match_operand:SVE_I 1 "register_operand" "%0, w, w")
+ (match_operand:SVE_I 2 "aarch64_sve_logical_operand" "vsl, vsl, w")))]
+ "TARGET_SVE"
+ "@
+ <logical>\t%0.<Vetype>, %0.<Vetype>, #%C2
+ movprfx\t%0, %1\;<logical>\t%0.<Vetype>, %0.<Vetype>, #%C2
+ <logical>\t%0.d, %1.d, %2.d"
+ [(set_attr "movprfx" "*,yes,*")]
+)
+
+;; Merging forms are handled through SVE_INT_BINARY.
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] Binary logical operations (inverted second input)
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - BIC
+;; -------------------------------------------------------------------------
+
+(define_insn_and_rewrite "*bic<mode>3"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w")
+ (and:SVE_I
+ (unspec:SVE_I
+ [(match_operand 3)
+ (not:SVE_I (match_operand:SVE_I 2 "register_operand" "w"))]
+ UNSPEC_PRED_X)
+ (match_operand:SVE_I 1 "register_operand" "w")))]
+ "TARGET_SVE"
+ "bic\t%0.d, %1.d, %2.d"
+ "&& !CONSTANT_P (operands[3])"
+ {
+ operands[3] = CONSTM1_RTX (<VPRED>mode);
+ }
+)
+
+;; Predicated integer BIC, merging with the first input.
+(define_insn "*cond_bic<mode>_2"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (and:SVE_I
+ (not:SVE_I (match_operand:SVE_I 3 "register_operand" "w, w"))
+ (match_operand:SVE_I 2 "register_operand" "0, w"))
+ (match_dup 2)]
+ UNSPEC_SEL))]
+ "TARGET_SVE"
+ "@
+ bic\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %2\;bic\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Predicated integer BIC, merging with an independent value.
+(define_insn_and_rewrite "*cond_bic<mode>_any"
+ [(set (match_operand:SVE_I 0 "register_operand" "=&w, &w, &w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
+ (and:SVE_I
+ (not:SVE_I (match_operand:SVE_I 3 "register_operand" "w, w, w, w"))
+ (match_operand:SVE_I 2 "register_operand" "0, w, w, w"))
+ (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero" "Dz, Dz, 0, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
+ "@
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;bic\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;bic\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;bic\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ #"
+ "&& reload_completed
+ && register_operand (operands[4], <MODE>mode)
+ && !rtx_equal_p (operands[0], operands[4])"
+ {
+ emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
+ operands[4], operands[1]));
+ operands[4] = operands[2] = operands[0];
+ }
+ [(set_attr "movprfx" "yes")]
+)
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] Shifts
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - ASR
+;; - LSL
+;; - LSR
+;; -------------------------------------------------------------------------
+
+;; Unpredicated shift by a scalar, which expands into one of the vector
+;; shifts below.
+(define_expand "<ASHIFT:optab><mode>3"
+ [(set (match_operand:SVE_I 0 "register_operand")
+ (ASHIFT:SVE_I (match_operand:SVE_I 1 "register_operand")
+ (match_operand:<VEL> 2 "general_operand")))]
+ "TARGET_SVE"
+ {
+ rtx amount;
+ if (CONST_INT_P (operands[2]))
+ {
+ amount = gen_const_vec_duplicate (<MODE>mode, operands[2]);
+ if (!aarch64_sve_<lr>shift_operand (operands[2], <MODE>mode))
+ amount = force_reg (<MODE>mode, amount);
+ }
+ else
+ {
+ amount = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_vec_duplicate<mode> (amount,
+ convert_to_mode (<VEL>mode,
+ operands[2], 0)));
+ }
+ emit_insn (gen_v<optab><mode>3 (operands[0], operands[1], amount));
+ DONE;
+ }
+)
+
+;; Unpredicated shift by a vector.
+(define_expand "v<optab><mode>3"
[(set (match_operand:SVE_I 0 "register_operand")
(unspec:SVE_I
- [(match_dup 2)
- (SVE_INT_UNARY:SVE_I (match_operand:SVE_I 1 "register_operand"))]
- UNSPEC_MERGE_PTRUE))]
+ [(match_dup 3)
+ (ASHIFT:SVE_I
+ (match_operand:SVE_I 1 "register_operand")
+ (match_operand:SVE_I 2 "aarch64_sve_<lr>shift_operand"))]
+ UNSPEC_PRED_X))]
"TARGET_SVE"
{
- operands[2] = aarch64_ptrue_reg (<VPRED>mode);
+ operands[3] = aarch64_ptrue_reg (<VPRED>mode);
}
)
-;; NEG, NOT and POPCOUNT predicated with a PTRUE.
-(define_insn "*<optab><mode>2"
+;; Shift by a vector, predicated with a PTRUE. We don't actually need
+;; the predicate for the first alternative, but using Upa or X isn't
+;; likely to gain much and would make the instruction seem less uniform
+;; to the register allocator.
+(define_insn_and_split "*v<optab><mode>3"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, w, w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
+ (ASHIFT:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "w, 0, w, w")
+ (match_operand:SVE_I 3 "aarch64_sve_<lr>shift_operand" "D<lr>, w, 0, w"))]
+ UNSPEC_PRED_X))]
+ "TARGET_SVE"
+ "@
+ #
+ <shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ <shift>r\t%0.<Vetype>, %1/m, %3.<Vetype>, %2.<Vetype>
+ movprfx\t%0, %2\;<shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ "&& reload_completed
+ && !register_operand (operands[3], <MODE>mode)"
+ [(set (match_dup 0) (ASHIFT:SVE_I (match_dup 2) (match_dup 3)))]
+ ""
+ [(set_attr "movprfx" "*,*,*,yes")]
+)
+
+;; Unpredicated shift operations by a constant (post-RA only).
+;; These are generated by splitting a predicated instruction whose
+;; predicate is unused.
+(define_insn "*post_ra_v<optab><mode>3"
[(set (match_operand:SVE_I 0 "register_operand" "=w")
+ (ASHIFT:SVE_I
+ (match_operand:SVE_I 1 "register_operand" "w")
+ (match_operand:SVE_I 2 "aarch64_simd_<lr>shift_imm")))]
+ "TARGET_SVE && reload_completed"
+ "<shift>\t%0.<Vetype>, %1.<Vetype>, #%2"
+)
+
+;; Predicated integer shift, merging with the first input.
+(define_insn "*cond_<optab><mode>_2_const"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
(unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (SVE_INT_UNARY:SVE_I
- (match_operand:SVE_I 2 "register_operand" "w"))]
- UNSPEC_MERGE_PTRUE))]
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (ASHIFT:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "0, w")
+ (match_operand:SVE_I 3 "aarch64_simd_<lr>shift_imm"))
+ (match_dup 2)]
+ UNSPEC_SEL))]
"TARGET_SVE"
- "<sve_int_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
+ "@
+ <shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
+ movprfx\t%0, %2\;<shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3"
+ [(set_attr "movprfx" "*,yes")]
)
-;; Vector AND, ORR and XOR.
-(define_insn "<optab><mode>3"
- [(set (match_operand:SVE_I 0 "register_operand" "=w, w")
- (LOGICAL:SVE_I
- (match_operand:SVE_I 1 "register_operand" "%0, w")
- (match_operand:SVE_I 2 "aarch64_sve_logical_operand" "vsl, w")))]
+;; Predicated integer shift, merging with an independent value.
+(define_insn_and_rewrite "*cond_<optab><mode>_any_const"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, &w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (ASHIFT:SVE_I
+ (match_operand:SVE_I 2 "register_operand" "w, w, w")
+ (match_operand:SVE_I 3 "aarch64_simd_<lr>shift_imm"))
+ (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero" "Dz, 0, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE && !rtx_equal_p (operands[2], operands[4])"
+ "@
+ movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
+ movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
+ #"
+ "&& reload_completed
+ && register_operand (operands[4], <MODE>mode)
+ && !rtx_equal_p (operands[0], operands[4])"
+ {
+ emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
+ operands[4], operands[1]));
+ operands[4] = operands[2] = operands[0];
+ }
+ [(set_attr "movprfx" "yes")]
+)
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] General binary arithmetic corresponding to rtx codes
+;; -------------------------------------------------------------------------
+;; Includes post-RA forms of:
+;; - FADD
+;; - FMUL
+;; - FSUB
+;; -------------------------------------------------------------------------
+
+;; Unpredicated floating-point binary operations (post-RA only).
+;; These are generated by splitting a predicated instruction whose
+;; predicate is unused.
+(define_insn "*post_ra_<sve_fp_op><mode>3"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w")
+ (SVE_UNPRED_FP_BINARY:SVE_F
+ (match_operand:SVE_F 1 "register_operand" "w")
+ (match_operand:SVE_F 2 "register_operand" "w")))]
+ "TARGET_SVE && reload_completed"
+ "<sve_fp_op>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>")
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] General binary arithmetic corresponding to unspecs
+;; -------------------------------------------------------------------------
+;; Includes merging forms of:
+;; - FADD (constant forms handled in the "Addition" section)
+;; - FDIV
+;; - FDIVR
+;; - FMAXNM (including #0.0 and #1.0)
+;; - FMINNM (including #0.0 and #1.0)
+;; - FMUL (including #0.5 and #2.0)
+;; - FSUB (constant forms handled in the "Addition" section)
+;; - FSUBR (constant forms handled in the "Subtraction" section)
+;; -------------------------------------------------------------------------
+
+;; Unpredicated floating-point binary operations.
+(define_expand "<optab><mode>3"
+ [(set (match_operand:SVE_F 0 "register_operand")
+ (unspec:SVE_F
+ [(match_dup 3)
+ (const_int SVE_RELAXED_GP)
+ (match_operand:SVE_F 1 "<sve_pred_fp_rhs1_operand>")
+ (match_operand:SVE_F 2 "<sve_pred_fp_rhs2_operand>")]
+ SVE_COND_FP_BINARY))]
+ "TARGET_SVE"
+ {
+ operands[3] = aarch64_ptrue_reg (<VPRED>mode);
+ }
+)
+
+;; Predicated floating-point binary operations that have no immediate forms.
+(define_insn "*<optab><mode>3"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (match_operand:SI 4 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "0, w, w")
+ (match_operand:SVE_F 3 "register_operand" "w, 0, w")]
+ SVE_COND_FP_BINARY_REG))]
"TARGET_SVE"
"@
- <logical>\t%0.<Vetype>, %0.<Vetype>, #%C2
- <logical>\t%0.d, %1.d, %2.d"
+ <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ <sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+ movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,*,yes")]
)
-;; Vector AND, ORR and XOR on floating-point modes. We avoid subregs
+;; Predicated floating-point operations with merging.
+(define_expand "cond_<optab><mode>"
+ [(set (match_operand:SVE_F 0 "register_operand")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand")
+ (unspec:SVE_F
+ [(match_dup 1)
+ (const_int SVE_STRICT_GP)
+ (match_operand:SVE_F 2 "<sve_pred_fp_rhs1_operand>")
+ (match_operand:SVE_F 3 "<sve_pred_fp_rhs2_operand>")]
+ SVE_COND_FP_BINARY)
+ (match_operand:SVE_F 4 "aarch64_simd_reg_or_zero")]
+ UNSPEC_SEL))]
+ "TARGET_SVE"
+)
+
+;; Predicated floating-point operations, merging with the first input.
+(define_insn_and_rewrite "*cond_<optab><mode>_2"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 4)
+ (match_operand:SI 5 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "0, w")
+ (match_operand:SVE_F 3 "register_operand" "w, w")]
+ SVE_COND_FP_BINARY)
+ (match_dup 2)]
+ UNSPEC_SEL))]
+ "TARGET_SVE && aarch64_sve_pred_dominates_p (&operands[4], operands[1])"
+ "@
+ <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ "&& !rtx_equal_p (operands[1], operands[4])"
+ {
+ operands[4] = copy_rtx (operands[1]);
+ }
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Same for operations that take a 1-bit constant.
+(define_insn_and_rewrite "*cond_<optab><mode>_2_const"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, ?w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 4)
+ (match_operand:SI 5 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "0, w")
+ (match_operand:SVE_F 3 "<sve_pred_fp_rhs2_immediate>")]
+ SVE_COND_FP_BINARY_I1)
+ (match_dup 2)]
+ UNSPEC_SEL))]
+ "TARGET_SVE && aarch64_sve_pred_dominates_p (&operands[4], operands[1])"
+ "@
+ <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
+ movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3"
+ "&& !rtx_equal_p (operands[1], operands[4])"
+ {
+ operands[4] = copy_rtx (operands[1]);
+ }
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Predicated floating-point operations, merging with the second input.
+(define_insn_and_rewrite "*cond_<optab><mode>_3"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 4)
+ (match_operand:SI 5 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "w, w")
+ (match_operand:SVE_F 3 "register_operand" "0, w")]
+ SVE_COND_FP_BINARY)
+ (match_dup 3)]
+ UNSPEC_SEL))]
+ "TARGET_SVE && aarch64_sve_pred_dominates_p (&operands[4], operands[1])"
+ "@
+ <sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+ movprfx\t%0, %3\;<sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
+ "&& !rtx_equal_p (operands[1], operands[4])"
+ {
+ operands[4] = copy_rtx (operands[1]);
+ }
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Predicated floating-point operations, merging with an independent value.
+(define_insn_and_rewrite "*cond_<optab><mode>_any"
+ [(set (match_operand:SVE_F 0 "register_operand" "=&w, &w, &w, &w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 5)
+ (match_operand:SI 6 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "0, w, w, w, w")
+ (match_operand:SVE_F 3 "register_operand" "w, 0, w, w, w")]
+ SVE_COND_FP_BINARY)
+ (match_operand:SVE_F 4 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, 0, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && !rtx_equal_p (operands[2], operands[4])
+ && !rtx_equal_p (operands[3], operands[4])
+ && aarch64_sve_pred_dominates_p (&operands[5], operands[1])"
+ "@
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ #"
+ "&& 1"
+ {
+ if (reload_completed
+ && register_operand (operands[4], <MODE>mode)
+ && !rtx_equal_p (operands[0], operands[4]))
+ {
+ emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
+ operands[4], operands[1]));
+ operands[4] = operands[2] = operands[0];
+ }
+ else if (!rtx_equal_p (operands[1], operands[5]))
+ operands[5] = copy_rtx (operands[1]);
+ else
+ FAIL;
+ }
+ [(set_attr "movprfx" "yes")]
+)
+
+;; Same for operations that take a 1-bit constant.
+(define_insn_and_rewrite "*cond_<optab><mode>_any_const"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 5)
+ (match_operand:SI 6 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "w, w, w")
+ (match_operand:SVE_F 3 "<sve_pred_fp_rhs2_immediate>")]
+ SVE_COND_FP_BINARY_I1)
+ (match_operand:SVE_F 4 "aarch64_simd_reg_or_zero" "Dz, 0, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && !rtx_equal_p (operands[2], operands[4])
+ && aarch64_sve_pred_dominates_p (&operands[5], operands[1])"
+ "@
+ movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
+ movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
+ #"
+ "&& 1"
+ {
+ if (reload_completed
+ && register_operand (operands[4], <MODE>mode)
+ && !rtx_equal_p (operands[0], operands[4]))
+ {
+ emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
+ operands[4], operands[1]));
+ operands[4] = operands[2] = operands[0];
+ }
+ else if (!rtx_equal_p (operands[1], operands[5]))
+ operands[5] = copy_rtx (operands[1]);
+ else
+ FAIL;
+ }
+ [(set_attr "movprfx" "yes")]
+)
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] Addition
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - FADD
+;; - FSUB
+;; -------------------------------------------------------------------------
+
+;; Predicated floating-point addition.
+(define_insn_and_split "*add<mode>3"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, w, w, ?&w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
+ (match_operand:SI 4 "aarch64_sve_gp_strictness" "i, i, Z, i, i")
+ (match_operand:SVE_F 2 "register_operand" "%0, 0, w, w, w")
+ (match_operand:SVE_F 3 "aarch64_sve_float_arith_with_sub_operand" "vsA, vsN, w, vsA, vsN")]
+ UNSPEC_COND_FADD))]
+ "TARGET_SVE"
+ "@
+ fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
+ fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
+ #
+ movprfx\t%0, %2\;fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
+ movprfx\t%0, %2\;fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3"
+ ; Split the unpredicated form after reload, so that we don't have
+ ; the unnecessary PTRUE.
+ "&& reload_completed
+ && register_operand (operands[3], <MODE>mode)"
+ [(set (match_dup 0) (plus:SVE_F (match_dup 2) (match_dup 3)))]
+ ""
+ [(set_attr "movprfx" "*,*,*,yes,yes")]
+)
+
+;; Predicated floating-point addition of a constant, merging with the
+;; first input.
+(define_insn_and_rewrite "*cond_add<mode>_2_const"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?w, ?w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 4)
+ (match_operand:SI 5 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "0, 0, w, w")
+ (match_operand:SVE_F 3 "aarch64_sve_float_arith_with_sub_immediate" "vsA, vsN, vsA, vsN")]
+ UNSPEC_COND_FADD)
+ (match_dup 2)]
+ UNSPEC_SEL))]
+ "TARGET_SVE && aarch64_sve_pred_dominates_p (&operands[4], operands[1])"
+ "@
+ fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
+ fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
+ movprfx\t%0, %2\;fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
+ movprfx\t%0, %2\;fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3"
+ "&& !rtx_equal_p (operands[1], operands[4])"
+ {
+ operands[4] = copy_rtx (operands[1]);
+ }
+ [(set_attr "movprfx" "*,*,yes,yes")]
+)
+
+;; Predicated floating-point addition of a constant, merging with an
+;; independent value.
+(define_insn_and_rewrite "*cond_add<mode>_any_const"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, w, w, w, ?w, ?w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 5)
+ (match_operand:SI 6 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "w, w, w, w, w, w")
+ (match_operand:SVE_F 3 "aarch64_sve_float_arith_with_sub_immediate" "vsA, vsN, vsA, vsN, vsA, vsN")]
+ UNSPEC_COND_FADD)
+ (match_operand:SVE_F 4 "aarch64_simd_reg_or_zero" "Dz, Dz, 0, 0, w, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && !rtx_equal_p (operands[2], operands[4])
+ && aarch64_sve_pred_dominates_p (&operands[5], operands[1])"
+ "@
+ movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
+ movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
+ movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
+ movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
+ #
+ #"
+ "&& 1"
+ {
+ if (reload_completed
+ && register_operand (operands[4], <MODE>mode)
+ && !rtx_equal_p (operands[0], operands[4]))
+ {
+ emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
+ operands[4], operands[1]));
+ operands[4] = operands[2] = operands[0];
+ }
+ else if (!rtx_equal_p (operands[1], operands[5]))
+ operands[5] = copy_rtx (operands[1]);
+ else
+ FAIL;
+ }
+ [(set_attr "movprfx" "yes")]
+)
+
+;; Register merging forms are handled through SVE_COND_FP_BINARY.
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] Subtraction
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - FSUB
+;; - FSUBR
+;; -------------------------------------------------------------------------
+
+;; Predicated floating-point subtraction.
+(define_insn_and_split "*sub<mode>3"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (match_operand:SI 4 "aarch64_sve_gp_strictness" "i, Z, i")
+ (match_operand:SVE_F 2 "aarch64_sve_float_arith_operand" "vsA, w, vsA")
+ (match_operand:SVE_F 3 "register_operand" "0, w, 0")]
+ UNSPEC_COND_FSUB))]
+ "TARGET_SVE"
+ "@
+ fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2
+ #
+ movprfx\t%0, %3\;fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2"
+ ; Split the unpredicated form after reload, so that we don't have
+ ; the unnecessary PTRUE.
+ "&& reload_completed
+ && register_operand (operands[2], <MODE>mode)"
+ [(set (match_dup 0) (minus:SVE_F (match_dup 2) (match_dup 3)))]
+ ""
+ [(set_attr "movprfx" "*,*,yes")]
+)
+
+;; Predicated floating-point subtraction from a constant, merging with the
+;; second input.
+(define_insn_and_rewrite "*cond_sub<mode>_3_const"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, ?w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 4)
+ (match_operand:SI 5 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "aarch64_sve_float_arith_immediate")
+ (match_operand:SVE_F 3 "register_operand" "0, w")]
+ UNSPEC_COND_FSUB)
+ (match_dup 3)]
+ UNSPEC_SEL))]
+ "TARGET_SVE && aarch64_sve_pred_dominates_p (&operands[4], operands[1])"
+ "@
+ fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2
+ movprfx\t%0, %3\;fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2"
+ "&& !rtx_equal_p (operands[1], operands[4])"
+ {
+ operands[4] = copy_rtx (operands[1]);
+ }
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Predicated floating-point subtraction from a constant, merging with an
+;; independent value.
+(define_insn_and_rewrite "*cond_sub<mode>_any_const"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 5)
+ (match_operand:SI 6 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "aarch64_sve_float_arith_immediate")
+ (match_operand:SVE_F 3 "register_operand" "w, w, w")]
+ UNSPEC_COND_FSUB)
+ (match_operand:SVE_F 4 "aarch64_simd_reg_or_zero" "Dz, 0, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && !rtx_equal_p (operands[3], operands[4])
+ && aarch64_sve_pred_dominates_p (&operands[5], operands[1])"
+ "@
+ movprfx\t%0.<Vetype>, %1/z, %3.<Vetype>\;fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2
+ movprfx\t%0.<Vetype>, %1/m, %3.<Vetype>\;fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2
+ #"
+ "&& 1"
+ {
+ if (reload_completed
+ && register_operand (operands[4], <MODE>mode)
+ && !rtx_equal_p (operands[0], operands[4]))
+ {
+ emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[3],
+ operands[4], operands[1]));
+ operands[4] = operands[3] = operands[0];
+ }
+ else if (!rtx_equal_p (operands[1], operands[5]))
+ operands[5] = copy_rtx (operands[1]);
+ else
+ FAIL;
+ }
+ [(set_attr "movprfx" "yes")]
+)
+
+;; Register merging forms are handled through SVE_COND_FP_BINARY.
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] Absolute difference
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - FABD
+;; -------------------------------------------------------------------------
+
+;; Predicated floating-point absolute difference.
+(define_insn_and_rewrite "*fabd<mode>3"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (match_operand:SI 4 "aarch64_sve_gp_strictness")
+ (unspec:SVE_F
+ [(match_operand 5)
+ (match_operand:SI 6 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "%0, w")
+ (match_operand:SVE_F 3 "register_operand" "w, w")]
+ UNSPEC_COND_FSUB)]
+ UNSPEC_COND_FABS))]
+ "TARGET_SVE && aarch64_sve_pred_dominates_p (&operands[5], operands[1])"
+ "@
+ fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %2\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ "&& !rtx_equal_p (operands[1], operands[5])"
+ {
+ operands[5] = copy_rtx (operands[1]);
+ }
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Predicated floating-point absolute difference, merging with the first
+;; input.
+(define_insn_and_rewrite "*aarch64_cond_abd<mode>_2"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 4)
+ (match_operand:SI 5 "aarch64_sve_gp_strictness")
+ (unspec:SVE_F
+ [(match_operand 6)
+ (match_operand:SI 7 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "0, w")
+ (match_operand:SVE_F 3 "register_operand" "w, w")]
+ UNSPEC_COND_FSUB)]
+ UNSPEC_COND_FABS)
+ (match_dup 2)]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && aarch64_sve_pred_dominates_p (&operands[4], operands[1])
+ && aarch64_sve_pred_dominates_p (&operands[6], operands[1])"
+ "@
+ fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %2\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ "&& (!rtx_equal_p (operands[1], operands[4])
+ || !rtx_equal_p (operands[1], operands[6]))"
+ {
+ operands[4] = copy_rtx (operands[1]);
+ operands[6] = copy_rtx (operands[1]);
+ }
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Predicated floating-point absolute difference, merging with the second
+;; input.
+(define_insn_and_rewrite "*aarch64_cond_abd<mode>_3"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 4)
+ (match_operand:SI 5 "aarch64_sve_gp_strictness")
+ (unspec:SVE_F
+ [(match_operand 6)
+ (match_operand:SI 7 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "w, w")
+ (match_operand:SVE_F 3 "register_operand" "0, w")]
+ UNSPEC_COND_FSUB)]
+ UNSPEC_COND_FABS)
+ (match_dup 3)]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && aarch64_sve_pred_dominates_p (&operands[4], operands[1])
+ && aarch64_sve_pred_dominates_p (&operands[6], operands[1])"
+ "@
+ fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+ movprfx\t%0, %3\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
+ "&& (!rtx_equal_p (operands[1], operands[4])
+ || !rtx_equal_p (operands[1], operands[6]))"
+ {
+ operands[4] = copy_rtx (operands[1]);
+ operands[6] = copy_rtx (operands[1]);
+ }
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Predicated floating-point absolute difference, merging with an
+;; independent value.
+(define_insn_and_rewrite "*aarch64_cond_abd<mode>_any"
+ [(set (match_operand:SVE_F 0 "register_operand" "=&w, &w, &w, &w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 5)
+ (match_operand:SI 6 "aarch64_sve_gp_strictness")
+ (unspec:SVE_F
+ [(match_operand 7)
+ (match_operand:SI 8 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "0, w, w, w, w")
+ (match_operand:SVE_F 3 "register_operand" "w, 0, w, w, w")]
+ UNSPEC_COND_FSUB)]
+ UNSPEC_COND_FABS)
+ (match_operand:SVE_F 4 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, 0, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && !rtx_equal_p (operands[2], operands[4])
+ && !rtx_equal_p (operands[3], operands[4])
+ && aarch64_sve_pred_dominates_p (&operands[5], operands[1])
+ && aarch64_sve_pred_dominates_p (&operands[7], operands[1])"
+ "@
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;fabd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ #"
+ "&& 1"
+ {
+ if (reload_completed
+ && register_operand (operands[4], <MODE>mode)
+ && !rtx_equal_p (operands[0], operands[4]))
+ {
+ emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[3],
+ operands[4], operands[1]));
+ operands[4] = operands[3] = operands[0];
+ }
+ else if (!rtx_equal_p (operands[1], operands[5])
+ || !rtx_equal_p (operands[1], operands[7]))
+ {
+ operands[5] = copy_rtx (operands[1]);
+ operands[7] = copy_rtx (operands[1]);
+ }
+ else
+ FAIL;
+ }
+ [(set_attr "movprfx" "yes")]
+)
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] Multiplication
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - FMUL
+;; -------------------------------------------------------------------------
+
+;; Predicated floating-point multiplication.
+(define_insn_and_split "*mul<mode>3"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (match_operand:SI 4 "aarch64_sve_gp_strictness" "i, Z, i")
+ (match_operand:SVE_F 2 "register_operand" "%0, w, 0")
+ (match_operand:SVE_F 3 "aarch64_sve_float_mul_operand" "vsM, w, vsM")]
+ UNSPEC_COND_FMUL))]
+ "TARGET_SVE"
+ "@
+ fmul\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
+ #
+ movprfx\t%0, %2\;fmul\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3"
+ ; Split the unpredicated form after reload, so that we don't have
+ ; the unnecessary PTRUE.
+ "&& reload_completed
+ && register_operand (operands[3], <MODE>mode)"
+ [(set (match_dup 0) (mult:SVE_F (match_dup 2) (match_dup 3)))]
+ ""
+ [(set_attr "movprfx" "*,*,yes")]
+)
+
+;; Merging forms are handled through SVE_COND_FP_BINARY and
+;; SVE_COND_FP_BINARY_I1.
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] Binary logical operations
+;; -------------------------------------------------------------------------
+;; Includes
+;; - AND
+;; - EOR
+;; - ORR
+;; -------------------------------------------------------------------------
+
+;; Binary logical operations on floating-point modes. We avoid subregs
;; by providing this, but we need to use UNSPECs since rtx logical ops
;; aren't defined for floating-point modes.
(define_insn "*<optab><mode>3"
@@ -1121,27 +3199,135 @@
"<logicalf_op>\t%0.d, %1.d, %2.d"
)
-;; REG_EQUAL notes on "not<mode>3" should ensure that we can generate
-;; this pattern even though the NOT instruction itself is predicated.
-(define_insn "bic<mode>3"
- [(set (match_operand:SVE_I 0 "register_operand" "=w")
- (and:SVE_I
- (not:SVE_I (match_operand:SVE_I 1 "register_operand" "w"))
- (match_operand:SVE_I 2 "register_operand" "w")))]
+;; -------------------------------------------------------------------------
+;; ---- [FP] Sign copying
+;; -------------------------------------------------------------------------
+;; The patterns in this section are synthetic.
+;; -------------------------------------------------------------------------
+
+(define_expand "copysign<mode>3"
+ [(match_operand:SVE_F 0 "register_operand")
+ (match_operand:SVE_F 1 "register_operand")
+ (match_operand:SVE_F 2 "register_operand")]
+ "TARGET_SVE"
+ {
+ rtx sign = gen_reg_rtx (<V_INT_EQUIV>mode);
+ rtx mant = gen_reg_rtx (<V_INT_EQUIV>mode);
+ rtx int_res = gen_reg_rtx (<V_INT_EQUIV>mode);
+ int bits = GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1;
+
+ rtx arg1 = lowpart_subreg (<V_INT_EQUIV>mode, operands[1], <MODE>mode);
+ rtx arg2 = lowpart_subreg (<V_INT_EQUIV>mode, operands[2], <MODE>mode);
+
+ emit_insn (gen_and<v_int_equiv>3
+ (sign, arg2,
+ aarch64_simd_gen_const_vector_dup (<V_INT_EQUIV>mode,
+ HOST_WIDE_INT_M1U
+ << bits)));
+ emit_insn (gen_and<v_int_equiv>3
+ (mant, arg1,
+ aarch64_simd_gen_const_vector_dup (<V_INT_EQUIV>mode,
+ ~(HOST_WIDE_INT_M1U
+ << bits))));
+ emit_insn (gen_ior<v_int_equiv>3 (int_res, sign, mant));
+ emit_move_insn (operands[0], gen_lowpart (<MODE>mode, int_res));
+ DONE;
+ }
+)
+
+(define_expand "xorsign<mode>3"
+ [(match_operand:SVE_F 0 "register_operand")
+ (match_operand:SVE_F 1 "register_operand")
+ (match_operand:SVE_F 2 "register_operand")]
+ "TARGET_SVE"
+ {
+ rtx sign = gen_reg_rtx (<V_INT_EQUIV>mode);
+ rtx int_res = gen_reg_rtx (<V_INT_EQUIV>mode);
+ int bits = GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1;
+
+ rtx arg1 = lowpart_subreg (<V_INT_EQUIV>mode, operands[1], <MODE>mode);
+ rtx arg2 = lowpart_subreg (<V_INT_EQUIV>mode, operands[2], <MODE>mode);
+
+ emit_insn (gen_and<v_int_equiv>3
+ (sign, arg2,
+ aarch64_simd_gen_const_vector_dup (<V_INT_EQUIV>mode,
+ HOST_WIDE_INT_M1U
+ << bits)));
+ emit_insn (gen_xor<v_int_equiv>3 (int_res, arg1, sign));
+ emit_move_insn (operands[0], gen_lowpart (<MODE>mode, int_res));
+ DONE;
+ }
+)
+
+;; -------------------------------------------------------------------------
+;; ---- [FP] Maximum and minimum
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - FMAXNM
+;; - FMINNM
+;; -------------------------------------------------------------------------
+
+;; Unpredicated fmax/fmin (the libm functions). The optabs for the
+;; smin/smax rtx codes are handled in the generic section above.
+(define_expand "<maxmin_uns><mode>3"
+ [(set (match_operand:SVE_F 0 "register_operand")
+ (unspec:SVE_F
+ [(match_dup 3)
+ (const_int SVE_RELAXED_GP)
+ (match_operand:SVE_F 1 "register_operand")
+ (match_operand:SVE_F 2 "aarch64_sve_float_maxmin_operand")]
+ SVE_COND_FP_MAXMIN_PUBLIC))]
+ "TARGET_SVE"
+ {
+ operands[3] = aarch64_ptrue_reg (<VPRED>mode);
+ }
+)
+
+;; Predicated floating-point maximum/minimum.
+(define_insn "*<optab><mode>3"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
+ (match_operand:SI 4 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "%0, 0, w, w")
+ (match_operand:SVE_F 3 "aarch64_sve_float_maxmin_operand" "vsB, w, vsB, w")]
+ SVE_COND_FP_MAXMIN_PUBLIC))]
"TARGET_SVE"
- "bic\t%0.d, %2.d, %1.d"
+ "@
+ <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
+ <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
+ movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,*,yes,yes")]
)
+;; Merging forms are handled through SVE_COND_FP_BINARY and
+;; SVE_COND_FP_BINARY_I1.
+
+;; -------------------------------------------------------------------------
+;; ---- [PRED] Binary logical operations
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - AND
+;; - ANDS
+;; - EOR
+;; - EORS
+;; - ORR
+;; - ORRS
+;; -------------------------------------------------------------------------
+
;; Predicate AND. We can reuse one of the inputs as the GP.
+;; Doubling the second operand is the preferred implementation
+;; of the MOV alias, so we use that instead of %1/z, %1, %2.
(define_insn "and<mode>3"
[(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
(and:PRED_ALL (match_operand:PRED_ALL 1 "register_operand" "Upa")
(match_operand:PRED_ALL 2 "register_operand" "Upa")))]
"TARGET_SVE"
- "and\t%0.b, %1/z, %1.b, %2.b"
+ "and\t%0.b, %1/z, %2.b, %2.b"
)
-;; Unpredicated predicate ORR and XOR.
+;; Unpredicated predicate EOR and ORR.
(define_expand "<optab><mode>3"
[(set (match_operand:PRED_ALL 0 "register_operand")
(and:PRED_ALL
@@ -1155,8 +3341,8 @@
}
)
-;; Predicated predicate ORR and XOR.
-(define_insn "pred_<optab><mode>3"
+;; Predicated predicate AND, EOR and ORR.
+(define_insn "@aarch64_pred_<optab><mode>_z"
[(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
(and:PRED_ALL
(LOGICAL:PRED_ALL
@@ -1168,61 +3354,55 @@
)
;; Perform a logical operation on operands 2 and 3, using operand 1 as
-;; the GP (which is known to be a PTRUE). Store the result in operand 0
-;; and set the flags in the same way as for PTEST. The (and ...) in the
-;; UNSPEC_PTEST_PTRUE is logically redundant, but means that the tested
-;; value is structurally equivalent to rhs of the second set.
+;; the GP. Store the result in operand 0 and set the flags in the same
+;; way as for PTEST.
(define_insn "*<optab><mode>3_cc"
[(set (reg:CC_NZC CC_REGNUM)
(unspec:CC_NZC
- [(match_operand:PRED_ALL 1 "register_operand" "Upa")
+ [(match_operand:VNx16BI 1 "register_operand" "Upa")
+ (match_operand 4)
+ (match_operand:SI 5 "aarch64_sve_ptrue_flag")
(and:PRED_ALL
(LOGICAL:PRED_ALL
(match_operand:PRED_ALL 2 "register_operand" "Upa")
(match_operand:PRED_ALL 3 "register_operand" "Upa"))
- (match_dup 1))]
- UNSPEC_PTEST_PTRUE))
+ (match_dup 4))]
+ UNSPEC_PTEST))
(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
(and:PRED_ALL (LOGICAL:PRED_ALL (match_dup 2) (match_dup 3))
- (match_dup 1)))]
+ (match_dup 4)))]
"TARGET_SVE"
"<logical>s\t%0.b, %1/z, %2.b, %3.b"
)
-;; Unpredicated predicate inverse.
-(define_expand "one_cmpl<mode>2"
- [(set (match_operand:PRED_ALL 0 "register_operand")
- (and:PRED_ALL
- (not:PRED_ALL (match_operand:PRED_ALL 1 "register_operand"))
- (match_dup 2)))]
- "TARGET_SVE"
- {
- operands[2] = aarch64_ptrue_reg (<MODE>mode);
- }
-)
-
-;; Predicated predicate inverse.
-(define_insn "*one_cmpl<mode>3"
- [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
- (and:PRED_ALL
- (not:PRED_ALL (match_operand:PRED_ALL 2 "register_operand" "Upa"))
- (match_operand:PRED_ALL 1 "register_operand" "Upa")))]
- "TARGET_SVE"
- "not\t%0.b, %1/z, %2.b"
-)
+;; -------------------------------------------------------------------------
+;; ---- [PRED] Binary logical operations (inverted second input)
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - BIC
+;; - ORN
+;; -------------------------------------------------------------------------
;; Predicated predicate BIC and ORN.
(define_insn "*<nlogical><mode>3"
[(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
(and:PRED_ALL
(NLOGICAL:PRED_ALL
- (not:PRED_ALL (match_operand:PRED_ALL 2 "register_operand" "Upa"))
- (match_operand:PRED_ALL 3 "register_operand" "Upa"))
+ (not:PRED_ALL (match_operand:PRED_ALL 3 "register_operand" "Upa"))
+ (match_operand:PRED_ALL 2 "register_operand" "Upa"))
(match_operand:PRED_ALL 1 "register_operand" "Upa")))]
"TARGET_SVE"
- "<nlogical>\t%0.b, %1/z, %3.b, %2.b"
+ "<nlogical>\t%0.b, %1/z, %2.b, %3.b"
)
+;; -------------------------------------------------------------------------
+;; ---- [PRED] Binary logical operations (inverted result)
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - NAND
+;; - NOR
+;; -------------------------------------------------------------------------
+
;; Predicated predicate NAND and NOR.
(define_insn "*<logical_nn><mode>3"
[(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
@@ -1235,388 +3415,586 @@
"<logical_nn>\t%0.b, %1/z, %2.b, %3.b"
)
-;; Unpredicated LSL, LSR and ASR by a vector.
-(define_expand "v<optab><mode>3"
+;; =========================================================================
+;; == Ternary arithmetic
+;; =========================================================================
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] MLA and MAD
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - MAD
+;; - MLA
+;; -------------------------------------------------------------------------
+
+;; Unpredicated integer addition of product.
+(define_expand "fma<mode>4"
[(set (match_operand:SVE_I 0 "register_operand")
- (unspec:SVE_I
- [(match_dup 3)
- (ASHIFT:SVE_I
- (match_operand:SVE_I 1 "register_operand")
- (match_operand:SVE_I 2 "aarch64_sve_<lr>shift_operand"))]
- UNSPEC_MERGE_PTRUE))]
+ (plus:SVE_I
+ (unspec:SVE_I
+ [(match_dup 4)
+ (mult:SVE_I (match_operand:SVE_I 1 "register_operand")
+ (match_operand:SVE_I 2 "nonmemory_operand"))]
+ UNSPEC_PRED_X)
+ (match_operand:SVE_I 3 "register_operand")))]
"TARGET_SVE"
{
- operands[3] = aarch64_ptrue_reg (<VPRED>mode);
+ if (aarch64_prepare_sve_int_fma (operands, PLUS))
+ DONE;
+ operands[4] = aarch64_ptrue_reg (<VPRED>mode);
}
)
-;; LSL, LSR and ASR by a vector, predicated with a PTRUE. We don't
-;; actually need the predicate for the first alternative, but using Upa
-;; or X isn't likely to gain much and would make the instruction seem
-;; less uniform to the register allocator.
-(define_insn_and_split "*v<optab><mode>3"
+;; Predicated integer addition of product.
+(define_insn "*fma<mode>4"
[(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
- (unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
- (ASHIFT:SVE_I
- (match_operand:SVE_I 2 "register_operand" "w, 0, w")
- (match_operand:SVE_I 3 "aarch64_sve_<lr>shift_operand" "D<lr>, w, w"))]
- UNSPEC_MERGE_PTRUE))]
+ (plus:SVE_I
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w, w")
+ (match_operand:SVE_I 3 "register_operand" "w, w, w"))]
+ UNSPEC_PRED_X)
+ (match_operand:SVE_I 4 "register_operand" "w, 0, w")))]
"TARGET_SVE"
"@
- #
- <shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- movprfx\t%0, %2\;<shift>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
- "&& reload_completed
- && !register_operand (operands[3], <MODE>mode)"
- [(set (match_dup 0) (ASHIFT:SVE_I (match_dup 2) (match_dup 3)))]
- ""
+ mad\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
+ mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %4\;mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
[(set_attr "movprfx" "*,*,yes")]
)
-;; Unpredicated shift operations by a constant (post-RA only).
-;; These are generated by splitting a predicated instruction whose
-;; predicate is unused.
-(define_insn "*post_ra_v<optab><mode>3"
- [(set (match_operand:SVE_I 0 "register_operand" "=w")
- (ASHIFT:SVE_I
- (match_operand:SVE_I 1 "register_operand" "w")
- (match_operand:SVE_I 2 "aarch64_simd_<lr>shift_imm")))]
- "TARGET_SVE && reload_completed"
- "<shift>\t%0.<Vetype>, %1.<Vetype>, #%2"
-)
-
-;; LSL, LSR and ASR by a scalar, which expands into one of the vector
-;; shifts above.
-(define_expand "<ASHIFT:optab><mode>3"
+;; Predicated integer addition of product with merging.
+(define_expand "cond_fma<mode>"
[(set (match_operand:SVE_I 0 "register_operand")
- (ASHIFT:SVE_I (match_operand:SVE_I 1 "register_operand")
- (match_operand:<VEL> 2 "general_operand")))]
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand")
+ (plus:SVE_I
+ (mult:SVE_I (match_operand:SVE_I 2 "register_operand")
+ (match_operand:SVE_I 3 "general_operand"))
+ (match_operand:SVE_I 4 "register_operand"))
+ (match_operand:SVE_I 5 "aarch64_simd_reg_or_zero")]
+ UNSPEC_SEL))]
"TARGET_SVE"
{
- rtx amount;
- if (CONST_INT_P (operands[2]))
- {
- amount = gen_const_vec_duplicate (<MODE>mode, operands[2]);
- if (!aarch64_sve_<lr>shift_operand (operands[2], <MODE>mode))
- amount = force_reg (<MODE>mode, amount);
- }
- else
- {
- amount = gen_reg_rtx (<MODE>mode);
- emit_insn (gen_vec_duplicate<mode> (amount,
- convert_to_mode (<VEL>mode,
- operands[2], 0)));
- }
- emit_insn (gen_v<optab><mode>3 (operands[0], operands[1], amount));
- DONE;
+ if (aarch64_prepare_sve_cond_int_fma (operands, PLUS))
+ DONE;
+ /* Swap the multiplication operands if the fallback value is the
+ second of the two. */
+ if (rtx_equal_p (operands[3], operands[5]))
+ std::swap (operands[2], operands[3]);
}
)
-;; Test all bits of operand 1. Operand 0 is a GP that is known to hold PTRUE.
-;;
-;; Using UNSPEC_PTEST_PTRUE allows combine patterns to assume that the GP
-;; is a PTRUE even if the optimizers haven't yet been able to propagate
-;; the constant. We would use a separate unspec code for PTESTs involving
-;; GPs that might not be PTRUEs.
-(define_insn "ptest_ptrue<mode>"
- [(set (reg:CC_NZC CC_REGNUM)
- (unspec:CC_NZC
- [(match_operand:PRED_ALL 0 "register_operand" "Upa")
- (match_operand:PRED_ALL 1 "register_operand" "Upa")]
- UNSPEC_PTEST_PTRUE))]
+;; Predicated integer addition of product, merging with the first input.
+(define_insn "*cond_fma<mode>_2"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (plus:SVE_I
+ (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "0, w")
+ (match_operand:SVE_I 3 "register_operand" "w, w"))
+ (match_operand:SVE_I 4 "register_operand" "w, w"))
+ (match_dup 2)]
+ UNSPEC_SEL))]
"TARGET_SVE"
- "ptest\t%0, %1.b"
+ "@
+ mad\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
+ movprfx\t%0, %2\;mad\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
-;; Set element I of the result if operand1 + J < operand2 for all J in [0, I].
-;; with the comparison being unsigned.
-(define_insn "while_ult<GPI:mode><PRED_ALL:mode>"
- [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
- (unspec:PRED_ALL [(match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
- (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")]
- UNSPEC_WHILE_LO))
- (clobber (reg:CC_NZC CC_REGNUM))]
+;; Predicated integer addition of product, merging with the third input.
+(define_insn "*cond_fma<mode>_4"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (plus:SVE_I
+ (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "w, w")
+ (match_operand:SVE_I 3 "register_operand" "w, w"))
+ (match_operand:SVE_I 4 "register_operand" "0, w"))
+ (match_dup 4)]
+ UNSPEC_SEL))]
"TARGET_SVE"
- "whilelo\t%0.<PRED_ALL:Vetype>, %<w>1, %<w>2"
+ "@
+ mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %4\;mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
-;; WHILELO sets the flags in the same way as a PTEST with a PTRUE GP.
-;; Handle the case in which both results are useful. The GP operand
-;; to the PTEST isn't needed, so we allow it to be anything.
-(define_insn_and_rewrite "*while_ult<GPI:mode><PRED_ALL:mode>_cc"
- [(set (reg:CC_NZC CC_REGNUM)
- (unspec:CC_NZC
- [(match_operand:PRED_ALL 1)
- (unspec:PRED_ALL
- [(match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")
- (match_operand:GPI 3 "aarch64_reg_or_zero" "rZ")]
- UNSPEC_WHILE_LO)]
- UNSPEC_PTEST_PTRUE))
- (set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
- (unspec:PRED_ALL [(match_dup 2)
- (match_dup 3)]
- UNSPEC_WHILE_LO))]
+;; Predicated integer addition of product, merging with an independent value.
+(define_insn_and_rewrite "*cond_fma<mode>_any"
+ [(set (match_operand:SVE_I 0 "register_operand" "=&w, &w, &w, &w, &w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
+ (plus:SVE_I
+ (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "w, w, 0, w, w, w")
+ (match_operand:SVE_I 3 "register_operand" "w, w, w, 0, w, w"))
+ (match_operand:SVE_I 4 "register_operand" "w, 0, w, w, w, w"))
+ (match_operand:SVE_I 5 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, Dz, 0, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && !rtx_equal_p (operands[2], operands[5])
+ && !rtx_equal_p (operands[3], operands[5])
+ && !rtx_equal_p (operands[4], operands[5])"
+ "@
+ movprfx\t%0.<Vetype>, %1/z, %4.<Vetype>\;mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;mad\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;mad\t%0.<Vetype>, %1/m, %2.<Vetype>, %4.<Vetype>
+ movprfx\t%0.<Vetype>, %1/m, %4.<Vetype>\;mla\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ #"
+ "&& reload_completed
+ && register_operand (operands[5], <MODE>mode)
+ && !rtx_equal_p (operands[0], operands[5])"
+ {
+ emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[4],
+ operands[5], operands[1]));
+ operands[5] = operands[4] = operands[0];
+ }
+ [(set_attr "movprfx" "yes")]
+)
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] MLS and MSB
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - MLS
+;; - MSB
+;; -------------------------------------------------------------------------
+
+;; Unpredicated integer subtraction of product.
+(define_expand "fnma<mode>4"
+ [(set (match_operand:SVE_I 0 "register_operand")
+ (minus:SVE_I
+ (match_operand:SVE_I 3 "register_operand")
+ (unspec:SVE_I
+ [(match_dup 4)
+ (mult:SVE_I (match_operand:SVE_I 1 "register_operand")
+ (match_operand:SVE_I 2 "general_operand"))]
+ UNSPEC_PRED_X)))]
"TARGET_SVE"
- "whilelo\t%0.<PRED_ALL:Vetype>, %<w>2, %<w>3"
- ;; Force the compiler to drop the unused predicate operand, so that we
- ;; don't have an unnecessary PTRUE.
- "&& !CONSTANT_P (operands[1])"
{
- operands[1] = CONSTM1_RTX (<PRED_ALL:MODE>mode);
+ if (aarch64_prepare_sve_int_fma (operands, MINUS))
+ DONE;
+ operands[4] = aarch64_ptrue_reg (<VPRED>mode);
}
)
-;; Integer comparisons predicated with a PTRUE.
-(define_insn "*cmp<cmp_op><mode>"
- [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
- (unspec:<VPRED>
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (SVE_INT_CMP:<VPRED>
- (match_operand:SVE_I 2 "register_operand" "w, w")
- (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
- UNSPEC_MERGE_PTRUE))
- (clobber (reg:CC_NZC CC_REGNUM))]
+;; Predicated integer subtraction of product.
+(define_insn "*fnma<mode>3"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, w, ?&w")
+ (minus:SVE_I
+ (match_operand:SVE_I 4 "register_operand" "w, 0, w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w, w")
+ (match_operand:SVE_I 3 "register_operand" "w, w, w"))]
+ UNSPEC_PRED_X)))]
"TARGET_SVE"
"@
- cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
- cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
+ msb\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
+ mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %4\;mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,*,yes")]
)
-;; Integer comparisons predicated with a PTRUE in which only the flags result
-;; is interesting.
-(define_insn "*cmp<cmp_op><mode>_ptest"
- [(set (reg:CC_NZC CC_REGNUM)
- (unspec:CC_NZC
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (unspec:<VPRED>
- [(match_dup 1)
- (SVE_INT_CMP:<VPRED>
- (match_operand:SVE_I 2 "register_operand" "w, w")
- (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
- UNSPEC_MERGE_PTRUE)]
- UNSPEC_PTEST_PTRUE))
- (clobber (match_scratch:<VPRED> 0 "=Upa, Upa"))]
+;; Predicated integer subtraction of product with merging.
+(define_expand "cond_fnma<mode>"
+ [(set (match_operand:SVE_I 0 "register_operand")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand")
+ (minus:SVE_I
+ (match_operand:SVE_I 4 "register_operand")
+ (mult:SVE_I (match_operand:SVE_I 2 "register_operand")
+ (match_operand:SVE_I 3 "general_operand")))
+ (match_operand:SVE_I 5 "aarch64_simd_reg_or_zero")]
+ UNSPEC_SEL))]
"TARGET_SVE"
- "@
- cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
- cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
+ {
+ if (aarch64_prepare_sve_cond_int_fma (operands, MINUS))
+ DONE;
+ /* Swap the multiplication operands if the fallback value is the
+ second of the two. */
+ if (rtx_equal_p (operands[3], operands[5]))
+ std::swap (operands[2], operands[3]);
+ }
)
-;; Integer comparisons predicated with a PTRUE in which both the flag and
-;; predicate results are interesting.
-(define_insn "*cmp<cmp_op><mode>_cc"
- [(set (reg:CC_NZC CC_REGNUM)
- (unspec:CC_NZC
+;; Predicated integer subtraction of product, merging with the first input.
+(define_insn "*cond_fnma<mode>_2"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_I
[(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (unspec:<VPRED>
- [(match_dup 1)
- (SVE_INT_CMP:<VPRED>
- (match_operand:SVE_I 2 "register_operand" "w, w")
- (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
- UNSPEC_MERGE_PTRUE)]
- UNSPEC_PTEST_PTRUE))
- (set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
- (unspec:<VPRED>
- [(match_dup 1)
- (SVE_INT_CMP:<VPRED>
- (match_dup 2)
- (match_dup 3))]
- UNSPEC_MERGE_PTRUE))]
+ (minus:SVE_I
+ (match_operand:SVE_I 4 "register_operand" "w, w")
+ (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "0, w")
+ (match_operand:SVE_I 3 "register_operand" "w, w")))
+ (match_dup 2)]
+ UNSPEC_SEL))]
"TARGET_SVE"
"@
- cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
- cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
+ msb\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
+ movprfx\t%0, %2\;msb\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
-;; Predicated integer comparisons, formed by combining a PTRUE-predicated
-;; comparison with an AND. Split the instruction into its preferred form
-;; (below) at the earliest opportunity, in order to get rid of the
-;; redundant operand 1.
-(define_insn_and_split "*pred_cmp<cmp_op><mode>_combine"
- [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
- (and:<VPRED>
- (unspec:<VPRED>
- [(match_operand:<VPRED> 1)
- (SVE_INT_CMP:<VPRED>
- (match_operand:SVE_I 2 "register_operand" "w, w")
- (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
- UNSPEC_MERGE_PTRUE)
- (match_operand:<VPRED> 4 "register_operand" "Upl, Upl")))
- (clobber (reg:CC_NZC CC_REGNUM))]
+;; Predicated integer subtraction of product, merging with the third input.
+(define_insn "*cond_fnma<mode>_4"
+ [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (minus:SVE_I
+ (match_operand:SVE_I 4 "register_operand" "0, w")
+ (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "w, w")
+ (match_operand:SVE_I 3 "register_operand" "w, w")))
+ (match_dup 4)]
+ UNSPEC_SEL))]
"TARGET_SVE"
- "#"
- "&& 1"
- [(parallel
- [(set (match_dup 0)
- (and:<VPRED>
- (SVE_INT_CMP:<VPRED>
- (match_dup 2)
- (match_dup 3))
- (match_dup 4)))
- (clobber (reg:CC_NZC CC_REGNUM))])]
+ "@
+ mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %4\;mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,yes")]
)
-;; Predicated integer comparisons.
-(define_insn "*pred_cmp<cmp_op><mode>"
- [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
- (and:<VPRED>
- (SVE_INT_CMP:<VPRED>
- (match_operand:SVE_I 2 "register_operand" "w, w")
- (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))
- (match_operand:<VPRED> 1 "register_operand" "Upl, Upl")))
- (clobber (reg:CC_NZC CC_REGNUM))]
- "TARGET_SVE"
+;; Predicated integer subtraction of product, merging with an
+;; independent value.
+(define_insn_and_rewrite "*cond_fnma<mode>_any"
+ [(set (match_operand:SVE_I 0 "register_operand" "=&w, &w, &w, &w, &w, ?&w")
+ (unspec:SVE_I
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
+ (minus:SVE_I
+ (match_operand:SVE_I 4 "register_operand" "w, 0, w, w, w, w")
+ (mult:SVE_I (match_operand:SVE_I 2 "register_operand" "w, w, 0, w, w, w")
+ (match_operand:SVE_I 3 "register_operand" "w, w, w, 0, w, w")))
+ (match_operand:SVE_I 5 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, Dz, 0, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && !rtx_equal_p (operands[2], operands[5])
+ && !rtx_equal_p (operands[3], operands[5])
+ && !rtx_equal_p (operands[4], operands[5])"
"@
- cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
- cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
+ movprfx\t%0.<Vetype>, %1/z, %4.<Vetype>\;mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;msb\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;msb\t%0.<Vetype>, %1/m, %2.<Vetype>, %4.<Vetype>
+ movprfx\t%0.<Vetype>, %1/m, %4.<Vetype>\;mls\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ #"
+ "&& reload_completed
+ && register_operand (operands[5], <MODE>mode)
+ && !rtx_equal_p (operands[0], operands[5])"
+ {
+ emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[4],
+ operands[5], operands[1]));
+ operands[5] = operands[4] = operands[0];
+ }
+ [(set_attr "movprfx" "yes")]
)
-;; Floating-point comparisons predicated with a PTRUE.
-(define_insn "*fcm<cmp_op><mode>"
- [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
- (unspec:<VPRED>
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (SVE_FP_CMP:<VPRED>
- (match_operand:SVE_F 2 "register_operand" "w, w")
- (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w"))]
- UNSPEC_MERGE_PTRUE))]
+;; -------------------------------------------------------------------------
+;; ---- [INT] Dot product
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - SDOT
+;; - UDOT
+;; -------------------------------------------------------------------------
+
+;; Four-element integer dot-product with accumulation.
+(define_insn "<sur>dot_prod<vsi2qi>"
+ [(set (match_operand:SVE_SDI 0 "register_operand" "=w, ?&w")
+ (plus:SVE_SDI
+ (unspec:SVE_SDI
+ [(match_operand:<VSI2QI> 1 "register_operand" "w, w")
+ (match_operand:<VSI2QI> 2 "register_operand" "w, w")]
+ DOTPROD)
+ (match_operand:SVE_SDI 3 "register_operand" "0, w")))]
"TARGET_SVE"
"@
- fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #0.0
- fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
+ <sur>dot\\t%0.<Vetype>, %1.<Vetype_fourth>, %2.<Vetype_fourth>
+ movprfx\t%0, %3\;<sur>dot\\t%0.<Vetype>, %1.<Vetype_fourth>, %2.<Vetype_fourth>"
+ [(set_attr "movprfx" "*,yes")]
)
-(define_insn "*fcmuo<mode>"
- [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
- (unspec:<VPRED>
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (unordered:<VPRED>
- (match_operand:SVE_F 2 "register_operand" "w")
- (match_operand:SVE_F 3 "register_operand" "w"))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "fcmuo\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
-)
+;; -------------------------------------------------------------------------
+;; ---- [INT] Sum of absolute differences
+;; -------------------------------------------------------------------------
+;; The patterns in this section are synthetic.
+;; -------------------------------------------------------------------------
-;; Floating-point comparisons predicated on a PTRUE, with the results ANDed
-;; with another predicate P. This does not have the same trapping behavior
-;; as predicating the comparison itself on P, but it's a legitimate fold,
-;; since we can drop any potentially-trapping operations whose results
-;; are not needed.
-;;
-;; Split the instruction into its preferred form (below) at the earliest
-;; opportunity, in order to get rid of the redundant operand 1.
-(define_insn_and_split "*fcm<cmp_op><mode>_and_combine"
- [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
- (and:<VPRED>
- (unspec:<VPRED>
- [(match_operand:<VPRED> 1)
- (SVE_FP_CMP
- (match_operand:SVE_F 2 "register_operand" "w, w")
- (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w"))]
- UNSPEC_MERGE_PTRUE)
- (match_operand:<VPRED> 4 "register_operand" "Upl, Upl")))]
+;; Emit a sequence to produce a sum-of-absolute-differences of the inputs in
+;; operands 1 and 2. The sequence also has to perform a widening reduction of
+;; the difference into a vector and accumulate that into operand 3 before
+;; copying that into the result operand 0.
+;; Perform that with a sequence of:
+;; MOV ones.b, #1
+;; [SU]ABD diff.b, p0/m, op1.b, op2.b
+;; MOVPRFX op0, op3 // If necessary
+;; UDOT op0.s, diff.b, ones.b
+(define_expand "<sur>sad<vsi2qi>"
+ [(use (match_operand:SVE_SDI 0 "register_operand"))
+ (unspec:<VSI2QI> [(use (match_operand:<VSI2QI> 1 "register_operand"))
+ (use (match_operand:<VSI2QI> 2 "register_operand"))] ABAL)
+ (use (match_operand:SVE_SDI 3 "register_operand"))]
"TARGET_SVE"
- "#"
- "&& 1"
- [(set (match_dup 0)
- (and:<VPRED>
- (SVE_FP_CMP:<VPRED>
- (match_dup 2)
- (match_dup 3))
- (match_dup 4)))]
+ {
+ rtx ones = force_reg (<VSI2QI>mode, CONST1_RTX (<VSI2QI>mode));
+ rtx diff = gen_reg_rtx (<VSI2QI>mode);
+ emit_insn (gen_<sur>abd<vsi2qi>_3 (diff, operands[1], operands[2]));
+ emit_insn (gen_udot_prod<vsi2qi> (operands[0], diff, ones, operands[3]));
+ DONE;
+ }
)
-(define_insn_and_split "*fcmuo<mode>_and_combine"
- [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
- (and:<VPRED>
- (unspec:<VPRED>
- [(match_operand:<VPRED> 1)
- (unordered
- (match_operand:SVE_F 2 "register_operand" "w")
- (match_operand:SVE_F 3 "register_operand" "w"))]
- UNSPEC_MERGE_PTRUE)
- (match_operand:<VPRED> 4 "register_operand" "Upl")))]
+;; -------------------------------------------------------------------------
+;; ---- [FP] General ternary arithmetic corresponding to unspecs
+;; -------------------------------------------------------------------------
+;; Includes merging patterns for:
+;; - FMAD
+;; - FMLA
+;; - FMLS
+;; - FMSB
+;; - FNMAD
+;; - FNMLA
+;; - FNMLS
+;; - FNMSB
+;; -------------------------------------------------------------------------
+
+;; Unpredicated floating-point ternary operations.
+(define_expand "<optab><mode>4"
+ [(set (match_operand:SVE_F 0 "register_operand")
+ (unspec:SVE_F
+ [(match_dup 4)
+ (const_int SVE_RELAXED_GP)
+ (match_operand:SVE_F 1 "register_operand")
+ (match_operand:SVE_F 2 "register_operand")
+ (match_operand:SVE_F 3 "register_operand")]
+ SVE_COND_FP_TERNARY))]
"TARGET_SVE"
- "#"
- "&& 1"
- [(set (match_dup 0)
- (and:<VPRED>
- (unordered:<VPRED>
- (match_dup 2)
- (match_dup 3))
- (match_dup 4)))]
+ {
+ operands[4] = aarch64_ptrue_reg (<VPRED>mode);
+ }
)
-;; Unpredicated floating-point comparisons, with the results ANDed
-;; with another predicate. This is a valid fold for the same reasons
-;; as above.
-(define_insn "*fcm<cmp_op><mode>_and"
- [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
- (and:<VPRED>
- (SVE_FP_CMP:<VPRED>
- (match_operand:SVE_F 2 "register_operand" "w, w")
- (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w"))
- (match_operand:<VPRED> 1 "register_operand" "Upl, Upl")))]
+;; Predicated floating-point ternary operations.
+(define_insn "*<optab><mode>4"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (match_operand:SI 5 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "%w, 0, w")
+ (match_operand:SVE_F 3 "register_operand" "w, w, w")
+ (match_operand:SVE_F 4 "register_operand" "0, w, w")]
+ SVE_COND_FP_TERNARY))]
"TARGET_SVE"
"@
- fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #0.0
- fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
+ <sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ <sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
+ movprfx\t%0, %4\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
+ [(set_attr "movprfx" "*,*,yes")]
)
-(define_insn "*fcmuo<mode>_and"
- [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
- (and:<VPRED>
- (unordered:<VPRED>
- (match_operand:SVE_F 2 "register_operand" "w")
- (match_operand:SVE_F 3 "register_operand" "w"))
- (match_operand:<VPRED> 1 "register_operand" "Upl")))]
+;; Predicated floating-point ternary operations with merging.
+(define_expand "cond_<optab><mode>"
+ [(set (match_operand:SVE_F 0 "register_operand")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand")
+ (unspec:SVE_F
+ [(match_dup 1)
+ (const_int SVE_STRICT_GP)
+ (match_operand:SVE_F 2 "register_operand")
+ (match_operand:SVE_F 3 "register_operand")
+ (match_operand:SVE_F 4 "register_operand")]
+ SVE_COND_FP_TERNARY)
+ (match_operand:SVE_F 5 "aarch64_simd_reg_or_zero")]
+ UNSPEC_SEL))]
"TARGET_SVE"
- "fcmuo\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
+{
+ /* Swap the multiplication operands if the fallback value is the
+ second of the two. */
+ if (rtx_equal_p (operands[3], operands[5]))
+ std::swap (operands[2], operands[3]);
+})
+
+;; Predicated floating-point ternary operations, merging with the
+;; first input.
+(define_insn_and_rewrite "*cond_<optab><mode>_2"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 5)
+ (match_operand:SI 6 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "0, w")
+ (match_operand:SVE_F 3 "register_operand" "w, w")
+ (match_operand:SVE_F 4 "register_operand" "w, w")]
+ SVE_COND_FP_TERNARY)
+ (match_dup 2)]
+ UNSPEC_SEL))]
+ "TARGET_SVE && aarch64_sve_pred_dominates_p (&operands[5], operands[1])"
+ "@
+ <sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
+ movprfx\t%0, %2\;<sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
+ "&& !rtx_equal_p (operands[1], operands[5])"
+ {
+ operands[5] = copy_rtx (operands[1]);
+ }
+ [(set_attr "movprfx" "*,yes")]
)
-;; Predicated floating-point comparisons. We don't need a version
-;; of this for unordered comparisons.
-(define_insn "*pred_fcm<cmp_op><mode>"
- [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
- (unspec:<VPRED>
+;; Predicated floating-point ternary operations, merging with the
+;; third input.
+(define_insn_and_rewrite "*cond_<optab><mode>_4"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_F
[(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (match_operand:SVE_F 2 "register_operand" "w, w")
- (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w")]
- SVE_COND_FP_CMP))]
- "TARGET_SVE"
+ (unspec:SVE_F
+ [(match_operand 5)
+ (match_operand:SI 6 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "w, w")
+ (match_operand:SVE_F 3 "register_operand" "w, w")
+ (match_operand:SVE_F 4 "register_operand" "0, w")]
+ SVE_COND_FP_TERNARY)
+ (match_dup 4)]
+ UNSPEC_SEL))]
+ "TARGET_SVE && aarch64_sve_pred_dominates_p (&operands[5], operands[1])"
"@
- fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #0.0
- fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
+ <sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ movprfx\t%0, %4\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
+ "&& !rtx_equal_p (operands[1], operands[5])"
+ {
+ operands[5] = copy_rtx (operands[1]);
+ }
+ [(set_attr "movprfx" "*,yes")]
+)
+
+;; Predicated floating-point ternary operations, merging with an
+;; independent value.
+(define_insn_and_rewrite "*cond_<optab><mode>_any"
+ [(set (match_operand:SVE_F 0 "register_operand" "=&w, &w, &w, &w, &w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 6)
+ (match_operand:SI 7 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "w, w, 0, w, w, w")
+ (match_operand:SVE_F 3 "register_operand" "w, w, w, 0, w, w")
+ (match_operand:SVE_F 4 "register_operand" "w, 0, w, w, w, w")]
+ SVE_COND_FP_TERNARY)
+ (match_operand:SVE_F 5 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, Dz, 0, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && !rtx_equal_p (operands[2], operands[5])
+ && !rtx_equal_p (operands[3], operands[5])
+ && !rtx_equal_p (operands[4], operands[5])
+ && aarch64_sve_pred_dominates_p (&operands[6], operands[1])"
+ "@
+ movprfx\t%0.<Vetype>, %1/z, %4.<Vetype>\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
+ movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fmad_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %4.<Vetype>
+ movprfx\t%0.<Vetype>, %1/m, %4.<Vetype>\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
+ #"
+ "&& 1"
+ {
+ if (reload_completed
+ && register_operand (operands[5], <MODE>mode)
+ && !rtx_equal_p (operands[0], operands[5]))
+ {
+ emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[4],
+ operands[5], operands[1]));
+ operands[5] = operands[4] = operands[0];
+ }
+ else if (!rtx_equal_p (operands[1], operands[6]))
+ operands[6] = copy_rtx (operands[1]);
+ else
+ FAIL;
+ }
+ [(set_attr "movprfx" "yes")]
)
+;; =========================================================================
+;; == Comparisons and selects
+;; =========================================================================
+
+;; -------------------------------------------------------------------------
+;; ---- [INT,FP] Select based on predicates
+;; -------------------------------------------------------------------------
+;; Includes merging patterns for:
+;; - FMOV
+;; - MOV
+;; - SEL
+;; -------------------------------------------------------------------------
+
;; vcond_mask operand order: true, false, mask
;; UNSPEC_SEL operand order: mask, true, false (as for VEC_COND_EXPR)
;; SEL operand order: mask, true, false
-(define_insn "vcond_mask_<mode><vpred>"
- [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
+(define_expand "vcond_mask_<mode><vpred>"
+ [(set (match_operand:SVE_ALL 0 "register_operand")
(unspec:SVE_ALL
- [(match_operand:<VPRED> 3 "register_operand" "Upa")
- (match_operand:SVE_ALL 1 "register_operand" "w")
- (match_operand:SVE_ALL 2 "register_operand" "w")]
+ [(match_operand:<VPRED> 3 "register_operand")
+ (match_operand:SVE_ALL 1 "aarch64_sve_reg_or_dup_imm")
+ (match_operand:SVE_ALL 2 "aarch64_simd_reg_or_zero")]
UNSPEC_SEL))]
"TARGET_SVE"
- "sel\t%0.<Vetype>, %3, %1.<Vetype>, %2.<Vetype>"
+ {
+ if (register_operand (operands[1], <MODE>mode))
+ operands[2] = force_reg (<MODE>mode, operands[2]);
+ }
)
-;; Selects between a duplicated immediate and zero.
-(define_insn "aarch64_sve_dup<mode>_const"
- [(set (match_operand:SVE_I 0 "register_operand" "=w")
- (unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (match_operand:SVE_I 2 "aarch64_sve_dup_immediate")
- (match_operand:SVE_I 3 "aarch64_simd_imm_zero")]
+;; Selects between:
+;; - two registers
+;; - a duplicated immediate and a register
+;; - a duplicated immediate and zero
+(define_insn "*vcond_mask_<mode><vpred>"
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=w, w, w, w, ?w, ?&w, ?&w")
+ (unspec:SVE_ALL
+ [(match_operand:<VPRED> 3 "register_operand" "Upa, Upa, Upa, Upa, Upl, Upl, Upl")
+ (match_operand:SVE_ALL 1 "aarch64_sve_reg_or_dup_imm" "w, vss, vss, Ufc, Ufc, vss, Ufc")
+ (match_operand:SVE_ALL 2 "aarch64_simd_reg_or_zero" "w, 0, Dz, 0, Dz, w, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && (!register_operand (operands[1], <MODE>mode)
+ || register_operand (operands[2], <MODE>mode))"
+ "@
+ sel\t%0.<Vetype>, %3, %1.<Vetype>, %2.<Vetype>
+ mov\t%0.<Vetype>, %3/m, #%I1
+ mov\t%0.<Vetype>, %3/z, #%I1
+ fmov\t%0.<Vetype>, %3/m, #%1
+ movprfx\t%0.<Vetype>, %3/z, %0.<Vetype>\;fmov\t%0.<Vetype>, %3/m, #%1
+ movprfx\t%0, %2\;mov\t%0.<Vetype>, %3/m, #%I1
+ movprfx\t%0, %2\;fmov\t%0.<Vetype>, %3/m, #%1"
+ [(set_attr "movprfx" "*,*,*,*,yes,yes,yes")]
+)
+
+;; Optimize selects between a duplicated scalar variable and another vector,
+;; the latter of which can be a zero constant or a variable. Treat duplicates
+;; of GPRs as being more expensive than duplicates of FPRs, since they
+;; involve a cross-file move.
+(define_insn "*aarch64_sel_dup<mode>"
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=?w, w, ??w, ?&w, ??&w, ?&w")
+ (unspec:SVE_ALL
+ [(match_operand:<VPRED> 3 "register_operand" "Upa, Upa, Upl, Upl, Upl, Upl")
+ (vec_duplicate:SVE_ALL
+ (match_operand:<VEL> 1 "register_operand" "r, w, r, w, r, w"))
+ (match_operand:SVE_ALL 2 "aarch64_simd_reg_or_zero" "0, 0, Dz, Dz, w, w")]
UNSPEC_SEL))]
"TARGET_SVE"
- "mov\t%0.<Vetype>, %1/z, #%2"
+ "@
+ mov\t%0.<Vetype>, %3/m, %<vwcore>1
+ mov\t%0.<Vetype>, %3/m, %<Vetype>1
+ movprfx\t%0.<Vetype>, %3/z, %0.<Vetype>\;mov\t%0.<Vetype>, %3/m, %<vwcore>1
+ movprfx\t%0.<Vetype>, %3/z, %0.<Vetype>\;mov\t%0.<Vetype>, %3/m, %<Vetype>1
+ movprfx\t%0, %2\;mov\t%0.<Vetype>, %3/m, %<vwcore>1
+ movprfx\t%0, %2\;mov\t%0.<Vetype>, %3/m, %<Vetype>1"
+ [(set_attr "movprfx" "*,*,yes,yes,yes,yes")]
)
+;; -------------------------------------------------------------------------
+;; ---- [INT,FP] Compare and select
+;; -------------------------------------------------------------------------
+;; The patterns in this section are synthetic.
+;; -------------------------------------------------------------------------
+
;; Integer (signed) vcond. Don't enforce an immediate range here, since it
;; depends on the comparison; leave it to aarch64_expand_sve_vcond instead.
(define_expand "vcond<mode><v_int_equiv>"
@@ -1625,8 +4003,8 @@
(match_operator 3 "comparison_operator"
[(match_operand:<V_INT_EQUIV> 4 "register_operand")
(match_operand:<V_INT_EQUIV> 5 "nonmemory_operand")])
- (match_operand:SVE_ALL 1 "register_operand")
- (match_operand:SVE_ALL 2 "register_operand")))]
+ (match_operand:SVE_ALL 1 "nonmemory_operand")
+ (match_operand:SVE_ALL 2 "nonmemory_operand")))]
"TARGET_SVE"
{
aarch64_expand_sve_vcond (<MODE>mode, <V_INT_EQUIV>mode, operands);
@@ -1642,8 +4020,8 @@
(match_operator 3 "comparison_operator"
[(match_operand:<V_INT_EQUIV> 4 "register_operand")
(match_operand:<V_INT_EQUIV> 5 "nonmemory_operand")])
- (match_operand:SVE_ALL 1 "register_operand")
- (match_operand:SVE_ALL 2 "register_operand")))]
+ (match_operand:SVE_ALL 1 "nonmemory_operand")
+ (match_operand:SVE_ALL 2 "nonmemory_operand")))]
"TARGET_SVE"
{
aarch64_expand_sve_vcond (<MODE>mode, <V_INT_EQUIV>mode, operands);
@@ -1651,17 +4029,16 @@
}
)
-;; Floating-point vcond. All comparisons except FCMUO allow a zero
-;; operand; aarch64_expand_sve_vcond handles the case of an FCMUO
-;; with zero.
+;; Floating-point vcond. All comparisons except FCMUO allow a zero operand;
+;; aarch64_expand_sve_vcond handles the case of an FCMUO with zero.
(define_expand "vcond<mode><v_fp_equiv>"
- [(set (match_operand:SVE_SD 0 "register_operand")
- (if_then_else:SVE_SD
+ [(set (match_operand:SVE_HSD 0 "register_operand")
+ (if_then_else:SVE_HSD
(match_operator 3 "comparison_operator"
[(match_operand:<V_FP_EQUIV> 4 "register_operand")
(match_operand:<V_FP_EQUIV> 5 "aarch64_simd_reg_or_zero")])
- (match_operand:SVE_SD 1 "register_operand")
- (match_operand:SVE_SD 2 "register_operand")))]
+ (match_operand:SVE_HSD 1 "nonmemory_operand")
+ (match_operand:SVE_HSD 2 "nonmemory_operand")))]
"TARGET_SVE"
{
aarch64_expand_sve_vcond (<MODE>mode, <V_FP_EQUIV>mode, operands);
@@ -1669,6 +4046,22 @@
}
)
+;; -------------------------------------------------------------------------
+;; ---- [INT] Comparisons
+;; -------------------------------------------------------------------------
+;; Includes merging patterns for:
+;; - CMPEQ
+;; - CMPGE
+;; - CMPGT
+;; - CMPHI
+;; - CMPHS
+;; - CMPLE
+;; - CMPLO
+;; - CMPLS
+;; - CMPLT
+;; - CMPNE
+;; -------------------------------------------------------------------------
+
;; Signed integer comparisons. Don't enforce an immediate range here, since
;; it depends on the comparison; leave it to aarch64_expand_sve_vec_cmp_int
;; instead.
@@ -1705,293 +4098,379 @@
}
)
-;; Floating-point comparisons. All comparisons except FCMUO allow a zero
-;; operand; aarch64_expand_sve_vec_cmp_float handles the case of an FCMUO
-;; with zero.
-(define_expand "vec_cmp<mode><vpred>"
- [(set (match_operand:<VPRED> 0 "register_operand")
- (match_operator:<VPRED> 1 "comparison_operator"
- [(match_operand:SVE_F 2 "register_operand")
- (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero")]))]
+;; Predicated integer comparisons.
+(define_insn "@aarch64_pred_cmp<cmp_op><mode>"
+ [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
+ (unspec:<VPRED>
+ [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
+ (match_operand:SI 2 "aarch64_sve_ptrue_flag")
+ (SVE_INT_CMP:<VPRED>
+ (match_operand:SVE_I 3 "register_operand" "w, w")
+ (match_operand:SVE_I 4 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
+ UNSPEC_PRED_Z))
+ (clobber (reg:CC_NZC CC_REGNUM))]
"TARGET_SVE"
+ "@
+ cmp<cmp_op>\t%0.<Vetype>, %1/z, %3.<Vetype>, #%4
+ cmp<cmp_op>\t%0.<Vetype>, %1/z, %3.<Vetype>, %4.<Vetype>"
+)
+
+;; Predicated integer comparisons in which both the flag and predicate
+;; results are interesting.
+(define_insn_and_rewrite "*cmp<cmp_op><mode>_cc"
+ [(set (reg:CC_NZC CC_REGNUM)
+ (unspec:CC_NZC
+ [(match_operand:VNx16BI 1 "register_operand" "Upl, Upl")
+ (match_operand 4)
+ (match_operand:SI 5 "aarch64_sve_ptrue_flag")
+ (unspec:<VPRED>
+ [(match_operand 6)
+ (match_operand:SI 7 "aarch64_sve_ptrue_flag")
+ (SVE_INT_CMP:<VPRED>
+ (match_operand:SVE_I 2 "register_operand" "w, w")
+ (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
+ UNSPEC_PRED_Z)]
+ UNSPEC_PTEST))
+ (set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
+ (unspec:<VPRED>
+ [(match_dup 6)
+ (match_dup 7)
+ (SVE_INT_CMP:<VPRED>
+ (match_dup 2)
+ (match_dup 3))]
+ UNSPEC_PRED_Z))]
+ "TARGET_SVE
+ && aarch64_sve_same_pred_for_ptest_p (&operands[4], &operands[6])"
+ "@
+ cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
+ cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
+ "&& !rtx_equal_p (operands[4], operands[6])"
{
- aarch64_expand_sve_vec_cmp_float (operands[0], GET_CODE (operands[1]),
- operands[2], operands[3], false);
- DONE;
+ operands[6] = copy_rtx (operands[4]);
+ operands[7] = operands[5];
}
)
-;; Branch based on predicate equality or inequality.
-(define_expand "cbranch<mode>4"
- [(set (pc)
- (if_then_else
- (match_operator 0 "aarch64_equality_operator"
- [(match_operand:PRED_ALL 1 "register_operand")
- (match_operand:PRED_ALL 2 "aarch64_simd_reg_or_zero")])
- (label_ref (match_operand 3 ""))
- (pc)))]
- ""
+;; Predicated integer comparisons in which only the flags result is
+;; interesting.
+(define_insn_and_rewrite "*cmp<cmp_op><mode>_ptest"
+ [(set (reg:CC_NZC CC_REGNUM)
+ (unspec:CC_NZC
+ [(match_operand:VNx16BI 1 "register_operand" "Upl, Upl")
+ (match_operand 4)
+ (match_operand:SI 5 "aarch64_sve_ptrue_flag")
+ (unspec:<VPRED>
+ [(match_operand 6)
+ (match_operand:SI 7 "aarch64_sve_ptrue_flag")
+ (SVE_INT_CMP:<VPRED>
+ (match_operand:SVE_I 2 "register_operand" "w, w")
+ (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
+ UNSPEC_PRED_Z)]
+ UNSPEC_PTEST))
+ (clobber (match_scratch:<VPRED> 0 "=Upa, Upa"))]
+ "TARGET_SVE
+ && aarch64_sve_same_pred_for_ptest_p (&operands[4], &operands[6])"
+ "@
+ cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #%3
+ cmp<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
+ "&& !rtx_equal_p (operands[4], operands[6])"
{
- rtx ptrue = aarch64_ptrue_reg (<MODE>mode);
- rtx pred;
- if (operands[2] == CONST0_RTX (<MODE>mode))
- pred = operands[1];
- else
- {
- pred = gen_reg_rtx (<MODE>mode);
- emit_insn (gen_pred_xor<mode>3 (pred, ptrue, operands[1],
- operands[2]));
- }
- emit_insn (gen_ptest_ptrue<mode> (ptrue, pred));
- operands[1] = gen_rtx_REG (CC_NZCmode, CC_REGNUM);
- operands[2] = const0_rtx;
+ operands[6] = copy_rtx (operands[4]);
+ operands[7] = operands[5];
}
)
-;; Unpredicated integer MIN/MAX.
-(define_expand "<su><maxmin><mode>3"
- [(set (match_operand:SVE_I 0 "register_operand")
- (unspec:SVE_I
- [(match_dup 3)
- (MAXMIN:SVE_I (match_operand:SVE_I 1 "register_operand")
- (match_operand:SVE_I 2 "register_operand"))]
- UNSPEC_MERGE_PTRUE))]
+;; Predicated integer comparisons, formed by combining a PTRUE-predicated
+;; comparison with an AND. Split the instruction into its preferred form
+;; at the earliest opportunity, in order to get rid of the redundant
+;; operand 4.
+(define_insn_and_split "*cmp<cmp_op><mode>_and"
+ [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
+ (and:<VPRED>
+ (unspec:<VPRED>
+ [(match_operand 4)
+ (const_int SVE_KNOWN_PTRUE)
+ (SVE_INT_CMP:<VPRED>
+ (match_operand:SVE_I 2 "register_operand" "w, w")
+ (match_operand:SVE_I 3 "aarch64_sve_cmp_<sve_imm_con>_operand" "<sve_imm_con>, w"))]
+ UNSPEC_PRED_Z)
+ (match_operand:<VPRED> 1 "register_operand" "Upl, Upl")))
+ (clobber (reg:CC_NZC CC_REGNUM))]
"TARGET_SVE"
- {
- operands[3] = aarch64_ptrue_reg (<VPRED>mode);
- }
+ "#"
+ "&& 1"
+ [(parallel
+ [(set (match_dup 0)
+ (unspec:<VPRED>
+ [(match_dup 1)
+ (const_int SVE_MAYBE_NOT_PTRUE)
+ (SVE_INT_CMP:<VPRED>
+ (match_dup 2)
+ (match_dup 3))]
+ UNSPEC_PRED_Z))
+ (clobber (reg:CC_NZC CC_REGNUM))])]
)
-;; Integer MIN/MAX predicated with a PTRUE.
-(define_insn "*<su><maxmin><mode>3"
- [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
- (unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (MAXMIN:SVE_I (match_operand:SVE_I 2 "register_operand" "%0, w")
- (match_operand:SVE_I 3 "register_operand" "w, w"))]
- UNSPEC_MERGE_PTRUE))]
+;; -------------------------------------------------------------------------
+;; ---- [INT] While tests
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - WHILELO
+;; -------------------------------------------------------------------------
+
+;; Set element I of the result if operand1 + J < operand2 for all J in [0, I],
+;; with the comparison being unsigned.
+(define_insn "@while_ult<GPI:mode><PRED_ALL:mode>"
+ [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
+ (unspec:PRED_ALL [(match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
+ (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")]
+ UNSPEC_WHILE_LO))
+ (clobber (reg:CC_NZC CC_REGNUM))]
"TARGET_SVE"
- "@
- <su><maxmin>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- movprfx\t%0, %2\;<su><maxmin>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
- [(set_attr "movprfx" "*,yes")]
+ "whilelo\t%0.<PRED_ALL:Vetype>, %<w>1, %<w>2"
)
-;; Unpredicated floating-point MIN/MAX.
-(define_expand "<su><maxmin><mode>3"
- [(set (match_operand:SVE_F 0 "register_operand")
- (unspec:SVE_F
- [(match_dup 3)
- (FMAXMIN:SVE_F (match_operand:SVE_F 1 "register_operand")
- (match_operand:SVE_F 2 "register_operand"))]
- UNSPEC_MERGE_PTRUE))]
+;; WHILELO sets the flags in the same way as a PTEST with a PTRUE GP.
+;; Handle the case in which both results are useful. The GP operands
+;; to the PTEST aren't needed, so we allow them to be anything.
+(define_insn_and_rewrite "*while_ult<GPI:mode><PRED_ALL:mode>_cc"
+ [(set (reg:CC_NZC CC_REGNUM)
+ (unspec:CC_NZC
+ [(match_operand 3)
+ (match_operand 4)
+ (const_int SVE_KNOWN_PTRUE)
+ (unspec:PRED_ALL
+ [(match_operand:GPI 1 "aarch64_reg_or_zero" "rZ")
+ (match_operand:GPI 2 "aarch64_reg_or_zero" "rZ")]
+ UNSPEC_WHILE_LO)]
+ UNSPEC_PTEST))
+ (set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
+ (unspec:PRED_ALL [(match_dup 1)
+ (match_dup 2)]
+ UNSPEC_WHILE_LO))]
"TARGET_SVE"
+ "whilelo\t%0.<PRED_ALL:Vetype>, %<w>1, %<w>2"
+ ;; Force the compiler to drop the unused predicate operand, so that we
+ ;; don't have an unnecessary PTRUE.
+ "&& (!CONSTANT_P (operands[3]) || !CONSTANT_P (operands[4]))"
{
- operands[3] = aarch64_ptrue_reg (<VPRED>mode);
+ operands[3] = CONSTM1_RTX (VNx16BImode);
+ operands[4] = CONSTM1_RTX (<PRED_ALL:MODE>mode);
}
)
-;; Floating-point MIN/MAX predicated with a PTRUE.
-(define_insn "*<su><maxmin><mode>3"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (FMAXMIN:SVE_F (match_operand:SVE_F 2 "register_operand" "%0, w")
- (match_operand:SVE_F 3 "register_operand" "w, w"))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "@
- f<maxmin>nm\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- movprfx\t%0, %2\;f<maxmin>nm\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
- [(set_attr "movprfx" "*,yes")]
-)
+;; -------------------------------------------------------------------------
+;; ---- [FP] Direct comparisons
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - FCMEQ
+;; - FCMGE
+;; - FCMGT
+;; - FCMLE
+;; - FCMLT
+;; - FCMNE
+;; - FCMUO
+;; -------------------------------------------------------------------------
-;; Unpredicated fmin/fmax.
-(define_expand "<maxmin_uns><mode>3"
- [(set (match_operand:SVE_F 0 "register_operand")
- (unspec:SVE_F
- [(match_dup 3)
- (unspec:SVE_F [(match_operand:SVE_F 1 "register_operand")
- (match_operand:SVE_F 2 "register_operand")]
- FMAXMIN_UNS)]
- UNSPEC_MERGE_PTRUE))]
+;; Floating-point comparisons. All comparisons except FCMUO allow a zero
+;; operand; aarch64_expand_sve_vec_cmp_float handles the case of an FCMUO
+;; with zero.
+(define_expand "vec_cmp<mode><vpred>"
+ [(set (match_operand:<VPRED> 0 "register_operand")
+ (match_operator:<VPRED> 1 "comparison_operator"
+ [(match_operand:SVE_F 2 "register_operand")
+ (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero")]))]
"TARGET_SVE"
{
- operands[3] = aarch64_ptrue_reg (<VPRED>mode);
+ aarch64_expand_sve_vec_cmp_float (operands[0], GET_CODE (operands[1]),
+ operands[2], operands[3], false);
+ DONE;
}
)
-;; fmin/fmax predicated with a PTRUE.
-(define_insn "*<maxmin_uns><mode>3"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
- (unspec:SVE_F
+;; Predicated floating-point comparisons.
+(define_insn "*fcm<cmp_op><mode>"
+ [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
+ (unspec:<VPRED>
[(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (unspec:SVE_F [(match_operand:SVE_F 2 "register_operand" "%0, w")
- (match_operand:SVE_F 3 "register_operand" "w, w")]
- FMAXMIN_UNS)]
- UNSPEC_MERGE_PTRUE))]
+ (match_operand:SI 4 "aarch64_sve_ptrue_flag")
+ (match_operand:SVE_F 2 "register_operand" "w, w")
+ (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w")]
+ SVE_COND_FP_CMP_I0))]
"TARGET_SVE"
"@
- <maxmin_uns_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- movprfx\t%0, %2\;<maxmin_uns_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
- [(set_attr "movprfx" "*,yes")]
-)
-
-;; Predicated integer operations with select.
-(define_expand "cond_<optab><mode>"
- [(set (match_operand:SVE_I 0 "register_operand")
- (unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand")
- (SVE_INT_BINARY:SVE_I
- (match_operand:SVE_I 2 "register_operand")
- (match_operand:SVE_I 3 "register_operand"))
- (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero")]
- UNSPEC_SEL))]
- "TARGET_SVE"
+ fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, #0.0
+ fcm<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
)
-(define_expand "cond_<optab><mode>"
- [(set (match_operand:SVE_SDI 0 "register_operand")
- (unspec:SVE_SDI
- [(match_operand:<VPRED> 1 "register_operand")
- (SVE_INT_BINARY_SD:SVE_SDI
- (match_operand:SVE_SDI 2 "register_operand")
- (match_operand:SVE_SDI 3 "register_operand"))
- (match_operand:SVE_SDI 4 "aarch64_simd_reg_or_zero")]
- UNSPEC_SEL))]
+;; Same for unordered comparisons.
+(define_insn "*fcmuo<mode>"
+ [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
+ (unspec:<VPRED>
+ [(match_operand:<VPRED> 1 "register_operand" "Upl")
+ (match_operand:SI 4 "aarch64_sve_ptrue_flag")
+ (match_operand:SVE_F 2 "register_operand" "w")
+ (match_operand:SVE_F 3 "register_operand" "w")]
+ UNSPEC_COND_FCMUO))]
"TARGET_SVE"
+ "fcmuo\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
)
-;; Predicated integer operations with select matching the first operand.
-(define_insn "*cond_<optab><mode>_2"
- [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
- (unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (SVE_INT_BINARY:SVE_I
- (match_operand:SVE_I 2 "register_operand" "0, w")
- (match_operand:SVE_I 3 "register_operand" "w, w"))
- (match_dup 2)]
- UNSPEC_SEL))]
+;; Floating-point comparisons predicated on a PTRUE, with the results ANDed
+;; with another predicate P. This does not have the same trapping behavior
+;; as predicating the comparison itself on P, but it's a legitimate fold,
+;; since we can drop any potentially-trapping operations whose results
+;; are not needed.
+;;
+;; Split the instruction into its preferred form (below) at the earliest
+;; opportunity, in order to get rid of the redundant operand 1.
+(define_insn_and_split "*fcm<cmp_op><mode>_and_combine"
+ [(set (match_operand:<VPRED> 0 "register_operand" "=Upa, Upa")
+ (and:<VPRED>
+ (unspec:<VPRED>
+ [(match_operand:<VPRED> 1)
+ (const_int SVE_KNOWN_PTRUE)
+ (match_operand:SVE_F 2 "register_operand" "w, w")
+ (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "Dz, w")]
+ SVE_COND_FP_CMP_I0)
+ (match_operand:<VPRED> 4 "register_operand" "Upl, Upl")))]
"TARGET_SVE"
- "@
- <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
- [(set_attr "movprfx" "*,yes")]
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (unspec:<VPRED>
+ [(match_dup 4)
+ (const_int SVE_MAYBE_NOT_PTRUE)
+ (match_dup 2)
+ (match_dup 3)]
+ SVE_COND_FP_CMP_I0))]
)
-(define_insn "*cond_<optab><mode>_2"
- [(set (match_operand:SVE_SDI 0 "register_operand" "=w, ?&w")
- (unspec:SVE_SDI
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (SVE_INT_BINARY_SD:SVE_SDI
- (match_operand:SVE_SDI 2 "register_operand" "0, w")
- (match_operand:SVE_SDI 3 "register_operand" "w, w"))
- (match_dup 2)]
- UNSPEC_SEL))]
+;; Same for unordered comparisons.
+(define_insn_and_split "*fcmuo<mode>_and_combine"
+ [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
+ (and:<VPRED>
+ (unspec:<VPRED>
+ [(match_operand:<VPRED> 1)
+ (const_int SVE_KNOWN_PTRUE)
+ (match_operand:SVE_F 2 "register_operand" "w")
+ (match_operand:SVE_F 3 "register_operand" "w")]
+ UNSPEC_COND_FCMUO)
+ (match_operand:<VPRED> 4 "register_operand" "Upl")))]
"TARGET_SVE"
- "@
- <sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- movprfx\t%0, %2\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
- [(set_attr "movprfx" "*,yes")]
-)
-
-;; Predicated integer operations with select matching the second operand.
-(define_insn "*cond_<optab><mode>_3"
- [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
- (unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (SVE_INT_BINARY:SVE_I
- (match_operand:SVE_I 2 "register_operand" "w, w")
- (match_operand:SVE_I 3 "register_operand" "0, w"))
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (unspec:<VPRED>
+ [(match_dup 4)
+ (const_int SVE_MAYBE_NOT_PTRUE)
+ (match_dup 2)
(match_dup 3)]
- UNSPEC_SEL))]
- "TARGET_SVE"
- "@
- <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
- movprfx\t%0, %3\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
- [(set_attr "movprfx" "*,yes")]
+ UNSPEC_COND_FCMUO))]
)
-(define_insn "*cond_<optab><mode>_3"
- [(set (match_operand:SVE_SDI 0 "register_operand" "=w, ?&w")
- (unspec:SVE_SDI
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (SVE_INT_BINARY_SD:SVE_SDI
- (match_operand:SVE_SDI 2 "register_operand" "w, w")
- (match_operand:SVE_SDI 3 "register_operand" "0, w"))
- (match_dup 3)]
- UNSPEC_SEL))]
- "TARGET_SVE"
- "@
- <sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
- movprfx\t%0, %3\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
- [(set_attr "movprfx" "*,yes")]
-)
+;; -------------------------------------------------------------------------
+;; ---- [FP] Absolute comparisons
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - FACGE
+;; - FACGT
+;; - FACLE
+;; - FACLT
+;; -------------------------------------------------------------------------
-;; Predicated integer binary operations in which the values of inactive
-;; lanes are distinct from the other inputs.
-(define_insn_and_rewrite "*cond_<optab><mode>_any"
- [(set (match_operand:SVE_I 0 "register_operand" "=&w, &w, &w, &w, ?&w")
- (unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
- (SVE_INT_BINARY:SVE_I
- (match_operand:SVE_I 2 "register_operand" "0, w, w, w, w")
- (match_operand:SVE_I 3 "register_operand" "w, 0, w, w, w"))
- (match_operand:SVE_I 4 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, 0, w")]
- UNSPEC_SEL))]
+;; Predicated floating-point absolute comparisons.
+(define_insn_and_rewrite "*aarch64_pred_fac<cmp_op><mode>"
+ [(set (match_operand:<VPRED> 0 "register_operand" "=Upa")
+ (unspec:<VPRED>
+ [(match_operand:<VPRED> 1 "register_operand" "Upl")
+ (match_operand:SI 4 "aarch64_sve_ptrue_flag")
+ (unspec:SVE_F
+ [(match_operand 5)
+ (match_operand:SI 6 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "w")]
+ UNSPEC_COND_FABS)
+ (unspec:SVE_F
+ [(match_operand 7)
+ (match_operand:SI 8 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 3 "register_operand" "w")]
+ UNSPEC_COND_FABS)]
+ SVE_COND_FP_ABS_CMP))]
"TARGET_SVE
- && !rtx_equal_p (operands[2], operands[4])
- && !rtx_equal_p (operands[3], operands[4])"
- "@
- movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
- movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- #"
- "&& reload_completed
- && register_operand (operands[4], <MODE>mode)
- && !rtx_equal_p (operands[0], operands[4])"
+ && aarch64_sve_pred_dominates_p (&operands[5], operands[1])
+ && aarch64_sve_pred_dominates_p (&operands[7], operands[1])"
+ "fac<cmp_op>\t%0.<Vetype>, %1/z, %2.<Vetype>, %3.<Vetype>"
+ "&& (!rtx_equal_p (operands[1], operands[5])
+ || !rtx_equal_p (operands[1], operands[7]))"
{
- emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
- operands[4], operands[1]));
- operands[4] = operands[2] = operands[0];
+ operands[5] = copy_rtx (operands[1]);
+ operands[7] = copy_rtx (operands[1]);
}
- [(set_attr "movprfx" "yes")]
)
-(define_insn_and_rewrite "*cond_<optab><mode>_any"
- [(set (match_operand:SVE_SDI 0 "register_operand" "=&w, &w, &w, &w, ?&w")
- (unspec:SVE_SDI
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
- (SVE_INT_BINARY_SD:SVE_SDI
- (match_operand:SVE_SDI 2 "register_operand" "0, w, w, w, w")
- (match_operand:SVE_SDI 3 "register_operand" "w, 0, w, w, w"))
- (match_operand:SVE_SDI 4 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, 0, w")]
- UNSPEC_SEL))]
- "TARGET_SVE
- && !rtx_equal_p (operands[2], operands[4])
- && !rtx_equal_p (operands[3], operands[4])"
- "@
- movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_int_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
- movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_int_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- #"
- "&& reload_completed
- && register_operand (operands[4], <MODE>mode)
- && !rtx_equal_p (operands[0], operands[4])"
+;; -------------------------------------------------------------------------
+;; ---- [PRED] Test bits
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - PTEST
+;; -------------------------------------------------------------------------
+
+;; Branch based on predicate equality or inequality.
+(define_expand "cbranch<mode>4"
+ [(set (pc)
+ (if_then_else
+ (match_operator 0 "aarch64_equality_operator"
+ [(match_operand:PRED_ALL 1 "register_operand")
+ (match_operand:PRED_ALL 2 "aarch64_simd_reg_or_zero")])
+ (label_ref (match_operand 3 ""))
+ (pc)))]
+ ""
{
- emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
- operands[4], operands[1]));
- operands[4] = operands[2] = operands[0];
+ rtx ptrue = force_reg (VNx16BImode, aarch64_ptrue_all (<data_bytes>));
+ rtx cast_ptrue = gen_lowpart (<MODE>mode, ptrue);
+ rtx ptrue_flag = gen_int_mode (SVE_KNOWN_PTRUE, SImode);
+ rtx pred;
+ if (operands[2] == CONST0_RTX (<MODE>mode))
+ pred = operands[1];
+ else
+ {
+ pred = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_aarch64_pred_xor<mode>_z (pred, cast_ptrue, operands[1],
+ operands[2]));
+ }
+ emit_insn (gen_aarch64_ptest<mode> (ptrue, cast_ptrue, ptrue_flag, pred));
+ operands[1] = gen_rtx_REG (CC_NZCmode, CC_REGNUM);
+ operands[2] = const0_rtx;
}
- [(set_attr "movprfx" "yes")]
)
+;; See "Description of UNSPEC_PTEST" above for details.
+(define_insn "aarch64_ptest<mode>"
+ [(set (reg:CC_NZC CC_REGNUM)
+ (unspec:CC_NZC [(match_operand:VNx16BI 0 "register_operand" "Upa")
+ (match_operand 1)
+ (match_operand:SI 2 "aarch64_sve_ptrue_flag")
+ (match_operand:PRED_ALL 3 "register_operand" "Upa")]
+ UNSPEC_PTEST))]
+ "TARGET_SVE"
+ "ptest\t%0, %3.b"
+)
+
+;; =========================================================================
+;; == Reductions
+;; =========================================================================
+
+;; -------------------------------------------------------------------------
+;; ---- [INT,FP] Conditional reductions
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - CLASTB
+;; -------------------------------------------------------------------------
+
;; Set operand 0 to the last active element in operand 3, or to tied
;; operand 1 if no elements are active.
(define_insn "fold_extract_last_<mode>"
- [(set (match_operand:<VEL> 0 "register_operand" "=r, w")
+ [(set (match_operand:<VEL> 0 "register_operand" "=?r, w")
(unspec:<VEL>
[(match_operand:<VEL> 1 "register_operand" "0, 0")
(match_operand:<VPRED> 2 "register_operand" "Upl, Upl")
@@ -2000,8 +4479,22 @@
"TARGET_SVE"
"@
clastb\t%<vwcore>0, %2, %<vwcore>0, %3.<Vetype>
- clastb\t%<vw>0, %2, %<vw>0, %3.<Vetype>"
-)
+ clastb\t%<Vetype>0, %2, %<Vetype>0, %3.<Vetype>"
+)
+
+;; -------------------------------------------------------------------------
+;; ---- [INT] Tree reductions
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - ANDV
+;; - EORV
+;; - ORV
+;; - SMAXV
+;; - SMINV
+;; - UADDV
+;; - UMAXV
+;; - UMINV
+;; -------------------------------------------------------------------------
;; Unpredicated integer add reduction.
(define_expand "reduc_plus_scal_<mode>"
@@ -2025,92 +4518,68 @@
"uaddv\t%d0, %1, %2.<Vetype>"
)
-;; Unpredicated floating-point add reduction.
-(define_expand "reduc_plus_scal_<mode>"
- [(set (match_operand:<VEL> 0 "register_operand")
- (unspec:<VEL> [(match_dup 2)
- (match_operand:SVE_F 1 "register_operand")]
- UNSPEC_FADDV))]
- "TARGET_SVE"
- {
- operands[2] = aarch64_ptrue_reg (<VPRED>mode);
- }
-)
-
-;; Predicated floating-point add reduction.
-(define_insn "*reduc_plus_scal_<mode>"
- [(set (match_operand:<VEL> 0 "register_operand" "=w")
- (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (match_operand:SVE_F 2 "register_operand" "w")]
- UNSPEC_FADDV))]
- "TARGET_SVE"
- "faddv\t%<Vetype>0, %1, %2.<Vetype>"
-)
-
-;; Unpredicated integer MIN/MAX reduction.
-(define_expand "reduc_<maxmin_uns>_scal_<mode>"
+;; Unpredicated integer reductions.
+(define_expand "reduc_<optab>_scal_<mode>"
[(set (match_operand:<VEL> 0 "register_operand")
(unspec:<VEL> [(match_dup 2)
(match_operand:SVE_I 1 "register_operand")]
- MAXMINV))]
+ SVE_INT_REDUCTION))]
"TARGET_SVE"
{
operands[2] = aarch64_ptrue_reg (<VPRED>mode);
}
)
-;; Predicated integer MIN/MAX reduction.
-(define_insn "*reduc_<maxmin_uns>_scal_<mode>"
+;; Predicated integer reductions.
+(define_insn "*reduc_<optab>_scal_<mode>"
[(set (match_operand:<VEL> 0 "register_operand" "=w")
(unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
(match_operand:SVE_I 2 "register_operand" "w")]
- MAXMINV))]
+ SVE_INT_REDUCTION))]
"TARGET_SVE"
- "<maxmin_uns_op>v\t%<Vetype>0, %1, %2.<Vetype>"
+ "<sve_int_op>\t%<Vetype>0, %1, %2.<Vetype>"
)
-;; Unpredicated floating-point MIN/MAX reduction.
-(define_expand "reduc_<maxmin_uns>_scal_<mode>"
- [(set (match_operand:<VEL> 0 "register_operand")
- (unspec:<VEL> [(match_dup 2)
- (match_operand:SVE_F 1 "register_operand")]
- FMAXMINV))]
- "TARGET_SVE"
- {
- operands[2] = aarch64_ptrue_reg (<VPRED>mode);
- }
-)
-
-;; Predicated floating-point MIN/MAX reduction.
-(define_insn "*reduc_<maxmin_uns>_scal_<mode>"
- [(set (match_operand:<VEL> 0 "register_operand" "=w")
- (unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (match_operand:SVE_F 2 "register_operand" "w")]
- FMAXMINV))]
- "TARGET_SVE"
- "<maxmin_uns_op>v\t%<Vetype>0, %1, %2.<Vetype>"
-)
+;; -------------------------------------------------------------------------
+;; ---- [FP] Tree reductions
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - FADDV
+;; - FMAXNMV
+;; - FMAXV
+;; - FMINNMV
+;; - FMINV
+;; -------------------------------------------------------------------------
+;; Unpredicated floating-point tree reductions.
(define_expand "reduc_<optab>_scal_<mode>"
[(set (match_operand:<VEL> 0 "register_operand")
(unspec:<VEL> [(match_dup 2)
- (match_operand:SVE_I 1 "register_operand")]
- BITWISEV))]
+ (match_operand:SVE_F 1 "register_operand")]
+ SVE_FP_REDUCTION))]
"TARGET_SVE"
{
operands[2] = aarch64_ptrue_reg (<VPRED>mode);
}
)
+;; Predicated floating-point tree reductions.
(define_insn "*reduc_<optab>_scal_<mode>"
[(set (match_operand:<VEL> 0 "register_operand" "=w")
(unspec:<VEL> [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (match_operand:SVE_I 2 "register_operand" "w")]
- BITWISEV))]
+ (match_operand:SVE_F 2 "register_operand" "w")]
+ SVE_FP_REDUCTION))]
"TARGET_SVE"
- "<bit_reduc_op>\t%<Vetype>0, %1, %2.<Vetype>"
+ "<sve_fp_op>\t%<Vetype>0, %1, %2.<Vetype>"
)
+;; -------------------------------------------------------------------------
+;; ---- [FP] Left-to-right reductions
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - FADDA
+;; -------------------------------------------------------------------------
+
;; Unpredicated in-order FP reductions.
(define_expand "fold_left_plus_<mode>"
[(set (match_operand:<VEL> 0 "register_operand")
@@ -2124,7 +4593,7 @@
}
)
-;; In-order FP reductions predicated with PTRUE.
+;; Predicated in-order FP reductions.
(define_insn "mask_fold_left_plus_<mode>"
[(set (match_operand:<VEL> 0 "register_operand" "=w")
(unspec:<VEL> [(match_operand:<VPRED> 3 "register_operand" "Upl")
@@ -2135,422 +4604,313 @@
"fadda\t%<Vetype>0, %3, %<Vetype>0, %2.<Vetype>"
)
-;; Predicated form of the above in-order reduction.
-(define_insn "*pred_fold_left_plus_<mode>"
- [(set (match_operand:<VEL> 0 "register_operand" "=w")
- (unspec:<VEL>
- [(match_operand:<VEL> 1 "register_operand" "0")
- (unspec:SVE_F
- [(match_operand:<VPRED> 2 "register_operand" "Upl")
- (match_operand:SVE_F 3 "register_operand" "w")
- (match_operand:SVE_F 4 "aarch64_simd_imm_zero")]
- UNSPEC_SEL)]
- UNSPEC_FADDA))]
- "TARGET_SVE"
- "fadda\t%<Vetype>0, %2, %<Vetype>0, %3.<Vetype>"
-)
+;; =========================================================================
+;; == Permutes
+;; =========================================================================
-;; Unpredicated floating-point addition.
-(define_expand "add<mode>3"
- [(set (match_operand:SVE_F 0 "register_operand")
- (unspec:SVE_F
- [(match_dup 3)
- (plus:SVE_F
- (match_operand:SVE_F 1 "register_operand")
- (match_operand:SVE_F 2 "aarch64_sve_float_arith_with_sub_operand"))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
+;; -------------------------------------------------------------------------
+;; ---- [INT,FP] General permutes
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - TBL
+;; -------------------------------------------------------------------------
+
+(define_expand "vec_perm<mode>"
+ [(match_operand:SVE_ALL 0 "register_operand")
+ (match_operand:SVE_ALL 1 "register_operand")
+ (match_operand:SVE_ALL 2 "register_operand")
+ (match_operand:<V_INT_EQUIV> 3 "aarch64_sve_vec_perm_operand")]
+ "TARGET_SVE && GET_MODE_NUNITS (<MODE>mode).is_constant ()"
{
- operands[3] = aarch64_ptrue_reg (<VPRED>mode);
+ aarch64_expand_sve_vec_perm (operands[0], operands[1],
+ operands[2], operands[3]);
+ DONE;
}
)
-;; Floating-point addition predicated with a PTRUE.
-(define_insn_and_split "*add<mode>3"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, w, w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
- (plus:SVE_F
- (match_operand:SVE_F 2 "register_operand" "%0, 0, w")
- (match_operand:SVE_F 3 "aarch64_sve_float_arith_with_sub_operand" "vsA, vsN, w"))]
- UNSPEC_MERGE_PTRUE))]
+(define_insn "*aarch64_sve_tbl<mode>"
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
+ (unspec:SVE_ALL
+ [(match_operand:SVE_ALL 1 "register_operand" "w")
+ (match_operand:<V_INT_EQUIV> 2 "register_operand" "w")]
+ UNSPEC_TBL))]
"TARGET_SVE"
- "@
- fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
- fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
- #"
- ; Split the unpredicated form after reload, so that we don't have
- ; the unnecessary PTRUE.
- "&& reload_completed
- && register_operand (operands[3], <MODE>mode)"
- [(set (match_dup 0) (plus:SVE_F (match_dup 2) (match_dup 3)))]
+ "tbl\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
)
-;; Unpredicated floating-point subtraction.
-(define_expand "sub<mode>3"
- [(set (match_operand:SVE_F 0 "register_operand")
- (unspec:SVE_F
- [(match_dup 3)
- (minus:SVE_F
- (match_operand:SVE_F 1 "aarch64_sve_float_arith_operand")
- (match_operand:SVE_F 2 "register_operand"))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- {
- operands[3] = aarch64_ptrue_reg (<VPRED>mode);
- }
-)
+;; -------------------------------------------------------------------------
+;; ---- [INT,FP] Special-purpose unary permutes
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - DUP
+;; - REV
+;; -------------------------------------------------------------------------
-;; Floating-point subtraction predicated with a PTRUE.
-(define_insn_and_split "*sub<mode>3"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, w, w, w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl")
- (minus:SVE_F
- (match_operand:SVE_F 2 "aarch64_sve_float_arith_operand" "0, 0, vsA, w")
- (match_operand:SVE_F 3 "aarch64_sve_float_arith_with_sub_operand" "vsA, vsN, 0, w"))]
- UNSPEC_MERGE_PTRUE))]
+;; Duplicate one element of a vector.
+(define_insn "*aarch64_sve_dup_lane<mode>"
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
+ (vec_duplicate:SVE_ALL
+ (vec_select:<VEL>
+ (match_operand:SVE_ALL 1 "register_operand" "w")
+ (parallel [(match_operand:SI 2 "const_int_operand")]))))]
"TARGET_SVE
- && (register_operand (operands[2], <MODE>mode)
- || register_operand (operands[3], <MODE>mode))"
- "@
- fsub\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
- fadd\t%0.<Vetype>, %1/m, %0.<Vetype>, #%N3
- fsubr\t%0.<Vetype>, %1/m, %0.<Vetype>, #%2
- #"
- ; Split the unpredicated form after reload, so that we don't have
- ; the unnecessary PTRUE.
- "&& reload_completed
- && register_operand (operands[2], <MODE>mode)
- && register_operand (operands[3], <MODE>mode)"
- [(set (match_dup 0) (minus:SVE_F (match_dup 2) (match_dup 3)))]
+ && IN_RANGE (INTVAL (operands[2]) * GET_MODE_SIZE (<VEL>mode), 0, 63)"
+ "dup\t%0.<Vetype>, %1.<Vetype>[%2]"
)
-;; Unpredicated floating-point multiplication.
-(define_expand "mul<mode>3"
- [(set (match_operand:SVE_F 0 "register_operand")
- (unspec:SVE_F
- [(match_dup 3)
- (mult:SVE_F
- (match_operand:SVE_F 1 "register_operand")
- (match_operand:SVE_F 2 "aarch64_sve_float_mul_operand"))]
- UNSPEC_MERGE_PTRUE))]
+;; Reverse the order of elements within a full vector.
+(define_insn "@aarch64_sve_rev<mode>"
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
+ (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "w")]
+ UNSPEC_REV))]
"TARGET_SVE"
- {
- operands[3] = aarch64_ptrue_reg (<VPRED>mode);
- }
-)
+ "rev\t%0.<Vetype>, %1.<Vetype>")
-;; Floating-point multiplication predicated with a PTRUE.
-(define_insn_and_split "*mul<mode>3"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (mult:SVE_F
- (match_operand:SVE_F 2 "register_operand" "%0, w")
- (match_operand:SVE_F 3 "aarch64_sve_float_mul_operand" "vsM, w"))]
- UNSPEC_MERGE_PTRUE))]
+;; -------------------------------------------------------------------------
+;; ---- [INT,FP] Special-purpose binary permutes
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - TRN1
+;; - TRN2
+;; - UZP1
+;; - UZP2
+;; - ZIP1
+;; - ZIP2
+;; -------------------------------------------------------------------------
+
+;; Permutes that take half the elements from one vector and half the
+;; elements from the other.
+(define_insn "aarch64_sve_<perm_insn><mode>"
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=w")
+ (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "w")
+ (match_operand:SVE_ALL 2 "register_operand" "w")]
+ PERMUTE))]
"TARGET_SVE"
- "@
- fmul\t%0.<Vetype>, %1/m, %0.<Vetype>, #%3
- #"
- ; Split the unpredicated form after reload, so that we don't have
- ; the unnecessary PTRUE.
- "&& reload_completed
- && register_operand (operands[3], <MODE>mode)"
- [(set (match_dup 0) (mult:SVE_F (match_dup 2) (match_dup 3)))]
+ "<perm_insn>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
)
-;; Unpredicated floating-point binary operations (post-RA only).
-;; These are generated by splitting a predicated instruction whose
-;; predicate is unused.
-(define_insn "*post_ra_<sve_fp_op><mode>3"
- [(set (match_operand:SVE_F 0 "register_operand" "=w")
- (SVE_UNPRED_FP_BINARY:SVE_F
- (match_operand:SVE_F 1 "register_operand" "w")
- (match_operand:SVE_F 2 "register_operand" "w")))]
- "TARGET_SVE && reload_completed"
- "<sve_fp_op>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>")
-
-;; Unpredicated fma (%0 = (%1 * %2) + %3).
-(define_expand "fma<mode>4"
- [(set (match_operand:SVE_F 0 "register_operand")
- (unspec:SVE_F
- [(match_dup 4)
- (fma:SVE_F (match_operand:SVE_F 1 "register_operand")
- (match_operand:SVE_F 2 "register_operand")
- (match_operand:SVE_F 3 "register_operand"))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
+;; Concatenate two vectors and extract a subvector. Note that the
+;; immediate (third) operand is the lane index not the byte index.
+(define_insn "*aarch64_sve_ext<mode>"
+ [(set (match_operand:SVE_ALL 0 "register_operand" "=w, ?&w")
+ (unspec:SVE_ALL [(match_operand:SVE_ALL 1 "register_operand" "0, w")
+ (match_operand:SVE_ALL 2 "register_operand" "w, w")
+ (match_operand:SI 3 "const_int_operand")]
+ UNSPEC_EXT))]
+ "TARGET_SVE
+ && IN_RANGE (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode), 0, 255)"
{
- operands[4] = aarch64_ptrue_reg (<VPRED>mode);
+ operands[3] = GEN_INT (INTVAL (operands[3]) * GET_MODE_SIZE (<VEL>mode));
+ return (which_alternative == 0
+ ? "ext\\t%0.b, %0.b, %2.b, #%3"
+ : "movprfx\t%0, %1\;ext\\t%0.b, %0.b, %2.b, #%3");
}
+ [(set_attr "movprfx" "*,yes")]
)
-;; fma predicated with a PTRUE.
-(define_insn "*fma<mode>4"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
- (fma:SVE_F (match_operand:SVE_F 3 "register_operand" "%0, w, w")
- (match_operand:SVE_F 4 "register_operand" "w, w, w")
- (match_operand:SVE_F 2 "register_operand" "w, 0, w"))]
- UNSPEC_MERGE_PTRUE))]
+;; -------------------------------------------------------------------------
+;; ---- [PRED] Special-purpose binary permutes
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - TRN1
+;; - TRN2
+;; - UZP1
+;; - UZP2
+;; - ZIP1
+;; - ZIP2
+;; -------------------------------------------------------------------------
+
+;; Permutes that take half the elements from one vector and half the
+;; elements from the other.
+(define_insn "@aarch64_sve_<perm_insn><mode>"
+ [(set (match_operand:PRED_ALL 0 "register_operand" "=Upa")
+ (unspec:PRED_ALL [(match_operand:PRED_ALL 1 "register_operand" "Upa")
+ (match_operand:PRED_ALL 2 "register_operand" "Upa")]
+ PERMUTE))]
"TARGET_SVE"
- "@
- fmad\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
- fmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
- movprfx\t%0, %2\;fmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
- [(set_attr "movprfx" "*,*,yes")]
+ "<perm_insn>\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
)
-;; Unpredicated fnma (%0 = (-%1 * %2) + %3).
-(define_expand "fnma<mode>4"
- [(set (match_operand:SVE_F 0 "register_operand")
- (unspec:SVE_F
- [(match_dup 4)
- (fma:SVE_F (neg:SVE_F
- (match_operand:SVE_F 1 "register_operand"))
- (match_operand:SVE_F 2 "register_operand")
- (match_operand:SVE_F 3 "register_operand"))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- {
- operands[4] = aarch64_ptrue_reg (<VPRED>mode);
- }
-)
+;; =========================================================================
+;; == Conversions
+;; =========================================================================
-;; fnma predicated with a PTRUE.
-(define_insn "*fnma<mode>4"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
- (fma:SVE_F (neg:SVE_F
- (match_operand:SVE_F 3 "register_operand" "%0, w, w"))
- (match_operand:SVE_F 4 "register_operand" "w, w, w")
- (match_operand:SVE_F 2 "register_operand" "w, 0, w"))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "@
- fmsb\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
- fmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
- movprfx\t%0, %2\;fmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
- [(set_attr "movprfx" "*,*,yes")]
-)
+;; -------------------------------------------------------------------------
+;; ---- [INT<-INT] Packs
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - UZP1
+;; -------------------------------------------------------------------------
-;; Unpredicated fms (%0 = (%1 * %2) - %3).
-(define_expand "fms<mode>4"
- [(set (match_operand:SVE_F 0 "register_operand")
- (unspec:SVE_F
- [(match_dup 4)
- (fma:SVE_F (match_operand:SVE_F 1 "register_operand")
- (match_operand:SVE_F 2 "register_operand")
- (neg:SVE_F
- (match_operand:SVE_F 3 "register_operand")))]
- UNSPEC_MERGE_PTRUE))]
+;; Integer pack. Use UZP1 on the narrower type, which discards
+;; the high part of each wide element.
+(define_insn "vec_pack_trunc_<Vwide>"
+ [(set (match_operand:SVE_BHSI 0 "register_operand" "=w")
+ (unspec:SVE_BHSI
+ [(match_operand:<VWIDE> 1 "register_operand" "w")
+ (match_operand:<VWIDE> 2 "register_operand" "w")]
+ UNSPEC_PACK))]
"TARGET_SVE"
- {
- operands[4] = aarch64_ptrue_reg (<VPRED>mode);
- }
+ "uzp1\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
)
-;; fms predicated with a PTRUE.
-(define_insn "*fms<mode>4"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
- (fma:SVE_F (match_operand:SVE_F 3 "register_operand" "%0, w, w")
- (match_operand:SVE_F 4 "register_operand" "w, w, w")
- (neg:SVE_F
- (match_operand:SVE_F 2 "register_operand" "w, 0, w")))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "@
- fnmsb\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
- fnmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
- movprfx\t%0, %2\;fnmls\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
- [(set_attr "movprfx" "*,*,yes")]
-)
+;; -------------------------------------------------------------------------
+;; ---- [INT<-INT] Unpacks
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - SUNPKHI
+;; - SUNPKLO
+;; - UUNPKHI
+;; - UUNPKLO
+;; -------------------------------------------------------------------------
-;; Unpredicated fnms (%0 = (-%1 * %2) - %3).
-(define_expand "fnms<mode>4"
- [(set (match_operand:SVE_F 0 "register_operand")
- (unspec:SVE_F
- [(match_dup 4)
- (fma:SVE_F (neg:SVE_F
- (match_operand:SVE_F 1 "register_operand"))
- (match_operand:SVE_F 2 "register_operand")
- (neg:SVE_F
- (match_operand:SVE_F 3 "register_operand")))]
- UNSPEC_MERGE_PTRUE))]
+;; Unpack the low or high half of a vector, where "high" refers to
+;; the low-numbered lanes for big-endian and the high-numbered lanes
+;; for little-endian.
+(define_expand "vec_unpack<su>_<perm_hilo>_<SVE_BHSI:mode>"
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (unspec:<VWIDE> [(match_operand:SVE_BHSI 1 "register_operand")] UNPACK)]
"TARGET_SVE"
{
- operands[4] = aarch64_ptrue_reg (<VPRED>mode);
+ emit_insn ((<hi_lanes_optab>
+ ? gen_aarch64_sve_<su>unpkhi_<SVE_BHSI:mode>
+ : gen_aarch64_sve_<su>unpklo_<SVE_BHSI:mode>)
+ (operands[0], operands[1]));
+ DONE;
}
)
-;; fnms predicated with a PTRUE.
-(define_insn "*fnms<mode>4"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
- (fma:SVE_F (neg:SVE_F
- (match_operand:SVE_F 3 "register_operand" "%0, w, w"))
- (match_operand:SVE_F 4 "register_operand" "w, w, w")
- (neg:SVE_F
- (match_operand:SVE_F 2 "register_operand" "w, 0, w")))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "@
- fnmad\t%0.<Vetype>, %1/m, %4.<Vetype>, %2.<Vetype>
- fnmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
- movprfx\t%0, %2\;fnmla\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
- [(set_attr "movprfx" "*,*,yes")]
-)
-
-;; Unpredicated floating-point division.
-(define_expand "div<mode>3"
- [(set (match_operand:SVE_F 0 "register_operand")
- (unspec:SVE_F
- [(match_dup 3)
- (div:SVE_F (match_operand:SVE_F 1 "register_operand")
- (match_operand:SVE_F 2 "register_operand"))]
- UNSPEC_MERGE_PTRUE))]
+(define_insn "aarch64_sve_<su>unpk<perm_hilo>_<SVE_BHSI:mode>"
+ [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
+ (unspec:<VWIDE> [(match_operand:SVE_BHSI 1 "register_operand" "w")]
+ UNPACK))]
"TARGET_SVE"
- {
- operands[3] = aarch64_ptrue_reg (<VPRED>mode);
- }
+ "<su>unpk<perm_hilo>\t%0.<Vewtype>, %1.<Vetype>"
)
-;; Floating-point division predicated with a PTRUE.
-(define_insn "*div<mode>3"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, w, ?&w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
- (div:SVE_F (match_operand:SVE_F 2 "register_operand" "0, w, w")
- (match_operand:SVE_F 3 "register_operand" "w, 0, w"))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "@
- fdiv\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- fdivr\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
- movprfx\t%0, %2\;fdiv\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
- [(set_attr "movprfx" "*,*,yes")]
-)
+;; -------------------------------------------------------------------------
+;; ---- [INT<-FP] Conversions
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - FCVTZS
+;; - FCVTZU
+;; -------------------------------------------------------------------------
-;; Unpredicated FNEG, FABS and FSQRT.
-(define_expand "<optab><mode>2"
- [(set (match_operand:SVE_F 0 "register_operand")
- (unspec:SVE_F
+;; Unpredicated conversion of floats to integers of the same size (HF to HI,
+;; SF to SI or DF to DI).
+(define_expand "<optab><mode><v_int_equiv>2"
+ [(set (match_operand:<V_INT_EQUIV> 0 "register_operand")
+ (unspec:<V_INT_EQUIV>
[(match_dup 2)
- (SVE_FP_UNARY:SVE_F (match_operand:SVE_F 1 "register_operand"))]
- UNSPEC_MERGE_PTRUE))]
+ (const_int SVE_RELAXED_GP)
+ (match_operand:SVE_F 1 "register_operand")]
+ SVE_COND_FCVTI))]
"TARGET_SVE"
{
operands[2] = aarch64_ptrue_reg (<VPRED>mode);
}
)
-;; FNEG, FABS and FSQRT predicated with a PTRUE.
-(define_insn "*<optab><mode>2"
- [(set (match_operand:SVE_F 0 "register_operand" "=w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (SVE_FP_UNARY:SVE_F (match_operand:SVE_F 2 "register_operand" "w"))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "<sve_fp_op>\t%0.<Vetype>, %1/m, %2.<Vetype>"
-)
-
-(define_insn "*fabd<mode>3"
- [(set (match_operand:SVE_F 0 "register_operand" "=w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (abs:SVE_F
- (minus:SVE_F
- (match_operand:SVE_F 2 "register_operand" "0")
- (match_operand:SVE_F 3 "register_operand" "w")))]
- UNSPEC_MERGE_PTRUE))]
+;; Predicated float-to-integer conversion, either to the same width or wider.
+(define_insn "*aarch64_sve_<optab>_nontrunc<SVE_F:mode><SVE_HSDI:mode>"
+ [(set (match_operand:SVE_HSDI 0 "register_operand" "=w")
+ (unspec:SVE_HSDI
+ [(match_operand:<SVE_HSDI:VPRED> 1 "register_operand" "Upl")
+ (match_operand:SI 3 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "w")]
+ SVE_COND_FCVTI))]
+ "TARGET_SVE && <SVE_HSDI:elem_bits> >= <SVE_F:elem_bits>"
+ "fcvtz<su>\t%0.<SVE_HSDI:Vetype>, %1/m, %2.<SVE_F:Vetype>"
+)
+
+;; Predicated narrowing float-to-integer conversion.
+(define_insn "*aarch64_sve_<optab>_trunc<VNx2DF_ONLY:mode><VNx4SI_ONLY:mode>"
+ [(set (match_operand:VNx4SI_ONLY 0 "register_operand" "=w")
+ (unspec:VNx4SI_ONLY
+ [(match_operand:VNx2BI 1 "register_operand" "Upl")
+ (match_operand:SI 3 "aarch64_sve_gp_strictness")
+ (match_operand:VNx2DF_ONLY 2 "register_operand" "w")]
+ SVE_COND_FCVTI))]
"TARGET_SVE"
- "fabd\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
+ "fcvtz<su>\t%0.<VNx4SI_ONLY:Vetype>, %1/m, %2.<VNx2DF_ONLY:Vetype>"
)
-;; Unpredicated FRINTy.
-(define_expand "<frint_pattern><mode>2"
- [(set (match_operand:SVE_F 0 "register_operand")
- (unspec:SVE_F
- [(match_dup 2)
- (unspec:SVE_F [(match_operand:SVE_F 1 "register_operand")]
- FRINT)]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
+;; Predicated float-to-integer conversion with merging, either to the same
+;; width or wider.
+;;
+;; The first alternative doesn't need the earlyclobber, but the only case
+;; it would help is the uninteresting one in which operands 2 and 3 are
+;; the same register (despite having different modes). Making all the
+;; alternatives earlyclobber makes things more consistent for the
+;; register allocator.
+(define_insn_and_rewrite "*cond_<optab>_nontrunc<SVE_F:mode><SVE_HSDI:mode>"
+ [(set (match_operand:SVE_HSDI 0 "register_operand" "=&w, &w, ?&w")
+ (unspec:SVE_HSDI
+ [(match_operand:<SVE_HSDI:VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (unspec:SVE_HSDI
+ [(match_operand 4)
+ (match_operand:SI 5 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_F 2 "register_operand" "w, w, w")]
+ SVE_COND_FCVTI)
+ (match_operand:SVE_HSDI 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && <SVE_HSDI:elem_bits> >= <SVE_F:elem_bits>
+ && aarch64_sve_pred_dominates_p (&operands[4], operands[1])"
+ "@
+ fcvtz<su>\t%0.<SVE_HSDI:Vetype>, %1/m, %2.<SVE_F:Vetype>
+ movprfx\t%0.<SVE_HSDI:Vetype>, %1/z, %2.<SVE_HSDI:Vetype>\;fcvtz<su>\t%0.<SVE_HSDI:Vetype>, %1/m, %2.<SVE_F:Vetype>
+ movprfx\t%0, %3\;fcvtz<su>\t%0.<SVE_HSDI:Vetype>, %1/m, %2.<SVE_F:Vetype>"
+ "&& !rtx_equal_p (operands[1], operands[4])"
{
- operands[2] = aarch64_ptrue_reg (<VPRED>mode);
+ operands[4] = copy_rtx (operands[1]);
}
+ [(set_attr "movprfx" "*,yes,yes")]
)
-;; FRINTy predicated with a PTRUE.
-(define_insn "*<frint_pattern><mode>2"
- [(set (match_operand:SVE_F 0 "register_operand" "=w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (unspec:SVE_F [(match_operand:SVE_F 2 "register_operand" "w")]
- FRINT)]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "frint<frint_suffix>\t%0.<Vetype>, %1/m, %2.<Vetype>"
-)
+;; -------------------------------------------------------------------------
+;; ---- [INT<-FP] Packs
+;; -------------------------------------------------------------------------
+;; The patterns in this section are synthetic.
+;; -------------------------------------------------------------------------
-;; Unpredicated conversion of floats to integers of the same size (HF to HI,
-;; SF to SI or DF to DI).
-(define_expand "<fix_trunc_optab><mode><v_int_equiv>2"
- [(set (match_operand:<V_INT_EQUIV> 0 "register_operand")
- (unspec:<V_INT_EQUIV>
- [(match_dup 2)
- (FIXUORS:<V_INT_EQUIV>
- (match_operand:SVE_F 1 "register_operand"))]
- UNSPEC_MERGE_PTRUE))]
+;; Convert two vectors of DF to SI and pack the results into a single vector.
+(define_expand "vec_pack_<su>fix_trunc_vnx2df"
+ [(set (match_dup 4)
+ (unspec:VNx4SI
+ [(match_dup 3)
+ (const_int SVE_RELAXED_GP)
+ (match_operand:VNx2DF 1 "register_operand")]
+ SVE_COND_FCVTI))
+ (set (match_dup 5)
+ (unspec:VNx4SI
+ [(match_dup 3)
+ (const_int SVE_RELAXED_GP)
+ (match_operand:VNx2DF 2 "register_operand")]
+ SVE_COND_FCVTI))
+ (set (match_operand:VNx4SI 0 "register_operand")
+ (unspec:VNx4SI [(match_dup 4) (match_dup 5)] UNSPEC_UZP1))]
"TARGET_SVE"
{
- operands[2] = aarch64_ptrue_reg (<VPRED>mode);
+ operands[3] = aarch64_ptrue_reg (VNx2BImode);
+ operands[4] = gen_reg_rtx (VNx4SImode);
+ operands[5] = gen_reg_rtx (VNx4SImode);
}
)
-;; Conversion of SF to DI, SI or HI, predicated with a PTRUE.
-(define_insn "*<fix_trunc_optab>v16hsf<mode>2"
- [(set (match_operand:SVE_HSDI 0 "register_operand" "=w")
- (unspec:SVE_HSDI
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (FIXUORS:SVE_HSDI
- (match_operand:VNx8HF 2 "register_operand" "w"))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "fcvtz<su>\t%0.<Vetype>, %1/m, %2.h"
-)
-
-;; Conversion of SF to DI or SI, predicated with a PTRUE.
-(define_insn "*<fix_trunc_optab>vnx4sf<mode>2"
- [(set (match_operand:SVE_SDI 0 "register_operand" "=w")
- (unspec:SVE_SDI
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (FIXUORS:SVE_SDI
- (match_operand:VNx4SF 2 "register_operand" "w"))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "fcvtz<su>\t%0.<Vetype>, %1/m, %2.s"
-)
+;; -------------------------------------------------------------------------
+;; ---- [INT<-FP] Unpacks
+;; -------------------------------------------------------------------------
+;; No patterns here yet!
+;; -------------------------------------------------------------------------
-;; Conversion of DF to DI or SI, predicated with a PTRUE.
-(define_insn "*<fix_trunc_optab>vnx2df<mode>2"
- [(set (match_operand:SVE_SDI 0 "register_operand" "=w")
- (unspec:SVE_SDI
- [(match_operand:VNx2BI 1 "register_operand" "Upl")
- (FIXUORS:SVE_SDI
- (match_operand:VNx2DF 2 "register_operand" "w"))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "fcvtz<su>\t%0.<Vetype>, %1/m, %2.d"
-)
+;; -------------------------------------------------------------------------
+;; ---- [FP<-INT] Conversions
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - SCVTF
+;; - UCVTF
+;; -------------------------------------------------------------------------
;; Unpredicated conversion of integers to floats of the same size
;; (HI to HF, SI to SF or DI to DF).
@@ -2558,155 +4918,84 @@
[(set (match_operand:SVE_F 0 "register_operand")
(unspec:SVE_F
[(match_dup 2)
- (FLOATUORS:SVE_F
- (match_operand:<V_INT_EQUIV> 1 "register_operand"))]
- UNSPEC_MERGE_PTRUE))]
+ (const_int SVE_RELAXED_GP)
+ (match_operand:<V_INT_EQUIV> 1 "register_operand")]
+ SVE_COND_ICVTF))]
"TARGET_SVE"
{
operands[2] = aarch64_ptrue_reg (<VPRED>mode);
}
)
-;; Conversion of DI, SI or HI to the same number of HFs, predicated
-;; with a PTRUE.
-(define_insn "*<optab><mode>vnx8hf2"
- [(set (match_operand:VNx8HF 0 "register_operand" "=w")
- (unspec:VNx8HF
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (FLOATUORS:VNx8HF
- (match_operand:SVE_HSDI 2 "register_operand" "w"))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "<su_optab>cvtf\t%0.h, %1/m, %2.<Vetype>"
-)
-
-;; Conversion of DI or SI to the same number of SFs, predicated with a PTRUE.
-(define_insn "*<optab><mode>vnx4sf2"
- [(set (match_operand:VNx4SF 0 "register_operand" "=w")
- (unspec:VNx4SF
- [(match_operand:<VPRED> 1 "register_operand" "Upl")
- (FLOATUORS:VNx4SF
- (match_operand:SVE_SDI 2 "register_operand" "w"))]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "<su_optab>cvtf\t%0.s, %1/m, %2.<Vetype>"
-)
-
-;; Conversion of DI or SI to DF, predicated with a PTRUE.
-(define_insn "aarch64_sve_<optab><mode>vnx2df2"
- [(set (match_operand:VNx2DF 0 "register_operand" "=w")
- (unspec:VNx2DF
+;; Predicated integer-to-float conversion, either to the same width or
+;; narrower.
+(define_insn "*aarch64_sve_<optab>_nonextend<SVE_HSDI:mode><SVE_F:mode>"
+ [(set (match_operand:SVE_F 0 "register_operand" "=w")
+ (unspec:SVE_F
+ [(match_operand:<SVE_HSDI:VPRED> 1 "register_operand" "Upl")
+ (match_operand:SI 3 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_HSDI 2 "register_operand" "w")]
+ SVE_COND_ICVTF))]
+ "TARGET_SVE && <SVE_HSDI:elem_bits> >= <SVE_F:elem_bits>"
+ "<su>cvtf\t%0.<SVE_F:Vetype>, %1/m, %2.<SVE_HSDI:Vetype>"
+)
+
+;; Predicated widening integer-to-float conversion.
+(define_insn "aarch64_sve_<optab>_extend<VNx4SI_ONLY:mode><VNx2DF_ONLY:mode>"
+ [(set (match_operand:VNx2DF_ONLY 0 "register_operand" "=w")
+ (unspec:VNx2DF_ONLY
[(match_operand:VNx2BI 1 "register_operand" "Upl")
- (FLOATUORS:VNx2DF
- (match_operand:SVE_SDI 2 "register_operand" "w"))]
- UNSPEC_MERGE_PTRUE))]
+ (match_operand:SI 3 "aarch64_sve_gp_strictness")
+ (match_operand:VNx4SI_ONLY 2 "register_operand" "w")]
+ SVE_COND_ICVTF))]
"TARGET_SVE"
- "<su_optab>cvtf\t%0.d, %1/m, %2.<Vetype>"
+ "<su>cvtf\t%0.<VNx2DF_ONLY:Vetype>, %1/m, %2.<VNx4SI_ONLY:Vetype>"
)
-;; Conversion of DFs to the same number of SFs, or SFs to the same number
-;; of HFs.
-(define_insn "*trunc<Vwide><mode>2"
- [(set (match_operand:SVE_HSF 0 "register_operand" "=w")
- (unspec:SVE_HSF
- [(match_operand:<VWIDE_PRED> 1 "register_operand" "Upl")
- (unspec:SVE_HSF
- [(match_operand:<VWIDE> 2 "register_operand" "w")]
- UNSPEC_FLOAT_CONVERT)]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "fcvt\t%0.<Vetype>, %1/m, %2.<Vewtype>"
-)
-
-;; Conversion of SFs to the same number of DFs, or HFs to the same number
-;; of SFs.
-(define_insn "aarch64_sve_extend<mode><Vwide>2"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (unspec:<VWIDE>
- [(match_operand:<VWIDE_PRED> 1 "register_operand" "Upl")
- (unspec:<VWIDE>
- [(match_operand:SVE_HSF 2 "register_operand" "w")]
- UNSPEC_FLOAT_CONVERT)]
- UNSPEC_MERGE_PTRUE))]
- "TARGET_SVE"
- "fcvt\t%0.<Vewtype>, %1/m, %2.<Vetype>"
-)
-
-;; Unpack the low or high half of a predicate, where "high" refers to
-;; the low-numbered lanes for big-endian and the high-numbered lanes
-;; for little-endian.
-(define_expand "vec_unpack<su>_<perm_hilo>_<mode>"
- [(match_operand:<VWIDE> 0 "register_operand")
- (unspec:<VWIDE> [(match_operand:PRED_BHS 1 "register_operand")]
- UNPACK)]
- "TARGET_SVE"
- {
- emit_insn ((<hi_lanes_optab>
- ? gen_aarch64_sve_punpkhi_<PRED_BHS:mode>
- : gen_aarch64_sve_punpklo_<PRED_BHS:mode>)
- (operands[0], operands[1]));
- DONE;
- }
-)
-
-;; PUNPKHI and PUNPKLO.
-(define_insn "aarch64_sve_punpk<perm_hilo>_<mode>"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=Upa")
- (unspec:<VWIDE> [(match_operand:PRED_BHS 1 "register_operand" "Upa")]
- UNPACK_UNSIGNED))]
- "TARGET_SVE"
- "punpk<perm_hilo>\t%0.h, %1.b"
-)
-
-;; Unpack the low or high half of a vector, where "high" refers to
-;; the low-numbered lanes for big-endian and the high-numbered lanes
-;; for little-endian.
-(define_expand "vec_unpack<su>_<perm_hilo>_<SVE_BHSI:mode>"
- [(match_operand:<VWIDE> 0 "register_operand")
- (unspec:<VWIDE> [(match_operand:SVE_BHSI 1 "register_operand")] UNPACK)]
- "TARGET_SVE"
+;; Predicated integer-to-float conversion with merging, either to the same
+;; width or narrower.
+;;
+;; The first alternative doesn't need the earlyclobber, but the only case
+;; it would help is the uninteresting one in which operands 2 and 3 are
+;; the same register (despite having different modes). Making all the
+;; alternatives earlyclobber makes things more consistent for the
+;; register allocator.
+(define_insn_and_rewrite "*cond_<optab>_nonextend<SVE_HSDI:mode><SVE_F:mode>"
+ [(set (match_operand:SVE_F 0 "register_operand" "=&w, &w, ?&w")
+ (unspec:SVE_F
+ [(match_operand:<SVE_HSDI:VPRED> 1 "register_operand" "Upl, Upl, Upl")
+ (unspec:SVE_F
+ [(match_operand 4)
+ (match_operand:SI 5 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_HSDI 2 "register_operand" "w, w, w")]
+ SVE_COND_ICVTF)
+ (match_operand:SVE_F 3 "aarch64_simd_reg_or_zero" "0, Dz, w")]
+ UNSPEC_SEL))]
+ "TARGET_SVE
+ && <SVE_HSDI:elem_bits> >= <SVE_F:elem_bits>
+ && aarch64_sve_pred_dominates_p (&operands[4], operands[1])"
+ "@
+ <su>cvtf\t%0.<SVE_F:Vetype>, %1/m, %2.<SVE_HSDI:Vetype>
+ movprfx\t%0.<SVE_HSDI:Vetype>, %1/z, %2.<SVE_HSDI:Vetype>\;<su>cvtf\t%0.<SVE_F:Vetype>, %1/m, %2.<SVE_HSDI:Vetype>
+ movprfx\t%0, %3\;<su>cvtf\t%0.<SVE_F:Vetype>, %1/m, %2.<SVE_HSDI:Vetype>"
+ "&& !rtx_equal_p (operands[1], operands[4])"
{
- emit_insn ((<hi_lanes_optab>
- ? gen_aarch64_sve_<su>unpkhi_<SVE_BHSI:mode>
- : gen_aarch64_sve_<su>unpklo_<SVE_BHSI:mode>)
- (operands[0], operands[1]));
- DONE;
+ operands[4] = copy_rtx (operands[1]);
}
+ [(set_attr "movprfx" "*,yes,yes")]
)
-;; SUNPKHI, UUNPKHI, SUNPKLO and UUNPKLO.
-(define_insn "aarch64_sve_<su>unpk<perm_hilo>_<SVE_BHSI:mode>"
- [(set (match_operand:<VWIDE> 0 "register_operand" "=w")
- (unspec:<VWIDE> [(match_operand:SVE_BHSI 1 "register_operand" "w")]
- UNPACK))]
- "TARGET_SVE"
- "<su>unpk<perm_hilo>\t%0.<Vewtype>, %1.<Vetype>"
-)
+;; -------------------------------------------------------------------------
+;; ---- [FP<-INT] Packs
+;; -------------------------------------------------------------------------
+;; No patterns here yet!
+;; -------------------------------------------------------------------------
-;; Unpack one half of a VNx4SF to VNx2DF, or one half of a VNx8HF to VNx4SF.
-;; First unpack the source without conversion, then float-convert the
-;; unpacked source.
-(define_expand "vec_unpacks_<perm_hilo>_<mode>"
- [(match_operand:<VWIDE> 0 "register_operand")
- (unspec:SVE_HSF [(match_operand:SVE_HSF 1 "register_operand")]
- UNPACK_UNSIGNED)]
- "TARGET_SVE"
- {
- /* Use ZIP to do the unpack, since we don't care about the upper halves
- and since it has the nice property of not needing any subregs.
- If using UUNPK* turns out to be preferable, we could model it as
- a ZIP whose first operand is zero. */
- rtx temp = gen_reg_rtx (<MODE>mode);
- emit_insn ((<hi_lanes_optab>
- ? gen_aarch64_sve_zip2<mode>
- : gen_aarch64_sve_zip1<mode>)
- (temp, operands[1], operands[1]));
- rtx ptrue = aarch64_ptrue_reg (<VWIDE_PRED>mode);
- emit_insn (gen_aarch64_sve_extend<mode><Vwide>2 (operands[0],
- ptrue, temp));
- DONE;
- }
-)
+;; -------------------------------------------------------------------------
+;; ---- [FP<-INT] Unpacks
+;; -------------------------------------------------------------------------
+;; The patterns in this section are synthetic.
+;; -------------------------------------------------------------------------
;; Unpack one half of a VNx4SI to VNx2DF. First unpack from VNx4SI
;; to VNx2DI, reinterpret the VNx2DI as a VNx4SI, then convert the
@@ -2728,35 +5017,19 @@
: gen_aarch64_sve_zip1vnx4si)
(temp, operands[1], operands[1]));
rtx ptrue = aarch64_ptrue_reg (VNx2BImode);
- emit_insn (gen_aarch64_sve_<FLOATUORS:optab>vnx4sivnx2df2 (operands[0],
- ptrue, temp));
+ rtx strictness = gen_int_mode (SVE_RELAXED_GP, SImode);
+ emit_insn (gen_aarch64_sve_<FLOATUORS:optab>_extendvnx4sivnx2df
+ (operands[0], ptrue, temp, strictness));
DONE;
}
)
-;; Predicate pack. Use UZP1 on the narrower type, which discards
-;; the high part of each wide element.
-(define_insn "vec_pack_trunc_<Vwide>"
- [(set (match_operand:PRED_BHS 0 "register_operand" "=Upa")
- (unspec:PRED_BHS
- [(match_operand:<VWIDE> 1 "register_operand" "Upa")
- (match_operand:<VWIDE> 2 "register_operand" "Upa")]
- UNSPEC_PACK))]
- "TARGET_SVE"
- "uzp1\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
-)
-
-;; Integer pack. Use UZP1 on the narrower type, which discards
-;; the high part of each wide element.
-(define_insn "vec_pack_trunc_<Vwide>"
- [(set (match_operand:SVE_BHSI 0 "register_operand" "=w")
- (unspec:SVE_BHSI
- [(match_operand:<VWIDE> 1 "register_operand" "w")
- (match_operand:<VWIDE> 2 "register_operand" "w")]
- UNSPEC_PACK))]
- "TARGET_SVE"
- "uzp1\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
-)
+;; -------------------------------------------------------------------------
+;; ---- [FP<-FP] Packs
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - FCVT
+;; -------------------------------------------------------------------------
;; Convert two vectors of DF to SF, or two vectors of SF to HF, and pack
;; the results into a single vector.
@@ -2764,15 +5037,15 @@
[(set (match_dup 4)
(unspec:SVE_HSF
[(match_dup 3)
- (unspec:SVE_HSF [(match_operand:<VWIDE> 1 "register_operand")]
- UNSPEC_FLOAT_CONVERT)]
- UNSPEC_MERGE_PTRUE))
+ (const_int SVE_RELAXED_GP)
+ (match_operand:<VWIDE> 1 "register_operand")]
+ UNSPEC_COND_FCVT))
(set (match_dup 5)
(unspec:SVE_HSF
[(match_dup 3)
- (unspec:SVE_HSF [(match_operand:<VWIDE> 2 "register_operand")]
- UNSPEC_FLOAT_CONVERT)]
- UNSPEC_MERGE_PTRUE))
+ (const_int SVE_RELAXED_GP)
+ (match_operand:<VWIDE> 2 "register_operand")]
+ UNSPEC_COND_FCVT))
(set (match_operand:SVE_HSF 0 "register_operand")
(unspec:SVE_HSF [(match_dup 4) (match_dup 5)] UNSPEC_UZP1))]
"TARGET_SVE"
@@ -2783,349 +5056,111 @@
}
)
-;; Convert two vectors of DF to SI and pack the results into a single vector.
-(define_expand "vec_pack_<su>fix_trunc_vnx2df"
- [(set (match_dup 4)
- (unspec:VNx4SI
- [(match_dup 3)
- (FIXUORS:VNx4SI (match_operand:VNx2DF 1 "register_operand"))]
- UNSPEC_MERGE_PTRUE))
- (set (match_dup 5)
- (unspec:VNx4SI
- [(match_dup 3)
- (FIXUORS:VNx4SI (match_operand:VNx2DF 2 "register_operand"))]
- UNSPEC_MERGE_PTRUE))
- (set (match_operand:VNx4SI 0 "register_operand")
- (unspec:VNx4SI [(match_dup 4) (match_dup 5)] UNSPEC_UZP1))]
- "TARGET_SVE"
- {
- operands[3] = aarch64_ptrue_reg (VNx2BImode);
- operands[4] = gen_reg_rtx (VNx4SImode);
- operands[5] = gen_reg_rtx (VNx4SImode);
- }
-)
-
-;; Predicated floating-point operations with select.
-(define_expand "cond_<optab><mode>"
- [(set (match_operand:SVE_F 0 "register_operand")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand")
- (unspec:SVE_F
- [(match_operand:SVE_F 2 "register_operand")
- (match_operand:SVE_F 3 "register_operand")]
- SVE_COND_FP_BINARY)
- (match_operand:SVE_F 4 "aarch64_simd_reg_or_zero")]
- UNSPEC_SEL))]
- "TARGET_SVE"
-)
-
-;; Predicated floating-point operations with select matching first operand.
-(define_insn "*cond_<optab><mode>_2"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (unspec:SVE_F
- [(match_operand:SVE_F 2 "register_operand" "0, w")
- (match_operand:SVE_F 3 "register_operand" "w, w")]
- SVE_COND_FP_BINARY)
- (match_dup 2)]
- UNSPEC_SEL))]
- "TARGET_SVE"
- "@
- <sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- movprfx\t%0, %2\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
- [(set_attr "movprfx" "*,yes")]
-)
-
-;; Predicated floating-point operations with select matching second operand.
-(define_insn "*cond_<optab><mode>_3"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (unspec:SVE_F
- [(match_operand:SVE_F 2 "register_operand" "w, w")
- (match_operand:SVE_F 3 "register_operand" "0, w")]
- SVE_COND_FP_BINARY)
- (match_dup 3)]
- UNSPEC_SEL))]
- "TARGET_SVE"
- "@
- <sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
- movprfx\t%0, %3\;<sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>"
- [(set_attr "movprfx" "*,yes")]
-)
-
-;; Predicated floating-point binary operations in which the values of
-;; inactive lanes are distinct from the other inputs.
-(define_insn_and_rewrite "*cond_<optab><mode>_any"
- [(set (match_operand:SVE_F 0 "register_operand" "=&w, &w, &w, &w, ?&w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl, Upl, Upl")
- (unspec:SVE_F
- [(match_operand:SVE_F 2 "register_operand" "0, w, w, w, w")
- (match_operand:SVE_F 3 "register_operand" "w, 0, w, w, w")]
- SVE_COND_FP_BINARY)
- (match_operand:SVE_F 4 "aarch64_simd_reg_or_zero" "Dz, Dz, Dz, 0, w")]
- UNSPEC_SEL))]
- "TARGET_SVE
- && !rtx_equal_p (operands[2], operands[4])
- && !rtx_equal_p (operands[3], operands[4])"
- "@
- movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- movprfx\t%0.<Vetype>, %1/z, %0.<Vetype>\;<sve_fp_op_rev>\t%0.<Vetype>, %1/m, %0.<Vetype>, %2.<Vetype>
- movprfx\t%0.<Vetype>, %1/z, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- movprfx\t%0.<Vetype>, %1/m, %2.<Vetype>\;<sve_fp_op>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- #"
- "&& reload_completed
- && register_operand (operands[4], <MODE>mode)
- && !rtx_equal_p (operands[0], operands[4])"
- {
- emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[2],
- operands[4], operands[1]));
- operands[4] = operands[2] = operands[0];
- }
- [(set_attr "movprfx" "yes")]
-)
-
-;; Predicated floating-point ternary operations with select.
-(define_expand "cond_<optab><mode>"
- [(set (match_operand:SVE_F 0 "register_operand")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand")
- (unspec:SVE_F
- [(match_operand:SVE_F 2 "register_operand")
- (match_operand:SVE_F 3 "register_operand")
- (match_operand:SVE_F 4 "register_operand")]
- SVE_COND_FP_TERNARY)
- (match_operand:SVE_F 5 "aarch64_simd_reg_or_zero")]
- UNSPEC_SEL))]
- "TARGET_SVE"
-{
- /* Swap the multiplication operands if the fallback value is the
- second of the two. */
- if (rtx_equal_p (operands[3], operands[5]))
- std::swap (operands[2], operands[3]);
-})
-
-;; Predicated floating-point ternary operations using the FMAD-like form.
-(define_insn "*cond_<optab><mode>_2"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (unspec:SVE_F
- [(match_operand:SVE_F 2 "register_operand" "0, w")
- (match_operand:SVE_F 3 "register_operand" "w, w")
- (match_operand:SVE_F 4 "register_operand" "w, w")]
- SVE_COND_FP_TERNARY)
- (match_dup 2)]
- UNSPEC_SEL))]
- "TARGET_SVE"
- "@
- <sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>
- movprfx\t%0, %2\;<sve_fmad_op>\t%0.<Vetype>, %1/m, %3.<Vetype>, %4.<Vetype>"
- [(set_attr "movprfx" "*,yes")]
-)
-
-;; Predicated floating-point ternary operations using the FMLA-like form.
-(define_insn "*cond_<optab><mode>_4"
- [(set (match_operand:SVE_F 0 "register_operand" "=w, ?&w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (unspec:SVE_F
- [(match_operand:SVE_F 2 "register_operand" "w, w")
- (match_operand:SVE_F 3 "register_operand" "w, w")
- (match_operand:SVE_F 4 "register_operand" "0, w")]
- SVE_COND_FP_TERNARY)
- (match_dup 4)]
- UNSPEC_SEL))]
- "TARGET_SVE"
- "@
- <sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
- movprfx\t%0, %4\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>"
- [(set_attr "movprfx" "*,yes")]
-)
-
-;; Predicated floating-point ternary operations in which the value for
-;; inactive lanes is distinct from the other inputs.
-(define_insn_and_rewrite "*cond_<optab><mode>_any"
- [(set (match_operand:SVE_F 0 "register_operand" "=&w, &w, ?&w")
- (unspec:SVE_F
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl, Upl")
- (unspec:SVE_F
- [(match_operand:SVE_F 2 "register_operand" "w, w, w")
- (match_operand:SVE_F 3 "register_operand" "w, w, w")
- (match_operand:SVE_F 4 "register_operand" "w, w, w")]
- SVE_COND_FP_TERNARY)
- (match_operand:SVE_F 5 "aarch64_simd_reg_or_zero" "Dz, 0, w")]
- UNSPEC_SEL))]
- "TARGET_SVE
- && !rtx_equal_p (operands[2], operands[5])
- && !rtx_equal_p (operands[3], operands[5])
- && !rtx_equal_p (operands[4], operands[5])"
- "@
- movprfx\t%0.<Vetype>, %1/z, %4.<Vetype>\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
- movprfx\t%0.<Vetype>, %1/m, %4.<Vetype>\;<sve_fmla_op>\t%0.<Vetype>, %1/m, %2.<Vetype>, %3.<Vetype>
- #"
- "&& reload_completed
- && !CONSTANT_P (operands[5])
- && !rtx_equal_p (operands[0], operands[5])"
- {
- emit_insn (gen_vcond_mask_<mode><vpred> (operands[0], operands[4],
- operands[5], operands[1]));
- operands[5] = operands[4] = operands[0];
- }
- [(set_attr "movprfx" "yes")]
+;; Predicated float-to-float truncation.
+(define_insn "*aarch64_sve_<optab>_trunc<SVE_SDF:mode><SVE_HSF:mode>"
+ [(set (match_operand:SVE_HSF 0 "register_operand" "=w")
+ (unspec:SVE_HSF
+ [(match_operand:<SVE_SDF:VPRED> 1 "register_operand" "Upl")
+ (match_operand:SI 3 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_SDF 2 "register_operand" "w")]
+ SVE_COND_FCVT))]
+ "TARGET_SVE && <SVE_SDF:elem_bits> > <SVE_HSF:elem_bits>"
+ "fcvt\t%0.<SVE_HSF:Vetype>, %1/m, %2.<SVE_SDF:Vetype>"
)
-;; Shift an SVE vector left and insert a scalar into element 0.
-(define_insn "vec_shl_insert_<mode>"
- [(set (match_operand:SVE_ALL 0 "register_operand" "=w, w")
- (unspec:SVE_ALL
- [(match_operand:SVE_ALL 1 "register_operand" "0, 0")
- (match_operand:<VEL> 2 "register_operand" "rZ, w")]
- UNSPEC_INSR))]
- "TARGET_SVE"
- "@
- insr\t%0.<Vetype>, %<vwcore>2
- insr\t%0.<Vetype>, %<Vetype>2"
-)
+;; -------------------------------------------------------------------------
+;; ---- [FP<-FP] Unpacks
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - FCVT
+;; -------------------------------------------------------------------------
-(define_expand "copysign<mode>3"
- [(match_operand:SVE_F 0 "register_operand")
- (match_operand:SVE_F 1 "register_operand")
- (match_operand:SVE_F 2 "register_operand")]
- "TARGET_SVE"
- {
- rtx sign = gen_reg_rtx (<V_INT_EQUIV>mode);
- rtx mant = gen_reg_rtx (<V_INT_EQUIV>mode);
- rtx int_res = gen_reg_rtx (<V_INT_EQUIV>mode);
- int bits = GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1;
-
- rtx arg1 = lowpart_subreg (<V_INT_EQUIV>mode, operands[1], <MODE>mode);
- rtx arg2 = lowpart_subreg (<V_INT_EQUIV>mode, operands[2], <MODE>mode);
-
- emit_insn (gen_and<v_int_equiv>3
- (sign, arg2,
- aarch64_simd_gen_const_vector_dup (<V_INT_EQUIV>mode,
- HOST_WIDE_INT_M1U
- << bits)));
- emit_insn (gen_and<v_int_equiv>3
- (mant, arg1,
- aarch64_simd_gen_const_vector_dup (<V_INT_EQUIV>mode,
- ~(HOST_WIDE_INT_M1U
- << bits))));
- emit_insn (gen_ior<v_int_equiv>3 (int_res, sign, mant));
- emit_move_insn (operands[0], gen_lowpart (<MODE>mode, int_res));
- DONE;
- }
-)
-
-(define_expand "xorsign<mode>3"
- [(match_operand:SVE_F 0 "register_operand")
- (match_operand:SVE_F 1 "register_operand")
- (match_operand:SVE_F 2 "register_operand")]
+;; Unpack one half of a VNx4SF to VNx2DF, or one half of a VNx8HF to VNx4SF.
+;; First unpack the source without conversion, then float-convert the
+;; unpacked source.
+(define_expand "vec_unpacks_<perm_hilo>_<mode>"
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (unspec:SVE_HSF [(match_operand:SVE_HSF 1 "register_operand")]
+ UNPACK_UNSIGNED)]
"TARGET_SVE"
{
- rtx sign = gen_reg_rtx (<V_INT_EQUIV>mode);
- rtx int_res = gen_reg_rtx (<V_INT_EQUIV>mode);
- int bits = GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1;
-
- rtx arg1 = lowpart_subreg (<V_INT_EQUIV>mode, operands[1], <MODE>mode);
- rtx arg2 = lowpart_subreg (<V_INT_EQUIV>mode, operands[2], <MODE>mode);
-
- emit_insn (gen_and<v_int_equiv>3
- (sign, arg2,
- aarch64_simd_gen_const_vector_dup (<V_INT_EQUIV>mode,
- HOST_WIDE_INT_M1U
- << bits)));
- emit_insn (gen_xor<v_int_equiv>3 (int_res, arg1, sign));
- emit_move_insn (operands[0], gen_lowpart (<MODE>mode, int_res));
+ /* Use ZIP to do the unpack, since we don't care about the upper halves
+ and since it has the nice property of not needing any subregs.
+ If using UUNPK* turns out to be preferable, we could model it as
+ a ZIP whose first operand is zero. */
+ rtx temp = gen_reg_rtx (<MODE>mode);
+ emit_insn ((<hi_lanes_optab>
+ ? gen_aarch64_sve_zip2<mode>
+ : gen_aarch64_sve_zip1<mode>)
+ (temp, operands[1], operands[1]));
+ rtx ptrue = aarch64_ptrue_reg (<VWIDE_PRED>mode);
+ rtx strictness = gen_int_mode (SVE_RELAXED_GP, SImode);
+ emit_insn (gen_aarch64_sve_fcvt_nontrunc<mode><Vwide>
+ (operands[0], ptrue, temp, strictness));
DONE;
}
)
-;; Unpredicated DOT product.
-(define_insn "<sur>dot_prod<vsi2qi>"
- [(set (match_operand:SVE_SDI 0 "register_operand" "=w, ?&w")
- (plus:SVE_SDI
- (unspec:SVE_SDI
- [(match_operand:<VSI2QI> 1 "register_operand" "w, w")
- (match_operand:<VSI2QI> 2 "register_operand" "w, w")]
- DOTPROD)
- (match_operand:SVE_SDI 3 "register_operand" "0, w")))]
- "TARGET_SVE"
- "@
- <sur>dot\\t%0.<Vetype>, %1.<Vetype_fourth>, %2.<Vetype_fourth>
- movprfx\t%0, %3\;<sur>dot\\t%0.<Vetype>, %1.<Vetype_fourth>, %2.<Vetype_fourth>"
- [(set_attr "movprfx" "*,yes")]
+;; Predicated float-to-float extension.
+(define_insn "aarch64_sve_<optab>_nontrunc<SVE_HSF:mode><SVE_SDF:mode>"
+ [(set (match_operand:SVE_SDF 0 "register_operand" "=w")
+ (unspec:SVE_SDF
+ [(match_operand:<SVE_SDF:VPRED> 1 "register_operand" "Upl")
+ (match_operand:SI 3 "aarch64_sve_gp_strictness")
+ (match_operand:SVE_HSF 2 "register_operand" "w")]
+ SVE_COND_FCVT))]
+ "TARGET_SVE && <SVE_SDF:elem_bits> > <SVE_HSF:elem_bits>"
+ "fcvt\t%0.<SVE_SDF:Vetype>, %1/m, %2.<SVE_HSF:Vetype>"
)
-;; Unpredicated integer absolute difference.
-(define_expand "<su>abd<mode>_3"
- [(use (match_operand:SVE_I 0 "register_operand"))
- (USMAX:SVE_I (match_operand:SVE_I 1 "register_operand")
- (match_operand:SVE_I 2 "register_operand"))]
- "TARGET_SVE"
- {
- rtx pred = aarch64_ptrue_reg (<VPRED>mode);
- emit_insn (gen_aarch64_<su>abd<mode>_3 (operands[0], pred, operands[1],
- operands[2]));
- DONE;
- }
-)
+;; -------------------------------------------------------------------------
+;; ---- [PRED<-PRED] Packs
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - UZP1
+;; -------------------------------------------------------------------------
-;; Predicated integer absolute difference.
-(define_insn "aarch64_<su>abd<mode>_3"
- [(set (match_operand:SVE_I 0 "register_operand" "=w, ?&w")
- (unspec:SVE_I
- [(match_operand:<VPRED> 1 "register_operand" "Upl, Upl")
- (minus:SVE_I
- (USMAX:SVE_I
- (match_operand:SVE_I 2 "register_operand" "0, w")
- (match_operand:SVE_I 3 "register_operand" "w, w"))
- (<max_opp>:SVE_I
- (match_dup 2)
- (match_dup 3)))]
- UNSPEC_MERGE_PTRUE))]
+;; Predicate pack. Use UZP1 on the narrower type, which discards
+;; the high part of each wide element.
+(define_insn "vec_pack_trunc_<Vwide>"
+ [(set (match_operand:PRED_BHS 0 "register_operand" "=Upa")
+ (unspec:PRED_BHS
+ [(match_operand:<VWIDE> 1 "register_operand" "Upa")
+ (match_operand:<VWIDE> 2 "register_operand" "Upa")]
+ UNSPEC_PACK))]
"TARGET_SVE"
- "@
- <su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
- movprfx\t%0, %2\;<su>abd\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
- [(set_attr "movprfx" "*,yes")]
+ "uzp1\t%0.<Vetype>, %1.<Vetype>, %2.<Vetype>"
)
-;; Emit a sequence to produce a sum-of-absolute-differences of the inputs in
-;; operands 1 and 2. The sequence also has to perform a widening reduction of
-;; the difference into a vector and accumulate that into operand 3 before
-;; copying that into the result operand 0.
-;; Perform that with a sequence of:
-;; MOV ones.b, #1
-;; [SU]ABD diff.b, p0/m, op1.b, op2.b
-;; MOVPRFX op0, op3 // If necessary
-;; UDOT op0.s, diff.b, ones.b
+;; -------------------------------------------------------------------------
+;; ---- [PRED<-PRED] Unpacks
+;; -------------------------------------------------------------------------
+;; Includes:
+;; - PUNPKHI
+;; - PUNPKLO
+;; -------------------------------------------------------------------------
-(define_expand "<sur>sad<vsi2qi>"
- [(use (match_operand:SVE_SDI 0 "register_operand"))
- (unspec:<VSI2QI> [(use (match_operand:<VSI2QI> 1 "register_operand"))
- (use (match_operand:<VSI2QI> 2 "register_operand"))] ABAL)
- (use (match_operand:SVE_SDI 3 "register_operand"))]
+;; Unpack the low or high half of a predicate, where "high" refers to
+;; the low-numbered lanes for big-endian and the high-numbered lanes
+;; for little-endian.
+(define_expand "vec_unpack<su>_<perm_hilo>_<mode>"
+ [(match_operand:<VWIDE> 0 "register_operand")
+ (unspec:<VWIDE> [(match_operand:PRED_BHS 1 "register_operand")]
+ UNPACK)]
"TARGET_SVE"
{
- rtx ones = force_reg (<VSI2QI>mode, CONST1_RTX (<VSI2QI>mode));
- rtx diff = gen_reg_rtx (<VSI2QI>mode);
- emit_insn (gen_<sur>abd<vsi2qi>_3 (diff, operands[1], operands[2]));
- emit_insn (gen_udot_prod<vsi2qi> (operands[0], diff, ones, operands[3]));
+ emit_insn ((<hi_lanes_optab>
+ ? gen_aarch64_sve_punpkhi_<PRED_BHS:mode>
+ : gen_aarch64_sve_punpklo_<PRED_BHS:mode>)
+ (operands[0], operands[1]));
DONE;
}
)
-;; Standard pattern name vec_init<mode><Vel>.
-(define_expand "vec_init<mode><Vel>"
- [(match_operand:SVE_ALL 0 "register_operand")
- (match_operand 1 "" "")]
+(define_insn "aarch64_sve_punpk<perm_hilo>_<mode>"
+ [(set (match_operand:<VWIDE> 0 "register_operand" "=Upa")
+ (unspec:<VWIDE> [(match_operand:PRED_BHS 1 "register_operand" "Upa")]
+ UNPACK_UNSIGNED))]
"TARGET_SVE"
- {
- aarch64_sve_expand_vector_init (operands[0], operands[1]);
- DONE;
- }
+ "punpk<perm_hilo>\t%0.h, %1.b"
)
diff --git a/gcc/config/aarch64/aarch64-sve2.md b/gcc/config/aarch64/aarch64-sve2.md
index d0c235b..2334e5a 100644
--- a/gcc/config/aarch64/aarch64-sve2.md
+++ b/gcc/config/aarch64/aarch64-sve2.md
@@ -26,7 +26,7 @@
(unspec:SVE_I [(match_operand:SVE_I 1 "register_operand")
(match_operand:SVE_I 2 "register_operand")]
HADD)]
- UNSPEC_MERGE_PTRUE))]
+ UNSPEC_PRED_X))]
"TARGET_SVE2"
{
operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
@@ -41,7 +41,7 @@
(unspec:SVE_I [(match_operand:SVE_I 1 "register_operand")
(match_operand:SVE_I 2 "register_operand")]
RHADD)]
- UNSPEC_MERGE_PTRUE))]
+ UNSPEC_PRED_X))]
"TARGET_SVE2"
{
operands[3] = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
@@ -56,10 +56,10 @@
(unspec:SVE_I [(match_operand:SVE_I 2 "register_operand" "%0, w")
(match_operand:SVE_I 3 "register_operand" "w, w")]
HADDSUB)]
- UNSPEC_MERGE_PTRUE))]
+ UNSPEC_PRED_X))]
"TARGET_SVE2"
"@
<sur>h<addsub>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>
movprfx\t%0, %2\;<sur>h<addsub>\t%0.<Vetype>, %1/m, %0.<Vetype>, %3.<Vetype>"
[(set_attr "movprfx" "*,yes")]
-) \ No newline at end of file
+)
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 5bf182c..be01622 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -73,6 +73,7 @@
#include "selftest-rtl.h"
#include "rtx-vector-builder.h"
#include "intl.h"
+#include "expmed.h"
/* This file should be included last. */
#include "target-def.h"
@@ -83,7 +84,7 @@
/* Information about a legitimate vector immediate operand. */
struct simd_immediate_info
{
- enum insn_type { MOV, MVN };
+ enum insn_type { MOV, MVN, INDEX, PTRUE };
enum modifier_type { LSL, MSL };
simd_immediate_info () {}
@@ -92,33 +93,51 @@ struct simd_immediate_info
insn_type = MOV, modifier_type = LSL,
unsigned int = 0);
simd_immediate_info (scalar_mode, rtx, rtx);
+ simd_immediate_info (scalar_int_mode, aarch64_svpattern);
/* The mode of the elements. */
scalar_mode elt_mode;
- /* The value of each element if all elements are the same, or the
- first value if the constant is a series. */
- rtx value;
-
- /* The value of the step if the constant is a series, null otherwise. */
- rtx step;
-
/* The instruction to use to move the immediate into a vector. */
insn_type insn;
- /* The kind of shift modifier to use, and the number of bits to shift.
- This is (LSL, 0) if no shift is needed. */
- modifier_type modifier;
- unsigned int shift;
+ union
+ {
+ /* For MOV and MVN. */
+ struct
+ {
+ /* The value of each element. */
+ rtx value;
+
+ /* The kind of shift modifier to use, and the number of bits to shift.
+ This is (LSL, 0) if no shift is needed. */
+ modifier_type modifier;
+ unsigned int shift;
+ } mov;
+
+ /* For INDEX. */
+ struct
+ {
+ /* The value of the first element and the step to be added for each
+ subsequent element. */
+ rtx base, step;
+ } index;
+
+ /* For PTRUE. */
+ aarch64_svpattern pattern;
+ } u;
};
/* Construct a floating-point immediate in which each element has mode
ELT_MODE_IN and value VALUE_IN. */
inline simd_immediate_info
::simd_immediate_info (scalar_float_mode elt_mode_in, rtx value_in)
- : elt_mode (elt_mode_in), value (value_in), step (NULL_RTX), insn (MOV),
- modifier (LSL), shift (0)
-{}
+ : elt_mode (elt_mode_in), insn (MOV)
+{
+ u.mov.value = value_in;
+ u.mov.modifier = LSL;
+ u.mov.shift = 0;
+}
/* Construct an integer immediate in which each element has mode ELT_MODE_IN
and value VALUE_IN. The other parameters are as for the structure
@@ -128,17 +147,32 @@ inline simd_immediate_info
unsigned HOST_WIDE_INT value_in,
insn_type insn_in, modifier_type modifier_in,
unsigned int shift_in)
- : elt_mode (elt_mode_in), value (gen_int_mode (value_in, elt_mode_in)),
- step (NULL_RTX), insn (insn_in), modifier (modifier_in), shift (shift_in)
-{}
+ : elt_mode (elt_mode_in), insn (insn_in)
+{
+ u.mov.value = gen_int_mode (value_in, elt_mode_in);
+ u.mov.modifier = modifier_in;
+ u.mov.shift = shift_in;
+}
/* Construct an integer immediate in which each element has mode ELT_MODE_IN
- and where element I is equal to VALUE_IN + I * STEP_IN. */
+ and where element I is equal to BASE_IN + I * STEP_IN. */
inline simd_immediate_info
-::simd_immediate_info (scalar_mode elt_mode_in, rtx value_in, rtx step_in)
- : elt_mode (elt_mode_in), value (value_in), step (step_in), insn (MOV),
- modifier (LSL), shift (0)
-{}
+::simd_immediate_info (scalar_mode elt_mode_in, rtx base_in, rtx step_in)
+ : elt_mode (elt_mode_in), insn (INDEX)
+{
+ u.index.base = base_in;
+ u.index.step = step_in;
+}
+
+/* Construct a predicate that controls elements of mode ELT_MODE_IN
+ and has PTRUE pattern PATTERN_IN. */
+inline simd_immediate_info
+::simd_immediate_info (scalar_int_mode elt_mode_in,
+ aarch64_svpattern pattern_in)
+ : elt_mode (elt_mode_in), insn (PTRUE)
+{
+ u.pattern = pattern_in;
+}
/* The current code model. */
enum aarch64_code_model aarch64_cmodel;
@@ -693,7 +727,7 @@ static const struct tune_params generic_tunings =
4, /* memmov_cost */
2, /* issue_rate */
(AARCH64_FUSE_AES_AESMC), /* fusible_ops */
- "8", /* function_align. */
+ "16:12", /* function_align. */
"4", /* jump_align. */
"8", /* loop_align. */
2, /* int_reassoc_width. */
@@ -1315,6 +1349,22 @@ static const char *const aarch64_sve_condition_codes[] =
"pmore", "plast", "tcont", "tstop", "gt", "le", "al", "nv"
};
+/* Return the assembly token for svpattern value VALUE. */
+
+static const char *
+svpattern_token (enum aarch64_svpattern pattern)
+{
+ switch (pattern)
+ {
+#define CASE(UPPER, LOWER, VALUE) case AARCH64_SV_##UPPER: return #LOWER;
+ AARCH64_FOR_SVPATTERN (CASE)
+#undef CASE
+ case AARCH64_NUM_SVPATTERNS:
+ break;
+ }
+ gcc_unreachable ();
+}
+
/* Generate code to enable conditional branches in functions over 1 MiB. */
const char *
aarch64_gen_far_branch (rtx * operands, int pos_label, const char * dest,
@@ -1433,6 +1483,16 @@ aarch64_dbx_register_number (unsigned regno)
return DWARF_FRAME_REGISTERS;
}
+/* If X is a CONST_DOUBLE, return its bit representation as a constant
+ integer, otherwise return X unmodified. */
+static rtx
+aarch64_bit_representation (rtx x)
+{
+ if (CONST_DOUBLE_P (x))
+ x = gen_lowpart (int_mode_for_mode (GET_MODE (x)).require (), x);
+ return x;
+}
+
/* Return true if MODE is any of the Advanced SIMD structure modes. */
static bool
aarch64_advsimd_struct_mode_p (machine_mode mode)
@@ -1474,34 +1534,68 @@ aarch64_classify_vector_mode (machine_mode mode)
if (aarch64_sve_pred_mode_p (mode))
return VEC_SVE_PRED;
- scalar_mode inner = GET_MODE_INNER (mode);
- if (VECTOR_MODE_P (mode)
- && (inner == QImode
- || inner == HImode
- || inner == HFmode
- || inner == SImode
- || inner == SFmode
- || inner == DImode
- || inner == DFmode))
- {
- if (TARGET_SVE)
- {
- if (known_eq (GET_MODE_BITSIZE (mode), BITS_PER_SVE_VECTOR))
- return VEC_SVE_DATA;
- if (known_eq (GET_MODE_BITSIZE (mode), BITS_PER_SVE_VECTOR * 2)
- || known_eq (GET_MODE_BITSIZE (mode), BITS_PER_SVE_VECTOR * 3)
- || known_eq (GET_MODE_BITSIZE (mode), BITS_PER_SVE_VECTOR * 4))
- return VEC_SVE_DATA | VEC_STRUCT;
- }
+ /* Make the decision based on the mode's enum value rather than its
+ properties, so that we keep the correct classification regardless
+ of -msve-vector-bits. */
+ switch (mode)
+ {
+ /* Single SVE vectors. */
+ case E_VNx16QImode:
+ case E_VNx8HImode:
+ case E_VNx4SImode:
+ case E_VNx2DImode:
+ case E_VNx8HFmode:
+ case E_VNx4SFmode:
+ case E_VNx2DFmode:
+ return TARGET_SVE ? VEC_SVE_DATA : 0;
+
+ /* x2 SVE vectors. */
+ case E_VNx32QImode:
+ case E_VNx16HImode:
+ case E_VNx8SImode:
+ case E_VNx4DImode:
+ case E_VNx16HFmode:
+ case E_VNx8SFmode:
+ case E_VNx4DFmode:
+ /* x3 SVE vectors. */
+ case E_VNx48QImode:
+ case E_VNx24HImode:
+ case E_VNx12SImode:
+ case E_VNx6DImode:
+ case E_VNx24HFmode:
+ case E_VNx12SFmode:
+ case E_VNx6DFmode:
+ /* x4 SVE vectors. */
+ case E_VNx64QImode:
+ case E_VNx32HImode:
+ case E_VNx16SImode:
+ case E_VNx8DImode:
+ case E_VNx32HFmode:
+ case E_VNx16SFmode:
+ case E_VNx8DFmode:
+ return TARGET_SVE ? VEC_SVE_DATA | VEC_STRUCT : 0;
+
+ /* 64-bit Advanced SIMD vectors. */
+ case E_V8QImode:
+ case E_V4HImode:
+ case E_V2SImode:
+ /* ...E_V1DImode doesn't exist. */
+ case E_V4HFmode:
+ case E_V2SFmode:
+ case E_V1DFmode:
+ /* 128-bit Advanced SIMD vectors. */
+ case E_V16QImode:
+ case E_V8HImode:
+ case E_V4SImode:
+ case E_V2DImode:
+ case E_V8HFmode:
+ case E_V4SFmode:
+ case E_V2DFmode:
+ return TARGET_SIMD ? VEC_ADVSIMD : 0;
- /* This includes V1DF but not V1DI (which doesn't exist). */
- if (TARGET_SIMD
- && (known_eq (GET_MODE_BITSIZE (mode), 64)
- || known_eq (GET_MODE_BITSIZE (mode), 128)))
- return VEC_ADVSIMD;
+ default:
+ return 0;
}
-
- return 0;
}
/* Return true if MODE is any of the data vector modes, including
@@ -1512,6 +1606,14 @@ aarch64_vector_data_mode_p (machine_mode mode)
return aarch64_classify_vector_mode (mode) & VEC_ANY_DATA;
}
+/* Return true if MODE is any form of SVE mode, including predicates,
+ vectors and structures. */
+bool
+aarch64_sve_mode_p (machine_mode mode)
+{
+ return aarch64_classify_vector_mode (mode) & VEC_ANY_SVE;
+}
+
/* Return true if MODE is an SVE data vector mode; either a single vector
or a structure of vectors. */
static bool
@@ -1582,6 +1684,43 @@ aarch64_get_mask_mode (poly_uint64 nunits, poly_uint64 nbytes)
return default_get_mask_mode (nunits, nbytes);
}
+/* Return the SVE vector mode that has NUNITS elements of mode INNER_MODE. */
+
+static opt_machine_mode
+aarch64_sve_data_mode (scalar_mode inner_mode, poly_uint64 nunits)
+{
+ enum mode_class mclass = (is_a <scalar_float_mode> (inner_mode)
+ ? MODE_VECTOR_FLOAT : MODE_VECTOR_INT);
+ machine_mode mode;
+ FOR_EACH_MODE_IN_CLASS (mode, mclass)
+ if (inner_mode == GET_MODE_INNER (mode)
+ && known_eq (nunits, GET_MODE_NUNITS (mode))
+ && aarch64_sve_data_mode_p (mode))
+ return mode;
+ return opt_machine_mode ();
+}
+
+/* Return the integer element mode associated with SVE mode MODE. */
+
+static scalar_int_mode
+aarch64_sve_element_int_mode (machine_mode mode)
+{
+ unsigned int elt_bits = vector_element_size (BITS_PER_SVE_VECTOR,
+ GET_MODE_NUNITS (mode));
+ return int_mode_for_size (elt_bits, 0).require ();
+}
+
+/* Return the integer vector mode associated with SVE mode MODE.
+ Unlike mode_for_int_vector, this can handle the case in which
+ MODE is a predicate (and thus has a different total size). */
+
+static machine_mode
+aarch64_sve_int_mode (machine_mode mode)
+{
+ scalar_int_mode int_mode = aarch64_sve_element_int_mode (mode);
+ return aarch64_sve_data_mode (int_mode, GET_MODE_NUNITS (mode)).require ();
+}
+
/* Implement TARGET_PREFERRED_ELSE_VALUE. For binary operations,
prefer to use the first arithmetic operand as the else value if
the else value doesn't matter, since that exactly matches the SVE
@@ -1610,6 +1749,7 @@ aarch64_hard_regno_nregs (unsigned regno, machine_mode mode)
{
case FP_REGS:
case FP_LO_REGS:
+ case FP_LO8_REGS:
if (aarch64_sve_data_mode_p (mode))
return exact_div (GET_MODE_SIZE (mode),
BYTES_PER_SVE_VECTOR).to_constant ();
@@ -2452,6 +2592,36 @@ aarch64_zero_extend_const_eq (machine_mode xmode, rtx x,
}
+/* Return TARGET if it is nonnull and a register of mode MODE.
+ Otherwise, return a fresh register of mode MODE if we can,
+ or TARGET reinterpreted as MODE if we can't. */
+
+static rtx
+aarch64_target_reg (rtx target, machine_mode mode)
+{
+ if (target && REG_P (target) && GET_MODE (target) == mode)
+ return target;
+ if (!can_create_pseudo_p ())
+ {
+ gcc_assert (target);
+ return gen_lowpart (mode, target);
+ }
+ return gen_reg_rtx (mode);
+}
+
+/* Return a register that contains the constant in BUILDER, given that
+ the constant is a legitimate move operand. Use TARGET as the register
+ if it is nonnull and convenient. */
+
+static rtx
+aarch64_emit_set_immediate (rtx target, rtx_vector_builder &builder)
+{
+ rtx src = builder.build ();
+ target = aarch64_target_reg (target, GET_MODE (src));
+ emit_insn (gen_rtx_SET (target, src));
+ return target;
+}
+
static rtx
aarch64_force_temporary (machine_mode mode, rtx x, rtx value)
{
@@ -2465,13 +2635,170 @@ aarch64_force_temporary (machine_mode mode, rtx x, rtx value)
}
}
+/* Return true if predicate value X is a constant in which every element
+ is a CONST_INT. When returning true, describe X in BUILDER as a VNx16BI
+ value, i.e. as a predicate in which all bits are significant. */
+
+static bool
+aarch64_get_sve_pred_bits (rtx_vector_builder &builder, rtx x)
+{
+ if (GET_CODE (x) != CONST_VECTOR)
+ return false;
+
+ unsigned int factor = vector_element_size (GET_MODE_NUNITS (VNx16BImode),
+ GET_MODE_NUNITS (GET_MODE (x)));
+ unsigned int npatterns = CONST_VECTOR_NPATTERNS (x) * factor;
+ unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (x);
+ builder.new_vector (VNx16BImode, npatterns, nelts_per_pattern);
+
+ unsigned int nelts = const_vector_encoded_nelts (x);
+ for (unsigned int i = 0; i < nelts; ++i)
+ {
+ rtx elt = CONST_VECTOR_ENCODED_ELT (x, i);
+ if (!CONST_INT_P (elt))
+ return false;
+
+ builder.quick_push (elt);
+ for (unsigned int j = 1; j < factor; ++j)
+ builder.quick_push (const0_rtx);
+ }
+ builder.finalize ();
+ return true;
+}
+
+/* BUILDER contains a predicate constant of mode VNx16BI. Return the
+ widest predicate element size it can have (that is, the largest size
+ for which each element would still be 0 or 1). */
+
+unsigned int
+aarch64_widest_sve_pred_elt_size (rtx_vector_builder &builder)
+{
+ /* Start with the most optimistic assumption: that we only need
+ one bit per pattern. This is what we will use if only the first
+ bit in each pattern is ever set. */
+ unsigned int mask = GET_MODE_SIZE (DImode);
+ mask |= builder.npatterns ();
+
+ /* Look for set bits. */
+ unsigned int nelts = builder.encoded_nelts ();
+ for (unsigned int i = 1; i < nelts; ++i)
+ if (INTVAL (builder.elt (i)) != 0)
+ {
+ if (i & 1)
+ return 1;
+ mask |= i;
+ }
+ return mask & -mask;
+}
+
+/* BUILDER is a predicate constant of mode VNx16BI. Consider the value
+ that the constant would have with predicate element size ELT_SIZE
+ (ignoring the upper bits in each element) and return:
+
+ * -1 if all bits are set
+ * N if the predicate has N leading set bits followed by all clear bits
+ * 0 if the predicate does not have any of these forms. */
+
+int
+aarch64_partial_ptrue_length (rtx_vector_builder &builder,
+ unsigned int elt_size)
+{
+ /* If nelts_per_pattern is 3, we have set bits followed by clear bits
+ followed by set bits. */
+ if (builder.nelts_per_pattern () == 3)
+ return 0;
+
+ /* Skip over leading set bits. */
+ unsigned int nelts = builder.encoded_nelts ();
+ unsigned int i = 0;
+ for (; i < nelts; i += elt_size)
+ if (INTVAL (builder.elt (i)) == 0)
+ break;
+ unsigned int vl = i / elt_size;
+
+ /* Check for the all-true case. */
+ if (i == nelts)
+ return -1;
+
+ /* If nelts_per_pattern is 1, then either VL is zero, or we have a
+ repeating pattern of set bits followed by clear bits. */
+ if (builder.nelts_per_pattern () != 2)
+ return 0;
+
+ /* We have a "foreground" value and a duplicated "background" value.
+ If the background might repeat and the last set bit belongs to it,
+ we might have set bits followed by clear bits followed by set bits. */
+ if (i > builder.npatterns () && maybe_ne (nelts, builder.full_nelts ()))
+ return 0;
+
+ /* Make sure that the rest are all clear. */
+ for (; i < nelts; i += elt_size)
+ if (INTVAL (builder.elt (i)) != 0)
+ return 0;
+
+ return vl;
+}
+
+/* See if there is an svpattern that encodes an SVE predicate of mode
+ PRED_MODE in which the first VL bits are set and the rest are clear.
+ Return the pattern if so, otherwise return AARCH64_NUM_SVPATTERNS.
+ A VL of -1 indicates an all-true vector. */
+
+aarch64_svpattern
+aarch64_svpattern_for_vl (machine_mode pred_mode, int vl)
+{
+ if (vl < 0)
+ return AARCH64_SV_ALL;
+
+ if (maybe_gt (vl, GET_MODE_NUNITS (pred_mode)))
+ return AARCH64_NUM_SVPATTERNS;
+
+ if (vl >= 1 && vl <= 8)
+ return aarch64_svpattern (AARCH64_SV_VL1 + (vl - 1));
+
+ if (vl >= 16 && vl <= 256 && pow2p_hwi (vl))
+ return aarch64_svpattern (AARCH64_SV_VL16 + (exact_log2 (vl) - 4));
+
+ int max_vl;
+ if (GET_MODE_NUNITS (pred_mode).is_constant (&max_vl))
+ {
+ if (vl == (max_vl / 3) * 3)
+ return AARCH64_SV_MUL3;
+ /* These would only trigger for non-power-of-2 lengths. */
+ if (vl == (max_vl & -4))
+ return AARCH64_SV_MUL4;
+ if (vl == (1 << floor_log2 (max_vl)))
+ return AARCH64_SV_POW2;
+ if (vl == max_vl)
+ return AARCH64_SV_ALL;
+ }
+ return AARCH64_NUM_SVPATTERNS;
+}
+
+/* Return a VNx16BImode constant in which every sequence of ELT_SIZE
+ bits has the lowest bit set and the upper bits clear. This is the
+ VNx16BImode equivalent of a PTRUE for controlling elements of
+ ELT_SIZE bytes. However, because the constant is VNx16BImode,
+ all bits are significant, even the upper zeros. */
+
+rtx
+aarch64_ptrue_all (unsigned int elt_size)
+{
+ rtx_vector_builder builder (VNx16BImode, elt_size, 1);
+ builder.quick_push (const1_rtx);
+ for (unsigned int i = 1; i < elt_size; ++i)
+ builder.quick_push (const0_rtx);
+ return builder.build ();
+}
+
/* Return an all-true predicate register of mode MODE. */
rtx
aarch64_ptrue_reg (machine_mode mode)
{
gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
- return force_reg (mode, CONSTM1_RTX (mode));
+ rtx reg = force_reg (VNx16BImode, CONSTM1_RTX (VNx16BImode));
+ return gen_lowpart (mode, reg);
}
/* Return an all-false predicate register of mode MODE. */
@@ -2480,7 +2807,80 @@ rtx
aarch64_pfalse_reg (machine_mode mode)
{
gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL);
- return force_reg (mode, CONST0_RTX (mode));
+ rtx reg = force_reg (VNx16BImode, CONST0_RTX (VNx16BImode));
+ return gen_lowpart (mode, reg);
+}
+
+/* Return true if predicate PRED1[0] is true whenever predicate PRED2 is
+ true, or alternatively if we know that the operation predicated by
+ PRED1[0] is safe to perform whenever PRED2 is true. PRED1[1] is a
+ aarch64_sve_gp_strictness operand that describes the operation
+ predicated by PRED1[0]. */
+
+bool
+aarch64_sve_pred_dominates_p (rtx *pred1, rtx pred2)
+{
+ machine_mode mode = GET_MODE (pred2);
+ gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL
+ && mode == GET_MODE (pred1[0])
+ && aarch64_sve_gp_strictness (pred1[1], SImode));
+ return (pred1[0] == CONSTM1_RTX (mode)
+ || INTVAL (pred1[1]) == SVE_RELAXED_GP
+ || rtx_equal_p (pred1[0], pred2));
+}
+
+/* PRED1[0] is a PTEST predicate and PRED1[1] is an aarch64_sve_ptrue_flag
+ for it. PRED2[0] is the predicate for the instruction whose result
+ is tested by the PTEST and PRED2[1] is again an aarch64_sve_ptrue_flag
+ for it. Return true if we can prove that the two predicates are
+ equivalent for PTEST purposes; that is, if we can replace PRED2[0]
+ with PRED1[0] without changing behavior. */
+
+bool
+aarch64_sve_same_pred_for_ptest_p (rtx *pred1, rtx *pred2)
+{
+ machine_mode mode = GET_MODE (pred1[0]);
+ gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL
+ && mode == GET_MODE (pred2[0])
+ && aarch64_sve_ptrue_flag (pred1[1], SImode)
+ && aarch64_sve_ptrue_flag (pred2[1], SImode));
+
+ bool ptrue1_p = (pred1[0] == CONSTM1_RTX (mode)
+ || INTVAL (pred1[1]) == SVE_KNOWN_PTRUE);
+ bool ptrue2_p = (pred2[0] == CONSTM1_RTX (mode)
+ || INTVAL (pred2[1]) == SVE_KNOWN_PTRUE);
+ return (ptrue1_p && ptrue2_p) || rtx_equal_p (pred1[0], pred2[0]);
+}
+
+/* Emit a comparison CMP between OP0 and OP1, both of which have mode
+ DATA_MODE, and return the result in a predicate of mode PRED_MODE.
+ Use TARGET as the target register if nonnull and convenient. */
+
+static rtx
+aarch64_sve_emit_int_cmp (rtx target, machine_mode pred_mode, rtx_code cmp,
+ machine_mode data_mode, rtx op1, rtx op2)
+{
+ insn_code icode = code_for_aarch64_pred_cmp (cmp, data_mode);
+ expand_operand ops[5];
+ create_output_operand (&ops[0], target, pred_mode);
+ create_input_operand (&ops[1], CONSTM1_RTX (pred_mode), pred_mode);
+ create_integer_operand (&ops[2], SVE_KNOWN_PTRUE);
+ create_input_operand (&ops[3], op1, data_mode);
+ create_input_operand (&ops[4], op2, data_mode);
+ expand_insn (icode, 5, ops);
+ return ops[0].value;
+}
+
+/* Use a comparison to convert integer vector SRC into MODE, which is
+ the corresponding SVE predicate mode. Use TARGET for the result
+ if it's nonnull and convenient. */
+
+static rtx
+aarch64_convert_sve_data_to_pred (rtx target, machine_mode mode, rtx src)
+{
+ machine_mode src_mode = GET_MODE (src);
+ return aarch64_sve_emit_int_cmp (target, mode, NE, src_mode,
+ src, CONST0_RTX (src_mode));
}
/* Return true if we can move VALUE into a register using a single
@@ -2510,16 +2910,17 @@ aarch64_sve_cnt_immediate_p (rtx x)
operand (a vector pattern followed by a multiplier in the range [1, 16]).
PREFIX is the mnemonic without the size suffix and OPERANDS is the
first part of the operands template (the part that comes before the
- vector size itself). FACTOR is the number of quadwords.
- NELTS_PER_VQ, if nonzero, is the number of elements in each quadword.
- If it is zero, we can use any element size. */
+ vector size itself). PATTERN is the pattern to use. FACTOR is the
+ number of quadwords. NELTS_PER_VQ, if nonzero, is the number of elements
+ in each quadword. If it is zero, we can use any element size. */
static char *
aarch64_output_sve_cnt_immediate (const char *prefix, const char *operands,
+ aarch64_svpattern pattern,
unsigned int factor,
unsigned int nelts_per_vq)
{
- static char buffer[sizeof ("sqincd\t%x0, %w0, all, mul #16")];
+ static char buffer[sizeof ("sqincd\t%x0, %w0, vl256, mul #16")];
if (nelts_per_vq == 0)
/* There is some overlap in the ranges of the four CNT instructions.
@@ -2532,12 +2933,16 @@ aarch64_output_sve_cnt_immediate (const char *prefix, const char *operands,
factor >>= shift;
unsigned int written;
- if (factor == 1)
+ if (pattern == AARCH64_SV_ALL && factor == 1)
written = snprintf (buffer, sizeof (buffer), "%s%c\t%s",
prefix, suffix, operands);
+ else if (factor == 1)
+ written = snprintf (buffer, sizeof (buffer), "%s%c\t%s, %s",
+ prefix, suffix, operands, svpattern_token (pattern));
else
- written = snprintf (buffer, sizeof (buffer), "%s%c\t%s, all, mul #%d",
- prefix, suffix, operands, factor);
+ written = snprintf (buffer, sizeof (buffer), "%s%c\t%s, %s, mul #%d",
+ prefix, suffix, operands, svpattern_token (pattern),
+ factor);
gcc_assert (written < sizeof (buffer));
return buffer;
}
@@ -2547,7 +2952,8 @@ aarch64_output_sve_cnt_immediate (const char *prefix, const char *operands,
PREFIX is the mnemonic without the size suffix and OPERANDS is the
first part of the operands template (the part that comes before the
vector size itself). X is the value of the vector size operand,
- as a polynomial integer rtx. */
+ as a polynomial integer rtx; we need to convert this into an "all"
+ pattern with a multiplier. */
char *
aarch64_output_sve_cnt_immediate (const char *prefix, const char *operands,
@@ -2555,10 +2961,37 @@ aarch64_output_sve_cnt_immediate (const char *prefix, const char *operands,
{
poly_int64 value = rtx_to_poly_int64 (x);
gcc_assert (aarch64_sve_cnt_immediate_p (value));
- return aarch64_output_sve_cnt_immediate (prefix, operands,
+ return aarch64_output_sve_cnt_immediate (prefix, operands, AARCH64_SV_ALL,
value.coeffs[1], 0);
}
+/* Return true if we can add X using a single SVE INC or DEC instruction. */
+
+bool
+aarch64_sve_scalar_inc_dec_immediate_p (rtx x)
+{
+ poly_int64 value;
+ return (poly_int_rtx_p (x, &value)
+ && (aarch64_sve_cnt_immediate_p (value)
+ || aarch64_sve_cnt_immediate_p (-value)));
+}
+
+/* Return the asm string for adding SVE INC/DEC immediate OFFSET to
+ operand 0. */
+
+char *
+aarch64_output_sve_scalar_inc_dec (rtx offset)
+{
+ poly_int64 offset_value = rtx_to_poly_int64 (offset);
+ gcc_assert (offset_value.coeffs[0] == offset_value.coeffs[1]);
+ if (offset_value.coeffs[1] > 0)
+ return aarch64_output_sve_cnt_immediate ("inc", "%x0", AARCH64_SV_ALL,
+ offset_value.coeffs[1], 0);
+ else
+ return aarch64_output_sve_cnt_immediate ("dec", "%x0", AARCH64_SV_ALL,
+ -offset_value.coeffs[1], 0);
+}
+
/* Return true if we can add VALUE to a register using a single ADDVL
or ADDPL instruction. */
@@ -2584,27 +3017,16 @@ aarch64_sve_addvl_addpl_immediate_p (rtx x)
&& aarch64_sve_addvl_addpl_immediate_p (value));
}
-/* Return the asm string for adding ADDVL or ADDPL immediate X to operand 1
- and storing the result in operand 0. */
+/* Return the asm string for adding ADDVL or ADDPL immediate OFFSET
+ to operand 1 and storing the result in operand 0. */
char *
-aarch64_output_sve_addvl_addpl (rtx dest, rtx base, rtx offset)
+aarch64_output_sve_addvl_addpl (rtx offset)
{
static char buffer[sizeof ("addpl\t%x0, %x1, #-") + 3 * sizeof (int)];
poly_int64 offset_value = rtx_to_poly_int64 (offset);
gcc_assert (aarch64_sve_addvl_addpl_immediate_p (offset_value));
- /* Use INC or DEC if possible. */
- if (rtx_equal_p (dest, base) && GP_REGNUM_P (REGNO (dest)))
- {
- if (aarch64_sve_cnt_immediate_p (offset_value))
- return aarch64_output_sve_cnt_immediate ("inc", "%x0",
- offset_value.coeffs[1], 0);
- if (aarch64_sve_cnt_immediate_p (-offset_value))
- return aarch64_output_sve_cnt_immediate ("dec", "%x0",
- -offset_value.coeffs[1], 0);
- }
-
int factor = offset_value.coeffs[1];
if ((factor & 15) == 0)
snprintf (buffer, sizeof (buffer), "addvl\t%%x0, %%x1, #%d", factor / 16);
@@ -2619,8 +3041,8 @@ aarch64_output_sve_addvl_addpl (rtx dest, rtx base, rtx offset)
factor in *FACTOR_OUT (if nonnull). */
bool
-aarch64_sve_inc_dec_immediate_p (rtx x, int *factor_out,
- unsigned int *nelts_per_vq_out)
+aarch64_sve_vector_inc_dec_immediate_p (rtx x, int *factor_out,
+ unsigned int *nelts_per_vq_out)
{
rtx elt;
poly_int64 value;
@@ -2654,9 +3076,9 @@ aarch64_sve_inc_dec_immediate_p (rtx x, int *factor_out,
instruction. */
bool
-aarch64_sve_inc_dec_immediate_p (rtx x)
+aarch64_sve_vector_inc_dec_immediate_p (rtx x)
{
- return aarch64_sve_inc_dec_immediate_p (x, NULL, NULL);
+ return aarch64_sve_vector_inc_dec_immediate_p (x, NULL, NULL);
}
/* Return the asm template for an SVE vector INC or DEC instruction.
@@ -2664,18 +3086,18 @@ aarch64_sve_inc_dec_immediate_p (rtx x)
value of the vector count operand itself. */
char *
-aarch64_output_sve_inc_dec_immediate (const char *operands, rtx x)
+aarch64_output_sve_vector_inc_dec (const char *operands, rtx x)
{
int factor;
unsigned int nelts_per_vq;
- if (!aarch64_sve_inc_dec_immediate_p (x, &factor, &nelts_per_vq))
+ if (!aarch64_sve_vector_inc_dec_immediate_p (x, &factor, &nelts_per_vq))
gcc_unreachable ();
if (factor < 0)
- return aarch64_output_sve_cnt_immediate ("dec", operands, -factor,
- nelts_per_vq);
+ return aarch64_output_sve_cnt_immediate ("dec", operands, AARCH64_SV_ALL,
+ -factor, nelts_per_vq);
else
- return aarch64_output_sve_cnt_immediate ("inc", operands, factor,
- nelts_per_vq);
+ return aarch64_output_sve_cnt_immediate ("inc", operands, AARCH64_SV_ALL,
+ factor, nelts_per_vq);
}
static int
@@ -3058,20 +3480,36 @@ aarch64_add_offset (scalar_int_mode mode, rtx dest, rtx src,
}
else
{
- /* Use CNTD, then multiply it by FACTOR. */
- val = gen_int_mode (poly_int64 (2, 2), mode);
+ /* Base the factor on LOW_BIT if we can calculate LOW_BIT
+ directly, since that should increase the chances of being
+ able to use a shift and add sequence. If LOW_BIT itself
+ is out of range, just use CNTD. */
+ if (low_bit <= 16 * 8)
+ factor /= low_bit;
+ else
+ low_bit = 1;
+
+ val = gen_int_mode (poly_int64 (low_bit * 2, low_bit * 2), mode);
val = aarch64_force_temporary (mode, temp1, val);
- /* Go back to using a negative multiplication factor if we have
- no register from which to subtract. */
- if (code == MINUS && src == const0_rtx)
+ if (can_create_pseudo_p ())
{
- factor = -factor;
- code = PLUS;
+ rtx coeff1 = gen_int_mode (factor, mode);
+ val = expand_mult (mode, val, coeff1, NULL_RTX, false, true);
+ }
+ else
+ {
+ /* Go back to using a negative multiplication factor if we have
+ no register from which to subtract. */
+ if (code == MINUS && src == const0_rtx)
+ {
+ factor = -factor;
+ code = PLUS;
+ }
+ rtx coeff1 = gen_int_mode (factor, mode);
+ coeff1 = aarch64_force_temporary (mode, temp2, coeff1);
+ val = gen_rtx_MULT (mode, val, coeff1);
}
- rtx coeff1 = gen_int_mode (factor, mode);
- coeff1 = aarch64_force_temporary (mode, temp2, coeff1);
- val = gen_rtx_MULT (mode, val, coeff1);
}
if (shift > 0)
@@ -3178,32 +3616,55 @@ aarch64_expand_vec_series (rtx dest, rtx base, rtx step)
emit_set_insn (dest, gen_rtx_VEC_SERIES (mode, base, step));
}
-/* Try to duplicate SRC into SVE register DEST, given that SRC is an
- integer of mode INT_MODE. Return true on success. */
+/* Duplicate 128-bit Advanced SIMD vector SRC so that it fills an SVE
+ register of mode MODE. Use TARGET for the result if it's nonnull
+ and convenient.
-static bool
-aarch64_expand_sve_widened_duplicate (rtx dest, scalar_int_mode src_mode,
- rtx src)
-{
- /* If the constant is smaller than 128 bits, we can do the move
- using a vector of SRC_MODEs. */
- if (src_mode != TImode)
- {
- poly_uint64 count = exact_div (GET_MODE_SIZE (GET_MODE (dest)),
- GET_MODE_SIZE (src_mode));
- machine_mode dup_mode = mode_for_vector (src_mode, count).require ();
- emit_move_insn (gen_lowpart (dup_mode, dest),
- gen_const_vec_duplicate (dup_mode, src));
- return true;
+ The two vector modes must have the same element mode. The behavior
+ is to duplicate architectural lane N of SRC into architectural lanes
+ N + I * STEP of the result. On big-endian targets, architectural
+ lane 0 of an Advanced SIMD vector is the last element of the vector
+ in memory layout, so for big-endian targets this operation has the
+ effect of reversing SRC before duplicating it. Callers need to
+ account for this. */
+
+rtx
+aarch64_expand_sve_dupq (rtx target, machine_mode mode, rtx src)
+{
+ machine_mode src_mode = GET_MODE (src);
+ gcc_assert (GET_MODE_INNER (mode) == GET_MODE_INNER (src_mode));
+ insn_code icode = (BYTES_BIG_ENDIAN
+ ? code_for_aarch64_vec_duplicate_vq_be (mode)
+ : code_for_aarch64_vec_duplicate_vq_le (mode));
+
+ unsigned int i = 0;
+ expand_operand ops[3];
+ create_output_operand (&ops[i++], target, mode);
+ create_output_operand (&ops[i++], src, src_mode);
+ if (BYTES_BIG_ENDIAN)
+ {
+ /* Create a PARALLEL describing the reversal of SRC. */
+ unsigned int nelts_per_vq = 128 / GET_MODE_UNIT_BITSIZE (mode);
+ rtx sel = aarch64_gen_stepped_int_parallel (nelts_per_vq,
+ nelts_per_vq - 1, -1);
+ create_fixed_operand (&ops[i++], sel);
}
+ expand_insn (icode, i, ops);
+ return ops[0].value;
+}
+
+/* Try to force 128-bit vector value SRC into memory and use LD1RQ to fetch
+ the memory image into DEST. Return true on success. */
- /* Use LD1RQ[BHWD] to load the 128 bits from memory. */
- src = force_const_mem (src_mode, src);
+static bool
+aarch64_expand_sve_ld1rq (rtx dest, rtx src)
+{
+ src = force_const_mem (GET_MODE (src), src);
if (!src)
return false;
/* Make sure that the address is legitimate. */
- if (!aarch64_sve_ld1r_operand_p (src))
+ if (!aarch64_sve_ld1rq_operand_p (src))
{
rtx addr = force_reg (Pmode, XEXP (src, 0));
src = replace_equiv_address (src, addr);
@@ -3213,46 +3674,127 @@ aarch64_expand_sve_widened_duplicate (rtx dest, scalar_int_mode src_mode,
unsigned int elem_bytes = GET_MODE_UNIT_SIZE (mode);
machine_mode pred_mode = aarch64_sve_pred_mode (elem_bytes).require ();
rtx ptrue = aarch64_ptrue_reg (pred_mode);
- src = gen_rtx_UNSPEC (mode, gen_rtvec (2, ptrue, src), UNSPEC_LD1RQ);
- emit_insn (gen_rtx_SET (dest, src));
+ emit_insn (gen_aarch64_sve_ld1rq (mode, dest, src, ptrue));
return true;
}
-/* Expand a move of general CONST_VECTOR SRC into DEST, given that it
- isn't a simple duplicate or series. */
+/* Return a register containing CONST_VECTOR SRC, given that SRC has an
+ SVE data mode and isn't a legitimate constant. Use TARGET for the
+ result if convenient.
-static void
-aarch64_expand_sve_const_vector (rtx dest, rtx src)
+ The returned register can have whatever mode seems most natural
+ given the contents of SRC. */
+
+static rtx
+aarch64_expand_sve_const_vector (rtx target, rtx src)
{
machine_mode mode = GET_MODE (src);
unsigned int npatterns = CONST_VECTOR_NPATTERNS (src);
unsigned int nelts_per_pattern = CONST_VECTOR_NELTS_PER_PATTERN (src);
- gcc_assert (npatterns > 1);
+ scalar_mode elt_mode = GET_MODE_INNER (mode);
+ unsigned int elt_bits = GET_MODE_BITSIZE (elt_mode);
+ unsigned int encoded_bits = npatterns * nelts_per_pattern * elt_bits;
+
+ if (nelts_per_pattern == 1 && encoded_bits == 128)
+ {
+ /* The constant is a duplicated quadword but can't be narrowed
+ beyond a quadword. Get the memory image of the first quadword
+ as a 128-bit vector and try using LD1RQ to load it from memory.
+
+ The effect for both endiannesses is to load memory lane N into
+ architectural lanes N + I * STEP of the result. On big-endian
+ targets, the layout of the 128-bit vector in an Advanced SIMD
+ register would be different from its layout in an SVE register,
+ but this 128-bit vector is a memory value only. */
+ machine_mode vq_mode = aarch64_vq_mode (elt_mode).require ();
+ rtx vq_value = simplify_gen_subreg (vq_mode, src, mode, 0);
+ if (vq_value && aarch64_expand_sve_ld1rq (target, vq_value))
+ return target;
+ }
+
+ if (nelts_per_pattern == 1 && encoded_bits < 128)
+ {
+ /* The vector is a repeating sequence of 64 bits or fewer.
+ See if we can load them using an Advanced SIMD move and then
+ duplicate it to fill a vector. This is better than using a GPR
+ move because it keeps everything in the same register file. */
+ machine_mode vq_mode = aarch64_vq_mode (elt_mode).require ();
+ rtx_vector_builder builder (vq_mode, npatterns, 1);
+ for (unsigned int i = 0; i < npatterns; ++i)
+ {
+ /* We want memory lane N to go into architectural lane N,
+ so reverse for big-endian targets. The DUP .Q pattern
+ has a compensating reverse built-in. */
+ unsigned int srci = BYTES_BIG_ENDIAN ? npatterns - i - 1 : i;
+ builder.quick_push (CONST_VECTOR_ENCODED_ELT (src, srci));
+ }
+ rtx vq_src = builder.build ();
+ if (aarch64_simd_valid_immediate (vq_src, NULL))
+ {
+ vq_src = force_reg (vq_mode, vq_src);
+ return aarch64_expand_sve_dupq (target, mode, vq_src);
+ }
- if (nelts_per_pattern == 1)
- {
- /* The constant is a repeating seqeuence of at least two elements,
- where the repeating elements occupy no more than 128 bits.
- Get an integer representation of the replicated value. */
- scalar_int_mode int_mode;
- if (BYTES_BIG_ENDIAN)
- /* For now, always use LD1RQ to load the value on big-endian
- targets, since the handling of smaller integers includes a
- subreg that is semantically an element reverse. */
- int_mode = TImode;
- else
+ /* Get an integer representation of the repeating part of Advanced
+ SIMD vector VQ_SRC. This preserves the endianness of VQ_SRC,
+ which for big-endian targets is lane-swapped wrt a normal
+ Advanced SIMD vector. This means that for both endiannesses,
+ memory lane N of SVE vector SRC corresponds to architectural
+ lane N of a register holding VQ_SRC. This in turn means that
+ memory lane 0 of SVE vector SRC is in the lsb of VQ_SRC (viewed
+ as a single 128-bit value) and thus that memory lane 0 of SRC is
+ in the lsb of the integer. Duplicating the integer therefore
+ ensures that memory lane N of SRC goes into architectural lane
+ N + I * INDEX of the SVE register. */
+ scalar_mode int_mode = int_mode_for_size (encoded_bits, 0).require ();
+ rtx elt_value = simplify_gen_subreg (int_mode, vq_src, vq_mode, 0);
+ if (elt_value)
{
- unsigned int int_bits = GET_MODE_UNIT_BITSIZE (mode) * npatterns;
- gcc_assert (int_bits <= 128);
- int_mode = int_mode_for_size (int_bits, 0).require ();
+ /* Pretend that we had a vector of INT_MODE to start with. */
+ elt_mode = int_mode;
+ mode = aarch64_full_sve_mode (int_mode).require ();
+
+ /* If the integer can be moved into a general register by a
+ single instruction, do that and duplicate the result. */
+ if (CONST_INT_P (elt_value)
+ && aarch64_move_imm (INTVAL (elt_value), elt_mode))
+ {
+ elt_value = force_reg (elt_mode, elt_value);
+ return expand_vector_broadcast (mode, elt_value);
+ }
+ }
+ else if (npatterns == 1)
+ /* We're duplicating a single value, but can't do better than
+ force it to memory and load from there. This handles things
+ like symbolic constants. */
+ elt_value = CONST_VECTOR_ENCODED_ELT (src, 0);
+
+ if (elt_value)
+ {
+ /* Load the element from memory if we can, otherwise move it into
+ a register and use a DUP. */
+ rtx op = force_const_mem (elt_mode, elt_value);
+ if (!op)
+ op = force_reg (elt_mode, elt_value);
+ return expand_vector_broadcast (mode, op);
}
- rtx int_value = simplify_gen_subreg (int_mode, src, mode, 0);
- if (int_value
- && aarch64_expand_sve_widened_duplicate (dest, int_mode, int_value))
- return;
}
+ /* Try using INDEX. */
+ rtx base, step;
+ if (const_vec_series_p (src, &base, &step))
+ {
+ aarch64_expand_vec_series (target, base, step);
+ return target;
+ }
+
+ /* From here on, it's better to force the whole constant to memory
+ if we can. */
+ if (GET_MODE_NUNITS (mode).is_constant ())
+ return NULL_RTX;
+
/* Expand each pattern individually. */
+ gcc_assert (npatterns > 1);
rtx_vector_builder builder;
auto_vec<rtx, 16> vectors (npatterns);
for (unsigned int i = 0; i < npatterns; ++i)
@@ -3269,22 +3811,262 @@ aarch64_expand_sve_const_vector (rtx dest, rtx src)
npatterns /= 2;
for (unsigned int i = 0; i < npatterns; ++i)
{
- rtx tmp = (npatterns == 1 ? dest : gen_reg_rtx (mode));
+ rtx tmp = (npatterns == 1 ? target : gen_reg_rtx (mode));
rtvec v = gen_rtvec (2, vectors[i], vectors[i + npatterns]);
emit_set_insn (tmp, gen_rtx_UNSPEC (mode, v, UNSPEC_ZIP1));
vectors[i] = tmp;
}
}
- gcc_assert (vectors[0] == dest);
+ gcc_assert (vectors[0] == target);
+ return target;
+}
+
+/* Use WHILE to set a predicate register of mode MODE in which the first
+ VL bits are set and the rest are clear. Use TARGET for the register
+ if it's nonnull and convenient. */
+
+static rtx
+aarch64_sve_move_pred_via_while (rtx target, machine_mode mode,
+ unsigned int vl)
+{
+ rtx limit = force_reg (DImode, gen_int_mode (vl, DImode));
+ target = aarch64_target_reg (target, mode);
+ emit_insn (gen_while_ult (DImode, mode, target, const0_rtx, limit));
+ return target;
+}
+
+static rtx
+aarch64_expand_sve_const_pred_1 (rtx, rtx_vector_builder &, bool);
+
+/* BUILDER is a constant predicate in which the index of every set bit
+ is a multiple of ELT_SIZE (which is <= 8). Try to load the constant
+ by inverting every element at a multiple of ELT_SIZE and EORing the
+ result with an ELT_SIZE PTRUE.
+
+ Return a register that contains the constant on success, otherwise
+ return null. Use TARGET as the register if it is nonnull and
+ convenient. */
+
+static rtx
+aarch64_expand_sve_const_pred_eor (rtx target, rtx_vector_builder &builder,
+ unsigned int elt_size)
+{
+ /* Invert every element at a multiple of ELT_SIZE, keeping the
+ other bits zero. */
+ rtx_vector_builder inv_builder (VNx16BImode, builder.npatterns (),
+ builder.nelts_per_pattern ());
+ for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
+ if ((i & (elt_size - 1)) == 0 && INTVAL (builder.elt (i)) == 0)
+ inv_builder.quick_push (const1_rtx);
+ else
+ inv_builder.quick_push (const0_rtx);
+ inv_builder.finalize ();
+
+ /* See if we can load the constant cheaply. */
+ rtx inv = aarch64_expand_sve_const_pred_1 (NULL_RTX, inv_builder, false);
+ if (!inv)
+ return NULL_RTX;
+
+ /* EOR the result with an ELT_SIZE PTRUE. */
+ rtx mask = aarch64_ptrue_all (elt_size);
+ mask = force_reg (VNx16BImode, mask);
+ target = aarch64_target_reg (target, VNx16BImode);
+ emit_insn (gen_aarch64_pred_z (XOR, VNx16BImode, target, mask, inv, mask));
+ return target;
+}
+
+/* BUILDER is a constant predicate in which the index of every set bit
+ is a multiple of ELT_SIZE (which is <= 8). Try to load the constant
+ using a TRN1 of size PERMUTE_SIZE, which is >= ELT_SIZE. Return the
+ register on success, otherwise return null. Use TARGET as the register
+ if nonnull and convenient. */
+
+static rtx
+aarch64_expand_sve_const_pred_trn (rtx target, rtx_vector_builder &builder,
+ unsigned int elt_size,
+ unsigned int permute_size)
+{
+ /* We're going to split the constant into two new constants A and B,
+ with element I of BUILDER going into A if (I & PERMUTE_SIZE) == 0
+ and into B otherwise. E.g. for PERMUTE_SIZE == 4 && ELT_SIZE == 1:
+
+ A: { 0, 1, 2, 3, _, _, _, _, 8, 9, 10, 11, _, _, _, _ }
+ B: { 4, 5, 6, 7, _, _, _, _, 12, 13, 14, 15, _, _, _, _ }
+
+ where _ indicates elements that will be discarded by the permute.
+
+ First calculate the ELT_SIZEs for A and B. */
+ unsigned int a_elt_size = GET_MODE_SIZE (DImode);
+ unsigned int b_elt_size = GET_MODE_SIZE (DImode);
+ for (unsigned int i = 0; i < builder.encoded_nelts (); i += elt_size)
+ if (INTVAL (builder.elt (i)) != 0)
+ {
+ if (i & permute_size)
+ b_elt_size |= i - permute_size;
+ else
+ a_elt_size |= i;
+ }
+ a_elt_size &= -a_elt_size;
+ b_elt_size &= -b_elt_size;
+
+ /* Now construct the vectors themselves. */
+ rtx_vector_builder a_builder (VNx16BImode, builder.npatterns (),
+ builder.nelts_per_pattern ());
+ rtx_vector_builder b_builder (VNx16BImode, builder.npatterns (),
+ builder.nelts_per_pattern ());
+ unsigned int nelts = builder.encoded_nelts ();
+ for (unsigned int i = 0; i < nelts; ++i)
+ if (i & (elt_size - 1))
+ {
+ a_builder.quick_push (const0_rtx);
+ b_builder.quick_push (const0_rtx);
+ }
+ else if ((i & permute_size) == 0)
+ {
+ /* The A and B elements are significant. */
+ a_builder.quick_push (builder.elt (i));
+ b_builder.quick_push (builder.elt (i + permute_size));
+ }
+ else
+ {
+ /* The A and B elements are going to be discarded, so pick whatever
+ is likely to give a nice constant. We are targeting element
+ sizes A_ELT_SIZE and B_ELT_SIZE for A and B respectively,
+ with the aim of each being a sequence of ones followed by
+ a sequence of zeros. So:
+
+ * if X_ELT_SIZE <= PERMUTE_SIZE, the best approach is to
+ duplicate the last X_ELT_SIZE element, to extend the
+ current sequence of ones or zeros.
+
+ * if X_ELT_SIZE > PERMUTE_SIZE, the best approach is to add a
+ zero, so that the constant really does have X_ELT_SIZE and
+ not a smaller size. */
+ if (a_elt_size > permute_size)
+ a_builder.quick_push (const0_rtx);
+ else
+ a_builder.quick_push (a_builder.elt (i - a_elt_size));
+ if (b_elt_size > permute_size)
+ b_builder.quick_push (const0_rtx);
+ else
+ b_builder.quick_push (b_builder.elt (i - b_elt_size));
+ }
+ a_builder.finalize ();
+ b_builder.finalize ();
+
+ /* Try loading A into a register. */
+ rtx_insn *last = get_last_insn ();
+ rtx a = aarch64_expand_sve_const_pred_1 (NULL_RTX, a_builder, false);
+ if (!a)
+ return NULL_RTX;
+
+ /* Try loading B into a register. */
+ rtx b = a;
+ if (a_builder != b_builder)
+ {
+ b = aarch64_expand_sve_const_pred_1 (NULL_RTX, b_builder, false);
+ if (!b)
+ {
+ delete_insns_since (last);
+ return NULL_RTX;
+ }
+ }
+
+ /* Emit the TRN1 itself. */
+ machine_mode mode = aarch64_sve_pred_mode (permute_size).require ();
+ target = aarch64_target_reg (target, mode);
+ emit_insn (gen_aarch64_sve (UNSPEC_TRN1, mode, target,
+ gen_lowpart (mode, a),
+ gen_lowpart (mode, b)));
+ return target;
}
-/* Set DEST to immediate IMM. For SVE vector modes, GEN_VEC_DUPLICATE
- is a pattern that can be used to set DEST to a replicated scalar
- element. */
+/* Subroutine of aarch64_expand_sve_const_pred. Try to load the VNx16BI
+ constant in BUILDER into an SVE predicate register. Return the register
+ on success, otherwise return null. Use TARGET for the register if
+ nonnull and convenient.
+
+ ALLOW_RECURSE_P is true if we can use methods that would call this
+ function recursively. */
+
+static rtx
+aarch64_expand_sve_const_pred_1 (rtx target, rtx_vector_builder &builder,
+ bool allow_recurse_p)
+{
+ if (builder.encoded_nelts () == 1)
+ /* A PFALSE or a PTRUE .B ALL. */
+ return aarch64_emit_set_immediate (target, builder);
+
+ unsigned int elt_size = aarch64_widest_sve_pred_elt_size (builder);
+ if (int vl = aarch64_partial_ptrue_length (builder, elt_size))
+ {
+ /* If we can load the constant using PTRUE, use it as-is. */
+ machine_mode mode = aarch64_sve_pred_mode (elt_size).require ();
+ if (aarch64_svpattern_for_vl (mode, vl) != AARCH64_NUM_SVPATTERNS)
+ return aarch64_emit_set_immediate (target, builder);
+
+ /* Otherwise use WHILE to set the first VL bits. */
+ return aarch64_sve_move_pred_via_while (target, mode, vl);
+ }
+
+ if (!allow_recurse_p)
+ return NULL_RTX;
+
+ /* Try inverting the vector in element size ELT_SIZE and then EORing
+ the result with an ELT_SIZE PTRUE. */
+ if (INTVAL (builder.elt (0)) == 0)
+ if (rtx res = aarch64_expand_sve_const_pred_eor (target, builder,
+ elt_size))
+ return res;
+
+ /* Try using TRN1 to permute two simpler constants. */
+ for (unsigned int i = elt_size; i <= 8; i *= 2)
+ if (rtx res = aarch64_expand_sve_const_pred_trn (target, builder,
+ elt_size, i))
+ return res;
+
+ return NULL_RTX;
+}
+
+/* Return an SVE predicate register that contains the VNx16BImode
+ constant in BUILDER, without going through the move expanders.
+
+ The returned register can have whatever mode seems most natural
+ given the contents of BUILDER. Use TARGET for the result if
+ convenient. */
+
+static rtx
+aarch64_expand_sve_const_pred (rtx target, rtx_vector_builder &builder)
+{
+ /* Try loading the constant using pure predicate operations. */
+ if (rtx res = aarch64_expand_sve_const_pred_1 (target, builder, true))
+ return res;
+
+ /* Try forcing the constant to memory. */
+ if (builder.full_nelts ().is_constant ())
+ if (rtx mem = force_const_mem (VNx16BImode, builder.build ()))
+ {
+ target = aarch64_target_reg (target, VNx16BImode);
+ emit_move_insn (target, mem);
+ return target;
+ }
+
+ /* The last resort is to load the constant as an integer and then
+ compare it against zero. Use -1 for set bits in order to increase
+ the changes of using SVE DUPM or an Advanced SIMD byte mask. */
+ rtx_vector_builder int_builder (VNx16QImode, builder.npatterns (),
+ builder.nelts_per_pattern ());
+ for (unsigned int i = 0; i < builder.encoded_nelts (); ++i)
+ int_builder.quick_push (INTVAL (builder.elt (i))
+ ? constm1_rtx : const0_rtx);
+ return aarch64_convert_sve_data_to_pred (target, VNx16BImode,
+ int_builder.build ());
+}
+
+/* Set DEST to immediate IMM. */
void
-aarch64_expand_mov_immediate (rtx dest, rtx imm,
- rtx (*gen_vec_duplicate) (rtx, rtx))
+aarch64_expand_mov_immediate (rtx dest, rtx imm)
{
machine_mode mode = GET_MODE (dest);
@@ -3407,38 +4189,50 @@ aarch64_expand_mov_immediate (rtx dest, rtx imm,
if (!CONST_INT_P (imm))
{
- rtx base, step, value;
- if (GET_CODE (imm) == HIGH
- || aarch64_simd_valid_immediate (imm, NULL))
- emit_insn (gen_rtx_SET (dest, imm));
- else if (const_vec_series_p (imm, &base, &step))
- aarch64_expand_vec_series (dest, base, step);
- else if (const_vec_duplicate_p (imm, &value))
+ if (GET_MODE_CLASS (mode) == MODE_VECTOR_BOOL)
{
- /* If the constant is out of range of an SVE vector move,
- load it from memory if we can, otherwise move it into
- a register and use a DUP. */
- scalar_mode inner_mode = GET_MODE_INNER (mode);
- rtx op = force_const_mem (inner_mode, value);
- if (!op)
- op = force_reg (inner_mode, value);
- else if (!aarch64_sve_ld1r_operand_p (op))
+ /* Only the low bit of each .H, .S and .D element is defined,
+ so we can set the upper bits to whatever we like. If the
+ predicate is all-true in MODE, prefer to set all the undefined
+ bits as well, so that we can share a single .B predicate for
+ all modes. */
+ if (imm == CONSTM1_RTX (mode))
+ imm = CONSTM1_RTX (VNx16BImode);
+
+ /* All methods for constructing predicate modes wider than VNx16BI
+ will set the upper bits of each element to zero. Expose this
+ by moving such constants as a VNx16BI, so that all bits are
+ significant and so that constants for different modes can be
+ shared. The wider constant will still be available as a
+ REG_EQUAL note. */
+ rtx_vector_builder builder;
+ if (aarch64_get_sve_pred_bits (builder, imm))
{
- rtx addr = force_reg (Pmode, XEXP (op, 0));
- op = replace_equiv_address (op, addr);
+ rtx res = aarch64_expand_sve_const_pred (dest, builder);
+ if (dest != res)
+ emit_move_insn (dest, gen_lowpart (mode, res));
+ return;
}
- emit_insn (gen_vec_duplicate (dest, op));
}
- else if (GET_CODE (imm) == CONST_VECTOR
- && !GET_MODE_NUNITS (GET_MODE (imm)).is_constant ())
- aarch64_expand_sve_const_vector (dest, imm);
- else
+
+ if (GET_CODE (imm) == HIGH
+ || aarch64_simd_valid_immediate (imm, NULL))
{
- rtx mem = force_const_mem (mode, imm);
- gcc_assert (mem);
- emit_move_insn (dest, mem);
+ emit_insn (gen_rtx_SET (dest, imm));
+ return;
}
+ if (GET_CODE (imm) == CONST_VECTOR && aarch64_sve_data_mode_p (mode))
+ if (rtx res = aarch64_expand_sve_const_vector (dest, imm))
+ {
+ if (dest != res)
+ emit_insn (gen_aarch64_sve_reinterpret (mode, dest, res));
+ return;
+ }
+
+ rtx mem = force_const_mem (mode, imm);
+ gcc_assert (mem);
+ emit_move_insn (dest, mem);
return;
}
@@ -3560,14 +4354,29 @@ aarch64_replace_reg_mode (rtx x, machine_mode mode)
return x;
}
+/* Return the SVE REV[BHW] unspec for reversing quantites of mode MODE
+ stored in wider integer containers. */
+
+static unsigned int
+aarch64_sve_rev_unspec (machine_mode mode)
+{
+ switch (GET_MODE_UNIT_SIZE (mode))
+ {
+ case 1: return UNSPEC_REVB;
+ case 2: return UNSPEC_REVH;
+ case 4: return UNSPEC_REVW;
+ }
+ gcc_unreachable ();
+}
+
/* Split a *aarch64_sve_mov<mode>_subreg_be pattern with the given
operands. */
void
aarch64_split_sve_subreg_move (rtx dest, rtx ptrue, rtx src)
{
- /* Decide which REV operation we need. The mode with narrower elements
- determines the mode of the operands and the mode with the wider
+ /* Decide which REV operation we need. The mode with wider elements
+ determines the mode of the operands and the mode with the narrower
elements determines the reverse width. */
machine_mode mode_with_wider_elts = GET_MODE (dest);
machine_mode mode_with_narrower_elts = GET_MODE (src);
@@ -3575,31 +4384,16 @@ aarch64_split_sve_subreg_move (rtx dest, rtx ptrue, rtx src)
< GET_MODE_UNIT_SIZE (mode_with_narrower_elts))
std::swap (mode_with_wider_elts, mode_with_narrower_elts);
+ unsigned int unspec = aarch64_sve_rev_unspec (mode_with_narrower_elts);
unsigned int wider_bytes = GET_MODE_UNIT_SIZE (mode_with_wider_elts);
- unsigned int unspec;
- if (wider_bytes == 8)
- unspec = UNSPEC_REV64;
- else if (wider_bytes == 4)
- unspec = UNSPEC_REV32;
- else if (wider_bytes == 2)
- unspec = UNSPEC_REV16;
- else
- gcc_unreachable ();
machine_mode pred_mode = aarch64_sve_pred_mode (wider_bytes).require ();
- /* Emit:
-
- (set DEST (unspec [PTRUE (unspec [SRC] UNSPEC_REV<nn>)]
- UNSPEC_MERGE_PTRUE))
-
- with the appropriate modes. */
+ /* Get the operands in the appropriate modes and emit the instruction. */
ptrue = gen_lowpart (pred_mode, ptrue);
- dest = aarch64_replace_reg_mode (dest, mode_with_narrower_elts);
- src = aarch64_replace_reg_mode (src, mode_with_narrower_elts);
- src = gen_rtx_UNSPEC (mode_with_narrower_elts, gen_rtvec (1, src), unspec);
- src = gen_rtx_UNSPEC (mode_with_narrower_elts, gen_rtvec (2, ptrue, src),
- UNSPEC_MERGE_PTRUE);
- emit_insn (gen_rtx_SET (dest, src));
+ dest = aarch64_replace_reg_mode (dest, mode_with_wider_elts);
+ src = aarch64_replace_reg_mode (src, mode_with_wider_elts);
+ emit_insn (gen_aarch64_pred (unspec, mode_with_wider_elts,
+ dest, ptrue, src));
}
static bool
@@ -7566,15 +8360,24 @@ aarch64_print_vector_float_operand (FILE *f, rtx x, bool negate)
if (negate)
r = real_value_negate (&r);
- /* We only handle the SVE single-bit immediates here. */
+ /* Handle the SVE single-bit immediates specially, since they have a
+ fixed form in the assembly syntax. */
if (real_equal (&r, &dconst0))
asm_fprintf (f, "0.0");
+ else if (real_equal (&r, &dconst2))
+ asm_fprintf (f, "2.0");
else if (real_equal (&r, &dconst1))
asm_fprintf (f, "1.0");
else if (real_equal (&r, &dconsthalf))
asm_fprintf (f, "0.5");
else
- return false;
+ {
+ const int buf_size = 20;
+ char float_buf[buf_size] = {'\0'};
+ real_to_decimal_for_mode (float_buf, &r, buf_size, buf_size,
+ 1, GET_MODE (elt));
+ asm_fprintf (f, "%s", float_buf);
+ }
return true;
}
@@ -7602,7 +8405,13 @@ sizetochar (int size)
'D': Take the duplicated element in a vector constant
and print it as an unsigned integer, in decimal.
'e': Print the sign/zero-extend size as a character 8->b,
- 16->h, 32->w.
+ 16->h, 32->w. Can also be used for masks:
+ 0xff->b, 0xffff->h, 0xffffffff->w.
+ 'I': If the operand is a duplicated vector constant,
+ replace it with the duplicated scalar. If the
+ operand is then a floating-point constant, replace
+ it with the integer bit representation. Print the
+ transformed constant as a signed decimal number.
'p': Prints N such that 2^N == X (X must be power of 2 and
const int).
'P': Print the number of non-zero bits in X (a const_int).
@@ -7668,27 +8477,22 @@ aarch64_print_operand (FILE *f, rtx x, int code)
case 'e':
{
- int n;
-
- if (!CONST_INT_P (x)
- || (n = exact_log2 (INTVAL (x) & ~7)) <= 0)
+ x = unwrap_const_vec_duplicate (x);
+ if (!CONST_INT_P (x))
{
output_operand_lossage ("invalid operand for '%%%c'", code);
return;
}
- switch (n)
+ HOST_WIDE_INT val = INTVAL (x);
+ if ((val & ~7) == 8 || val == 0xff)
+ fputc ('b', f);
+ else if ((val & ~7) == 16 || val == 0xffff)
+ fputc ('h', f);
+ else if ((val & ~7) == 32 || val == 0xffffffff)
+ fputc ('w', f);
+ else
{
- case 3:
- fputc ('b', f);
- break;
- case 4:
- fputc ('h', f);
- break;
- case 5:
- fputc ('w', f);
- break;
- default:
output_operand_lossage ("invalid operand for '%%%c'", code);
return;
}
@@ -7735,6 +8539,19 @@ aarch64_print_operand (FILE *f, rtx x, int code)
asm_fprintf (f, "%s", reg_names [REGNO (x) + 1]);
break;
+ case 'I':
+ {
+ x = aarch64_bit_representation (unwrap_const_vec_duplicate (x));
+ if (CONST_INT_P (x))
+ asm_fprintf (f, "%wd", INTVAL (x));
+ else
+ {
+ output_operand_lossage ("invalid operand for '%%%c'", code);
+ return;
+ }
+ break;
+ }
+
case 'M':
case 'm':
{
@@ -8279,7 +9096,8 @@ aarch64_regno_regclass (unsigned regno)
return POINTER_REGS;
if (FP_REGNUM_P (regno))
- return FP_LO_REGNUM_P (regno) ? FP_LO_REGS : FP_REGS;
+ return (FP_LO8_REGNUM_P (regno) ? FP_LO8_REGS
+ : FP_LO_REGNUM_P (regno) ? FP_LO_REGS : FP_REGS);
if (PR_REGNUM_P (regno))
return PR_LO_REGNUM_P (regno) ? PR_LO_REGS : PR_HI_REGS;
@@ -8569,6 +9387,7 @@ aarch64_class_max_nregs (reg_class_t regclass, machine_mode mode)
case POINTER_AND_FP_REGS:
case FP_REGS:
case FP_LO_REGS:
+ case FP_LO8_REGS:
if (aarch64_sve_data_mode_p (mode)
&& constant_multiple_p (GET_MODE_SIZE (mode),
BYTES_PER_SVE_VECTOR, &nregs))
@@ -10832,7 +11651,7 @@ aarch64_builtin_reciprocal (tree fndecl)
if (!use_rsqrt_p (mode))
return NULL_TREE;
- return aarch64_builtin_rsqrt (DECL_FUNCTION_CODE (fndecl));
+ return aarch64_builtin_rsqrt (DECL_MD_FUNCTION_CODE (fndecl));
}
/* Emit instruction sequence to compute either the approximate square root
@@ -14106,55 +14925,71 @@ aarch64_vector_mode_supported_p (machine_mode mode)
return vec_flags != 0 && (vec_flags & VEC_STRUCT) == 0;
}
+/* Return the full-width SVE vector mode for element mode MODE, if one
+ exists. */
+opt_machine_mode
+aarch64_full_sve_mode (scalar_mode mode)
+{
+ switch (mode)
+ {
+ case E_DFmode:
+ return VNx2DFmode;
+ case E_SFmode:
+ return VNx4SFmode;
+ case E_HFmode:
+ return VNx8HFmode;
+ case E_DImode:
+ return VNx2DImode;
+ case E_SImode:
+ return VNx4SImode;
+ case E_HImode:
+ return VNx8HImode;
+ case E_QImode:
+ return VNx16QImode;
+ default:
+ return opt_machine_mode ();
+ }
+}
+
+/* Return the 128-bit Advanced SIMD vector mode for element mode MODE,
+ if it exists. */
+opt_machine_mode
+aarch64_vq_mode (scalar_mode mode)
+{
+ switch (mode)
+ {
+ case E_DFmode:
+ return V2DFmode;
+ case E_SFmode:
+ return V4SFmode;
+ case E_HFmode:
+ return V8HFmode;
+ case E_SImode:
+ return V4SImode;
+ case E_HImode:
+ return V8HImode;
+ case E_QImode:
+ return V16QImode;
+ case E_DImode:
+ return V2DImode;
+ default:
+ return opt_machine_mode ();
+ }
+}
+
/* Return appropriate SIMD container
for MODE within a vector of WIDTH bits. */
static machine_mode
aarch64_simd_container_mode (scalar_mode mode, poly_int64 width)
{
if (TARGET_SVE && known_eq (width, BITS_PER_SVE_VECTOR))
- switch (mode)
- {
- case E_DFmode:
- return VNx2DFmode;
- case E_SFmode:
- return VNx4SFmode;
- case E_HFmode:
- return VNx8HFmode;
- case E_DImode:
- return VNx2DImode;
- case E_SImode:
- return VNx4SImode;
- case E_HImode:
- return VNx8HImode;
- case E_QImode:
- return VNx16QImode;
- default:
- return word_mode;
- }
+ return aarch64_full_sve_mode (mode).else_mode (word_mode);
gcc_assert (known_eq (width, 64) || known_eq (width, 128));
if (TARGET_SIMD)
{
if (known_eq (width, 128))
- switch (mode)
- {
- case E_DFmode:
- return V2DFmode;
- case E_SFmode:
- return V4SFmode;
- case E_HFmode:
- return V8HFmode;
- case E_SImode:
- return V4SImode;
- case E_HImode:
- return V8HImode;
- case E_QImode:
- return V16QImode;
- case E_DImode:
- return V2DImode;
- default:
- break;
- }
+ return aarch64_vq_mode (mode).else_mode (word_mode);
else
switch (mode)
{
@@ -14389,13 +15224,11 @@ aarch64_sve_bitmask_immediate_p (rtx x)
bool
aarch64_sve_dup_immediate_p (rtx x)
{
- rtx elt;
-
- if (!const_vec_duplicate_p (x, &elt)
- || !CONST_INT_P (elt))
+ x = aarch64_bit_representation (unwrap_const_vec_duplicate (x));
+ if (!CONST_INT_P (x))
return false;
- HOST_WIDE_INT val = INTVAL (elt);
+ HOST_WIDE_INT val = INTVAL (x);
if (val & 0xff)
return IN_RANGE (val, -0x80, 0x7f);
return IN_RANGE (val, -0x8000, 0x7f00);
@@ -14449,11 +15282,10 @@ aarch64_sve_float_mul_immediate_p (rtx x)
{
rtx elt;
- /* GCC will never generate a multiply with an immediate of 2, so there is no
- point testing for it (even though it is a valid constant). */
return (const_vec_duplicate_p (x, &elt)
&& GET_CODE (elt) == CONST_DOUBLE
- && real_equal (CONST_DOUBLE_REAL_VALUE (elt), &dconsthalf));
+ && (real_equal (CONST_DOUBLE_REAL_VALUE (elt), &dconsthalf)
+ || real_equal (CONST_DOUBLE_REAL_VALUE (elt), &dconst2)));
}
/* Return true if replicating VAL32 is a valid 2-byte or 4-byte immediate
@@ -14606,6 +15438,44 @@ aarch64_sve_valid_immediate (unsigned HOST_WIDE_INT val64,
return false;
}
+/* Return true if X is a valid SVE predicate. If INFO is nonnull, use
+ it to describe valid immediates. */
+
+static bool
+aarch64_sve_pred_valid_immediate (rtx x, simd_immediate_info *info)
+{
+ if (x == CONST0_RTX (GET_MODE (x)))
+ {
+ if (info)
+ *info = simd_immediate_info (DImode, 0);
+ return true;
+ }
+
+ /* Analyze the value as a VNx16BImode. This should be relatively
+ efficient, since rtx_vector_builder has enough built-in capacity
+ to store all VLA predicate constants without needing the heap. */
+ rtx_vector_builder builder;
+ if (!aarch64_get_sve_pred_bits (builder, x))
+ return false;
+
+ unsigned int elt_size = aarch64_widest_sve_pred_elt_size (builder);
+ if (int vl = aarch64_partial_ptrue_length (builder, elt_size))
+ {
+ machine_mode mode = aarch64_sve_pred_mode (elt_size).require ();
+ aarch64_svpattern pattern = aarch64_svpattern_for_vl (mode, vl);
+ if (pattern != AARCH64_NUM_SVPATTERNS)
+ {
+ if (info)
+ {
+ scalar_int_mode int_mode = aarch64_sve_element_int_mode (mode);
+ *info = simd_immediate_info (int_mode, pattern);
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
/* Return true if OP is a valid SIMD immediate for the operation
described by WHICH. If INFO is nonnull, use it to describe valid
immediates. */
@@ -14618,6 +15488,9 @@ aarch64_simd_valid_immediate (rtx op, simd_immediate_info *info,
if (vec_flags == 0 || vec_flags == (VEC_ADVSIMD | VEC_STRUCT))
return false;
+ if (vec_flags & VEC_SVE_PRED)
+ return aarch64_sve_pred_valid_immediate (op, info);
+
scalar_mode elt_mode = GET_MODE_INNER (mode);
rtx base, step;
unsigned int n_elts;
@@ -14642,11 +15515,6 @@ aarch64_simd_valid_immediate (rtx op, simd_immediate_info *info,
else
return false;
- /* Handle PFALSE and PTRUE. */
- if (vec_flags & VEC_SVE_PRED)
- return (op == CONST0_RTX (mode)
- || op == CONSTM1_RTX (mode));
-
scalar_float_mode elt_float_mode;
if (n_elts == 1
&& is_a <scalar_float_mode> (elt_mode, &elt_float_mode))
@@ -14762,7 +15630,17 @@ aarch64_mov_operand_p (rtx x, machine_mode mode)
return true;
if (VECTOR_MODE_P (GET_MODE (x)))
- return aarch64_simd_valid_immediate (x, NULL);
+ {
+ /* Require predicate constants to be VNx16BI before RA, so that we
+ force everything to have a canonical form. */
+ if (!lra_in_progress
+ && !reload_completed
+ && GET_MODE_CLASS (GET_MODE (x)) == MODE_VECTOR_BOOL
+ && GET_MODE (x) != VNx16BImode)
+ return false;
+
+ return aarch64_simd_valid_immediate (x, NULL);
+ }
if (GET_CODE (x) == SYMBOL_REF && mode == DImode && CONSTANT_ADDRESS_P (x))
return true;
@@ -14870,6 +15748,36 @@ aarch64_simd_check_vect_par_cnst_half (rtx op, machine_mode mode,
return true;
}
+/* Return a PARALLEL containing NELTS elements, with element I equal
+ to BASE + I * STEP. */
+
+rtx
+aarch64_gen_stepped_int_parallel (unsigned int nelts, int base, int step)
+{
+ rtvec vec = rtvec_alloc (nelts);
+ for (unsigned int i = 0; i < nelts; ++i)
+ RTVEC_ELT (vec, i) = gen_int_mode (base + i * step, DImode);
+ return gen_rtx_PARALLEL (VOIDmode, vec);
+}
+
+/* Return true if OP is a PARALLEL of CONST_INTs that form a linear
+ series with step STEP. */
+
+bool
+aarch64_stepped_int_parallel_p (rtx op, int step)
+{
+ if (GET_CODE (op) != PARALLEL || !CONST_INT_P (XVECEXP (op, 0, 0)))
+ return false;
+
+ unsigned HOST_WIDE_INT base = UINTVAL (XVECEXP (op, 0, 0));
+ for (int i = 1; i < XVECLEN (op, 0); ++i)
+ if (!CONST_INT_P (XVECEXP (op, 0, i))
+ || UINTVAL (XVECEXP (op, 0, i)) != base + i * step)
+ return false;
+
+ return true;
+}
+
/* Bounds-check lanes. Ensure OPERAND lies between LOW (inclusive) and
HIGH (exclusive). */
void
@@ -14922,6 +15830,25 @@ aarch64_sve_ld1r_operand_p (rtx op)
&& offset_6bit_unsigned_scaled_p (mode, addr.const_offset));
}
+/* Return true if OP is a valid MEM operand for an SVE LD1RQ instruction. */
+bool
+aarch64_sve_ld1rq_operand_p (rtx op)
+{
+ struct aarch64_address_info addr;
+ scalar_mode elem_mode = GET_MODE_INNER (GET_MODE (op));
+ if (!MEM_P (op)
+ || !aarch64_classify_address (&addr, XEXP (op, 0), elem_mode, false))
+ return false;
+
+ if (addr.type == ADDRESS_REG_IMM)
+ return offset_4bit_signed_scaled_p (TImode, addr.const_offset);
+
+ if (addr.type == ADDRESS_REG_REG)
+ return (1U << addr.shift) == GET_MODE_SIZE (elem_mode);
+
+ return false;
+}
+
/* Return true if OP is a valid MEM operand for an SVE LDR instruction.
The conditions for STR are the same. */
bool
@@ -14996,11 +15923,13 @@ aarch64_simd_attr_length_rglist (machine_mode mode)
static HOST_WIDE_INT
aarch64_simd_vector_alignment (const_tree type)
{
+ /* ??? Checking the mode isn't ideal, but VECTOR_BOOLEAN_TYPE_P can
+ be set for non-predicate vectors of booleans. Modes are the most
+ direct way we have of identifying real SVE predicate types. */
+ if (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_VECTOR_BOOL)
+ return 16;
if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
- /* ??? Checking the mode isn't ideal, but VECTOR_BOOLEAN_TYPE_P can
- be set for non-predicate vectors of booleans. Modes are the most
- direct way we have of identifying real SVE predicate types. */
- return GET_MODE_CLASS (TYPE_MODE (type)) == MODE_VECTOR_BOOL ? 16 : 128;
+ return 128;
return wi::umin (wi::to_wide (TYPE_SIZE (type)), 128).to_uhwi ();
}
@@ -15617,6 +16546,98 @@ aarch64_sve_expand_vector_init (rtx target, rtx vals)
aarch64_sve_expand_vector_init_insert_elems (target, v, nelts);
}
+/* Check whether VALUE is a vector constant in which every element
+ is either a power of 2 or a negated power of 2. If so, return
+ a constant vector of log2s, and flip CODE between PLUS and MINUS
+ if VALUE contains negated powers of 2. Return NULL_RTX otherwise. */
+
+static rtx
+aarch64_convert_mult_to_shift (rtx value, rtx_code &code)
+{
+ if (GET_CODE (value) != CONST_VECTOR)
+ return NULL_RTX;
+
+ rtx_vector_builder builder;
+ if (!builder.new_unary_operation (GET_MODE (value), value, false))
+ return NULL_RTX;
+
+ scalar_mode int_mode = GET_MODE_INNER (GET_MODE (value));
+ /* 1 if the result of the multiplication must be negated,
+ 0 if it mustn't, or -1 if we don't yet care. */
+ int negate = -1;
+ unsigned int encoded_nelts = const_vector_encoded_nelts (value);
+ for (unsigned int i = 0; i < encoded_nelts; ++i)
+ {
+ rtx elt = CONST_VECTOR_ENCODED_ELT (value, i);
+ if (!CONST_SCALAR_INT_P (elt))
+ return NULL_RTX;
+ rtx_mode_t val (elt, int_mode);
+ wide_int pow2 = wi::neg (val);
+ if (val != pow2)
+ {
+ /* It matters whether we negate or not. Make that choice,
+ and make sure that it's consistent with previous elements. */
+ if (negate == !wi::neg_p (val))
+ return NULL_RTX;
+ negate = wi::neg_p (val);
+ if (!negate)
+ pow2 = val;
+ }
+ /* POW2 is now the value that we want to be a power of 2. */
+ int shift = wi::exact_log2 (pow2);
+ if (shift < 0)
+ return NULL_RTX;
+ builder.quick_push (gen_int_mode (shift, int_mode));
+ }
+ if (negate == -1)
+ /* PLUS and MINUS are equivalent; canonicalize on PLUS. */
+ code = PLUS;
+ else if (negate == 1)
+ code = code == PLUS ? MINUS : PLUS;
+ return builder.build ();
+}
+
+/* Prepare for an integer SVE multiply-add or multiply-subtract pattern;
+ CODE is PLUS for the former and MINUS for the latter. OPERANDS is the
+ operands array, in the same order as for fma_optab. Return true if
+ the function emitted all the necessary instructions, false if the caller
+ should generate the pattern normally with the new OPERANDS array. */
+
+bool
+aarch64_prepare_sve_int_fma (rtx *operands, rtx_code code)
+{
+ machine_mode mode = GET_MODE (operands[0]);
+ if (rtx shifts = aarch64_convert_mult_to_shift (operands[2], code))
+ {
+ rtx product = expand_binop (mode, vashl_optab, operands[1], shifts,
+ NULL_RTX, true, OPTAB_DIRECT);
+ force_expand_binop (mode, code == PLUS ? add_optab : sub_optab,
+ operands[3], product, operands[0], true,
+ OPTAB_DIRECT);
+ return true;
+ }
+ operands[2] = force_reg (mode, operands[2]);
+ return false;
+}
+
+/* Likewise, but for a conditional pattern. */
+
+bool
+aarch64_prepare_sve_cond_int_fma (rtx *operands, rtx_code code)
+{
+ machine_mode mode = GET_MODE (operands[0]);
+ if (rtx shifts = aarch64_convert_mult_to_shift (operands[3], code))
+ {
+ rtx product = expand_binop (mode, vashl_optab, operands[2], shifts,
+ NULL_RTX, true, OPTAB_DIRECT);
+ emit_insn (gen_cond (code, mode, operands[0], operands[1],
+ operands[4], product, operands[5]));
+ return true;
+ }
+ operands[3] = force_reg (mode, operands[3]);
+ return false;
+}
+
static unsigned HOST_WIDE_INT
aarch64_shift_truncation_mask (machine_mode mode)
{
@@ -16143,6 +17164,7 @@ aarch64_float_const_representable_p (rtx x)
REAL_VALUE_TYPE r, m;
bool fail;
+ x = unwrap_const_vec_duplicate (x);
if (!CONST_DOUBLE_P (x))
return false;
@@ -16238,17 +17260,18 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width,
if (GET_MODE_CLASS (info.elt_mode) == MODE_FLOAT)
{
- gcc_assert (info.shift == 0 && info.insn == simd_immediate_info::MOV);
+ gcc_assert (info.insn == simd_immediate_info::MOV
+ && info.u.mov.shift == 0);
/* For FP zero change it to a CONST_INT 0 and use the integer SIMD
move immediate path. */
- if (aarch64_float_const_zero_rtx_p (info.value))
- info.value = GEN_INT (0);
+ if (aarch64_float_const_zero_rtx_p (info.u.mov.value))
+ info.u.mov.value = GEN_INT (0);
else
{
const unsigned int buf_size = 20;
char float_buf[buf_size] = {'\0'};
real_to_decimal_for_mode (float_buf,
- CONST_DOUBLE_REAL_VALUE (info.value),
+ CONST_DOUBLE_REAL_VALUE (info.u.mov.value),
buf_size, buf_size, 1, info.elt_mode);
if (lane_count == 1)
@@ -16260,36 +17283,39 @@ aarch64_output_simd_mov_immediate (rtx const_vector, unsigned width,
}
}
- gcc_assert (CONST_INT_P (info.value));
+ gcc_assert (CONST_INT_P (info.u.mov.value));
if (which == AARCH64_CHECK_MOV)
{
mnemonic = info.insn == simd_immediate_info::MVN ? "mvni" : "movi";
- shift_op = info.modifier == simd_immediate_info::MSL ? "msl" : "lsl";
+ shift_op = (info.u.mov.modifier == simd_immediate_info::MSL
+ ? "msl" : "lsl");
if (lane_count == 1)
snprintf (templ, sizeof (templ), "%s\t%%d0, " HOST_WIDE_INT_PRINT_HEX,
- mnemonic, UINTVAL (info.value));
- else if (info.shift)
+ mnemonic, UINTVAL (info.u.mov.value));
+ else if (info.u.mov.shift)
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, "
HOST_WIDE_INT_PRINT_HEX ", %s %d", mnemonic, lane_count,
- element_char, UINTVAL (info.value), shift_op, info.shift);
+ element_char, UINTVAL (info.u.mov.value), shift_op,
+ info.u.mov.shift);
else
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, "
HOST_WIDE_INT_PRINT_HEX, mnemonic, lane_count,
- element_char, UINTVAL (info.value));
+ element_char, UINTVAL (info.u.mov.value));
}
else
{
/* For AARCH64_CHECK_BIC and AARCH64_CHECK_ORR. */
mnemonic = info.insn == simd_immediate_info::MVN ? "bic" : "orr";
- if (info.shift)
+ if (info.u.mov.shift)
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #"
HOST_WIDE_INT_PRINT_DEC ", %s #%d", mnemonic, lane_count,
- element_char, UINTVAL (info.value), "lsl", info.shift);
+ element_char, UINTVAL (info.u.mov.value), "lsl",
+ info.u.mov.shift);
else
snprintf (templ, sizeof (templ), "%s\t%%0.%d%c, #"
HOST_WIDE_INT_PRINT_DEC, mnemonic, lane_count,
- element_char, UINTVAL (info.value));
+ element_char, UINTVAL (info.u.mov.value));
}
return templ;
}
@@ -16333,24 +17359,49 @@ aarch64_output_sve_mov_immediate (rtx const_vector)
element_char = sizetochar (GET_MODE_BITSIZE (info.elt_mode));
- if (info.step)
+ machine_mode vec_mode = GET_MODE (const_vector);
+ if (aarch64_sve_pred_mode_p (vec_mode))
+ {
+ static char buf[sizeof ("ptrue\t%0.N, vlNNNNN")];
+ if (info.insn == simd_immediate_info::MOV)
+ {
+ gcc_assert (info.u.mov.value == const0_rtx);
+ snprintf (buf, sizeof (buf), "pfalse\t%%0.b");
+ }
+ else
+ {
+ gcc_assert (info.insn == simd_immediate_info::PTRUE);
+ unsigned int total_bytes;
+ if (info.u.pattern == AARCH64_SV_ALL
+ && BYTES_PER_SVE_VECTOR.is_constant (&total_bytes))
+ snprintf (buf, sizeof (buf), "ptrue\t%%0.%c, vl%d", element_char,
+ total_bytes / GET_MODE_SIZE (info.elt_mode));
+ else
+ snprintf (buf, sizeof (buf), "ptrue\t%%0.%c, %s", element_char,
+ svpattern_token (info.u.pattern));
+ }
+ return buf;
+ }
+
+ if (info.insn == simd_immediate_info::INDEX)
{
snprintf (templ, sizeof (templ), "index\t%%0.%c, #"
HOST_WIDE_INT_PRINT_DEC ", #" HOST_WIDE_INT_PRINT_DEC,
- element_char, INTVAL (info.value), INTVAL (info.step));
+ element_char, INTVAL (info.u.index.base),
+ INTVAL (info.u.index.step));
return templ;
}
if (GET_MODE_CLASS (info.elt_mode) == MODE_FLOAT)
{
- if (aarch64_float_const_zero_rtx_p (info.value))
- info.value = GEN_INT (0);
+ if (aarch64_float_const_zero_rtx_p (info.u.mov.value))
+ info.u.mov.value = GEN_INT (0);
else
{
const int buf_size = 20;
char float_buf[buf_size] = {};
real_to_decimal_for_mode (float_buf,
- CONST_DOUBLE_REAL_VALUE (info.value),
+ CONST_DOUBLE_REAL_VALUE (info.u.mov.value),
buf_size, buf_size, 1, info.elt_mode);
snprintf (templ, sizeof (templ), "fmov\t%%0.%c, #%s",
@@ -16360,25 +17411,10 @@ aarch64_output_sve_mov_immediate (rtx const_vector)
}
snprintf (templ, sizeof (templ), "mov\t%%0.%c, #" HOST_WIDE_INT_PRINT_DEC,
- element_char, INTVAL (info.value));
+ element_char, INTVAL (info.u.mov.value));
return templ;
}
-/* Return the asm format for a PTRUE instruction whose destination has
- mode MODE. SUFFIX is the element size suffix. */
-
-char *
-aarch64_output_ptrue (machine_mode mode, char suffix)
-{
- unsigned int nunits;
- static char buf[sizeof ("ptrue\t%0.N, vlNNNNN")];
- if (GET_MODE_NUNITS (mode).is_constant (&nunits))
- snprintf (buf, sizeof (buf), "ptrue\t%%0.%c, vl%d", suffix, nunits);
- else
- snprintf (buf, sizeof (buf), "ptrue\t%%0.%c, all", suffix);
- return buf;
-}
-
/* Split operands into moves from op[1] + op[2] into op[0]. */
void
@@ -16794,13 +17830,31 @@ aarch64_evpc_rev_local (struct expand_vec_perm_d *d)
if (d->testing_p)
return true;
- rtx src = gen_rtx_UNSPEC (d->vmode, gen_rtvec (1, d->op0), unspec);
if (d->vec_flags == VEC_SVE_DATA)
{
- rtx pred = aarch64_ptrue_reg (pred_mode);
- src = gen_rtx_UNSPEC (d->vmode, gen_rtvec (2, pred, src),
- UNSPEC_MERGE_PTRUE);
+ machine_mode int_mode = aarch64_sve_int_mode (pred_mode);
+ rtx target = gen_reg_rtx (int_mode);
+ if (BYTES_BIG_ENDIAN)
+ /* The act of taking a subreg between INT_MODE and d->vmode
+ is itself a reversing operation on big-endian targets;
+ see the comment at the head of aarch64-sve.md for details.
+ First reinterpret OP0 as INT_MODE without using a subreg
+ and without changing the contents. */
+ emit_insn (gen_aarch64_sve_reinterpret (int_mode, target, d->op0));
+ else
+ {
+ /* For SVE we use REV[BHW] unspecs derived from the element size
+ of v->mode and vector modes whose elements have SIZE bytes.
+ This ensures that the vector modes match the predicate modes. */
+ int unspec = aarch64_sve_rev_unspec (d->vmode);
+ rtx pred = aarch64_ptrue_reg (pred_mode);
+ emit_insn (gen_aarch64_pred (unspec, int_mode, target, pred,
+ gen_lowpart (int_mode, d->op0)));
+ }
+ emit_move_insn (d->target, gen_lowpart (d->vmode, target));
+ return true;
}
+ rtx src = gen_rtx_UNSPEC (d->vmode, gen_rtvec (1, d->op0), unspec);
emit_set_insn (d->target, src);
return true;
}
@@ -17033,60 +18087,19 @@ aarch64_reverse_mask (machine_mode mode, unsigned int nunits)
return force_reg (V16QImode, mask);
}
-/* Return true if X is a valid second operand for the SVE instruction
- that implements integer comparison OP_CODE. */
-
-static bool
-aarch64_sve_cmp_operand_p (rtx_code op_code, rtx x)
-{
- if (register_operand (x, VOIDmode))
- return true;
-
- switch (op_code)
- {
- case LTU:
- case LEU:
- case GEU:
- case GTU:
- return aarch64_sve_cmp_immediate_p (x, false);
- case LT:
- case LE:
- case GE:
- case GT:
- case NE:
- case EQ:
- return aarch64_sve_cmp_immediate_p (x, true);
- default:
- gcc_unreachable ();
- }
-}
-
-/* Use predicated SVE instructions to implement the equivalent of:
-
- (set TARGET OP)
-
- given that PTRUE is an all-true predicate of the appropriate mode. */
-
-static void
-aarch64_emit_sve_ptrue_op (rtx target, rtx ptrue, rtx op)
-{
- rtx unspec = gen_rtx_UNSPEC (GET_MODE (target),
- gen_rtvec (2, ptrue, op),
- UNSPEC_MERGE_PTRUE);
- rtx_insn *insn = emit_set_insn (target, unspec);
- set_unique_reg_note (insn, REG_EQUAL, copy_rtx (op));
-}
+/* Expand an SVE integer comparison using the SVE equivalent of:
-/* Likewise, but also clobber the condition codes. */
+ (set TARGET (CODE OP0 OP1)). */
-static void
-aarch64_emit_sve_ptrue_op_cc (rtx target, rtx ptrue, rtx op)
+void
+aarch64_expand_sve_vec_cmp_int (rtx target, rtx_code code, rtx op0, rtx op1)
{
- rtx unspec = gen_rtx_UNSPEC (GET_MODE (target),
- gen_rtvec (2, ptrue, op),
- UNSPEC_MERGE_PTRUE);
- rtx_insn *insn = emit_insn (gen_set_clobber_cc_nzc (target, unspec));
- set_unique_reg_note (insn, REG_EQUAL, copy_rtx (op));
+ machine_mode pred_mode = GET_MODE (target);
+ machine_mode data_mode = GET_MODE (op0);
+ rtx res = aarch64_sve_emit_int_cmp (target, pred_mode, code, data_mode,
+ op0, op1);
+ if (!rtx_equal_p (target, res))
+ emit_move_insn (target, res);
}
/* Return the UNSPEC_COND_* code for comparison CODE. */
@@ -17097,17 +18110,19 @@ aarch64_unspec_cond_code (rtx_code code)
switch (code)
{
case NE:
- return UNSPEC_COND_NE;
+ return UNSPEC_COND_FCMNE;
case EQ:
- return UNSPEC_COND_EQ;
+ return UNSPEC_COND_FCMEQ;
case LT:
- return UNSPEC_COND_LT;
+ return UNSPEC_COND_FCMLT;
case GT:
- return UNSPEC_COND_GT;
+ return UNSPEC_COND_FCMGT;
case LE:
- return UNSPEC_COND_LE;
+ return UNSPEC_COND_FCMLE;
case GE:
- return UNSPEC_COND_GE;
+ return UNSPEC_COND_FCMGE;
+ case UNORDERED:
+ return UNSPEC_COND_FCMUO;
default:
gcc_unreachable ();
}
@@ -17115,78 +18130,58 @@ aarch64_unspec_cond_code (rtx_code code)
/* Emit:
- (set TARGET (unspec [PRED OP0 OP1] UNSPEC_COND_<X>))
+ (set TARGET (unspec [PRED KNOWN_PTRUE_P OP0 OP1] UNSPEC_COND_<X>))
- where <X> is the operation associated with comparison CODE. This form
- of instruction is used when (and (CODE OP0 OP1) PRED) would have different
- semantics, such as when PRED might not be all-true and when comparing
- inactive lanes could have side effects. */
+ where <X> is the operation associated with comparison CODE.
+ KNOWN_PTRUE_P is true if PRED is known to be a PTRUE. */
static void
-aarch64_emit_sve_predicated_cond (rtx target, rtx_code code,
- rtx pred, rtx op0, rtx op1)
+aarch64_emit_sve_fp_cond (rtx target, rtx_code code, rtx pred,
+ bool known_ptrue_p, rtx op0, rtx op1)
{
+ rtx flag = gen_int_mode (known_ptrue_p, SImode);
rtx unspec = gen_rtx_UNSPEC (GET_MODE (pred),
- gen_rtvec (3, pred, op0, op1),
+ gen_rtvec (4, pred, flag, op0, op1),
aarch64_unspec_cond_code (code));
emit_set_insn (target, unspec);
}
-/* Expand an SVE integer comparison using the SVE equivalent of:
-
- (set TARGET (CODE OP0 OP1)). */
-
-void
-aarch64_expand_sve_vec_cmp_int (rtx target, rtx_code code, rtx op0, rtx op1)
-{
- machine_mode pred_mode = GET_MODE (target);
- machine_mode data_mode = GET_MODE (op0);
-
- if (!aarch64_sve_cmp_operand_p (code, op1))
- op1 = force_reg (data_mode, op1);
-
- rtx ptrue = aarch64_ptrue_reg (pred_mode);
- rtx cond = gen_rtx_fmt_ee (code, pred_mode, op0, op1);
- aarch64_emit_sve_ptrue_op_cc (target, ptrue, cond);
-}
-
/* Emit the SVE equivalent of:
- (set TMP1 (CODE1 OP0 OP1))
- (set TMP2 (CODE2 OP0 OP1))
+ (set TMP1 (unspec [PRED KNOWN_PTRUE_P OP0 OP1] UNSPEC_COND_<X1>))
+ (set TMP2 (unspec [PRED KNOWN_PTRUE_P OP0 OP1] UNSPEC_COND_<X2>))
(set TARGET (ior:PRED_MODE TMP1 TMP2))
- PTRUE is an all-true predicate with the same mode as TARGET. */
+ where <Xi> is the operation associated with comparison CODEi.
+ KNOWN_PTRUE_P is true if PRED is known to be a PTRUE. */
static void
-aarch64_emit_sve_or_conds (rtx target, rtx_code code1, rtx_code code2,
- rtx ptrue, rtx op0, rtx op1)
+aarch64_emit_sve_or_fp_conds (rtx target, rtx_code code1, rtx_code code2,
+ rtx pred, bool known_ptrue_p, rtx op0, rtx op1)
{
- machine_mode pred_mode = GET_MODE (ptrue);
+ machine_mode pred_mode = GET_MODE (pred);
rtx tmp1 = gen_reg_rtx (pred_mode);
- aarch64_emit_sve_ptrue_op (tmp1, ptrue,
- gen_rtx_fmt_ee (code1, pred_mode, op0, op1));
+ aarch64_emit_sve_fp_cond (tmp1, code1, pred, known_ptrue_p, op0, op1);
rtx tmp2 = gen_reg_rtx (pred_mode);
- aarch64_emit_sve_ptrue_op (tmp2, ptrue,
- gen_rtx_fmt_ee (code2, pred_mode, op0, op1));
+ aarch64_emit_sve_fp_cond (tmp2, code2, pred, known_ptrue_p, op0, op1);
aarch64_emit_binop (target, ior_optab, tmp1, tmp2);
}
/* Emit the SVE equivalent of:
- (set TMP (CODE OP0 OP1))
+ (set TMP (unspec [PRED KNOWN_PTRUE_P OP0 OP1] UNSPEC_COND_<X>))
(set TARGET (not TMP))
- PTRUE is an all-true predicate with the same mode as TARGET. */
+ where <X> is the operation associated with comparison CODE.
+ KNOWN_PTRUE_P is true if PRED is known to be a PTRUE. */
static void
-aarch64_emit_sve_inverted_cond (rtx target, rtx ptrue, rtx_code code,
- rtx op0, rtx op1)
+aarch64_emit_sve_invert_fp_cond (rtx target, rtx_code code, rtx pred,
+ bool known_ptrue_p, rtx op0, rtx op1)
{
- machine_mode pred_mode = GET_MODE (ptrue);
+ machine_mode pred_mode = GET_MODE (pred);
rtx tmp = gen_reg_rtx (pred_mode);
- aarch64_emit_sve_ptrue_op (tmp, ptrue,
- gen_rtx_fmt_ee (code, pred_mode, op0, op1));
+ aarch64_emit_sve_fp_cond (tmp, code, pred, known_ptrue_p, op0, op1);
aarch64_emit_unop (target, one_cmpl_optab, tmp);
}
@@ -17219,14 +18214,13 @@ aarch64_expand_sve_vec_cmp_float (rtx target, rtx_code code,
case NE:
{
/* There is native support for the comparison. */
- rtx cond = gen_rtx_fmt_ee (code, pred_mode, op0, op1);
- aarch64_emit_sve_ptrue_op (target, ptrue, cond);
+ aarch64_emit_sve_fp_cond (target, code, ptrue, true, op0, op1);
return false;
}
case LTGT:
/* This is a trapping operation (LT or GT). */
- aarch64_emit_sve_or_conds (target, LT, GT, ptrue, op0, op1);
+ aarch64_emit_sve_or_fp_conds (target, LT, GT, ptrue, true, op0, op1);
return false;
case UNEQ:
@@ -17234,7 +18228,8 @@ aarch64_expand_sve_vec_cmp_float (rtx target, rtx_code code,
{
/* This would trap for signaling NaNs. */
op1 = force_reg (data_mode, op1);
- aarch64_emit_sve_or_conds (target, UNORDERED, EQ, ptrue, op0, op1);
+ aarch64_emit_sve_or_fp_conds (target, UNORDERED, EQ,
+ ptrue, true, op0, op1);
return false;
}
/* fall through */
@@ -17247,7 +18242,8 @@ aarch64_expand_sve_vec_cmp_float (rtx target, rtx_code code,
/* Work out which elements are ordered. */
rtx ordered = gen_reg_rtx (pred_mode);
op1 = force_reg (data_mode, op1);
- aarch64_emit_sve_inverted_cond (ordered, ptrue, UNORDERED, op0, op1);
+ aarch64_emit_sve_invert_fp_cond (ordered, UNORDERED,
+ ptrue, true, op0, op1);
/* Test the opposite condition for the ordered elements,
then invert the result. */
@@ -17257,13 +18253,12 @@ aarch64_expand_sve_vec_cmp_float (rtx target, rtx_code code,
code = reverse_condition_maybe_unordered (code);
if (can_invert_p)
{
- aarch64_emit_sve_predicated_cond (target, code,
- ordered, op0, op1);
+ aarch64_emit_sve_fp_cond (target, code,
+ ordered, false, op0, op1);
return true;
}
- rtx tmp = gen_reg_rtx (pred_mode);
- aarch64_emit_sve_predicated_cond (tmp, code, ordered, op0, op1);
- aarch64_emit_unop (target, one_cmpl_optab, tmp);
+ aarch64_emit_sve_invert_fp_cond (target, code,
+ ordered, false, op0, op1);
return false;
}
break;
@@ -17281,11 +18276,10 @@ aarch64_expand_sve_vec_cmp_float (rtx target, rtx_code code,
code = reverse_condition_maybe_unordered (code);
if (can_invert_p)
{
- rtx cond = gen_rtx_fmt_ee (code, pred_mode, op0, op1);
- aarch64_emit_sve_ptrue_op (target, ptrue, cond);
+ aarch64_emit_sve_fp_cond (target, code, ptrue, true, op0, op1);
return true;
}
- aarch64_emit_sve_inverted_cond (target, ptrue, code, op0, op1);
+ aarch64_emit_sve_invert_fp_cond (target, code, ptrue, true, op0, op1);
return false;
}
@@ -17310,6 +18304,13 @@ aarch64_expand_sve_vcond (machine_mode data_mode, machine_mode cmp_mode,
else
aarch64_expand_sve_vec_cmp_int (pred, GET_CODE (ops[3]), ops[4], ops[5]);
+ if (!aarch64_sve_reg_or_dup_imm (ops[1], data_mode))
+ ops[1] = force_reg (data_mode, ops[1]);
+ /* The "false" value can only be zero if the "true" value is a constant. */
+ if (register_operand (ops[1], data_mode)
+ || !aarch64_simd_reg_or_zero (ops[2], data_mode))
+ ops[2] = force_reg (data_mode, ops[2]);
+
rtvec vec = gen_rtvec (3, pred, ops[1], ops[2]);
emit_set_insn (ops[0], gen_rtx_UNSPEC (data_mode, vec, UNSPEC_SEL));
}
@@ -18546,19 +19547,21 @@ aarch64_gen_adjusted_ldpstp (rtx *operands, bool load,
/* Sort the operands. */
qsort (temp_operands, 4, 2 * sizeof (rtx *), aarch64_ldrstr_offset_compare);
+ /* Copy the memory operands so that if we have to bail for some
+ reason the original addresses are unchanged. */
if (load)
{
- mem_1 = temp_operands[1];
- mem_2 = temp_operands[3];
- mem_3 = temp_operands[5];
- mem_4 = temp_operands[7];
+ mem_1 = copy_rtx (temp_operands[1]);
+ mem_2 = copy_rtx (temp_operands[3]);
+ mem_3 = copy_rtx (temp_operands[5]);
+ mem_4 = copy_rtx (temp_operands[7]);
}
else
{
- mem_1 = temp_operands[0];
- mem_2 = temp_operands[2];
- mem_3 = temp_operands[4];
- mem_4 = temp_operands[6];
+ mem_1 = copy_rtx (temp_operands[0]);
+ mem_2 = copy_rtx (temp_operands[2]);
+ mem_3 = copy_rtx (temp_operands[4]);
+ mem_4 = copy_rtx (temp_operands[6]);
gcc_assert (code == UNKNOWN);
}
@@ -18747,6 +19750,29 @@ aarch64_fpconst_pow_of_2 (rtx x)
return exact_log2 (real_to_integer (r));
}
+/* If X is a positive CONST_DOUBLE with a value that is the reciprocal of a
+ power of 2 (i.e 1/2^n) return the number of float bits. e.g. for x==(1/2^n)
+ return n. Otherwise return -1. */
+
+int
+aarch64_fpconst_pow2_recip (rtx x)
+{
+ REAL_VALUE_TYPE r0;
+
+ if (!CONST_DOUBLE_P (x))
+ return -1;
+
+ r0 = *CONST_DOUBLE_REAL_VALUE (x);
+ if (exact_real_inverse (DFmode, &r0)
+ && !REAL_VALUE_NEGATIVE (r0))
+ {
+ int ret = exact_log2 (real_to_integer (&r0));
+ if (ret >= 1 && ret <= 32)
+ return ret;
+ }
+ return -1;
+}
+
/* If X is a vector of equal CONST_DOUBLE values and that value is
Y, return the aarch64_fpconst_pow_of_2 of Y. Otherwise return -1. */
@@ -18967,12 +19993,8 @@ aarch64_select_early_remat_modes (sbitmap modes)
/* SVE values are not normally live across a call, so it should be
worth doing early rematerialization even in VL-specific mode. */
for (int i = 0; i < NUM_MACHINE_MODES; ++i)
- {
- machine_mode mode = (machine_mode) i;
- unsigned int vec_flags = aarch64_classify_vector_mode (mode);
- if (vec_flags & VEC_ANY_SVE)
- bitmap_set_bit (modes, i);
- }
+ if (aarch64_sve_mode_p ((machine_mode) i))
+ bitmap_set_bit (modes, i);
}
/* Override the default target speculation_safe_value. */
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 92e38a8..0c27d90 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -199,6 +199,9 @@ extern unsigned aarch64_architecture_version;
#define AARCH64_FL_SVE2_SHA3 (1ULL << 31)
#define AARCH64_FL_SVE2_BITPERM (1ULL << 32)
+/* Transactional Memory Extension. */
+#define AARCH64_FL_TME (1ULL << 33) /* Has TME instructions. */
+
/* Has FP and SIMD. */
#define AARCH64_FL_FPSIMD (AARCH64_FL_FP | AARCH64_FL_SIMD)
@@ -243,6 +246,7 @@ extern unsigned aarch64_architecture_version;
#define AARCH64_ISA_F16FML (aarch64_isa_flags & AARCH64_FL_F16FML)
#define AARCH64_ISA_RCPC8_4 (aarch64_isa_flags & AARCH64_FL_RCPC8_4)
#define AARCH64_ISA_V8_5 (aarch64_isa_flags & AARCH64_FL_V8_5)
+#define AARCH64_ISA_TME (aarch64_isa_flags & AARCH64_FL_TME)
/* Crypto is an optional extension to AdvSIMD. */
#define TARGET_CRYPTO (TARGET_SIMD && AARCH64_ISA_CRYPTO)
@@ -287,6 +291,9 @@ extern unsigned aarch64_architecture_version;
/* Armv8.3-a Complex number extension to AdvSIMD extensions. */
#define TARGET_COMPLEX (TARGET_SIMD && TARGET_ARMV8_3)
+/* TME instructions are enabled. */
+#define TARGET_TME (AARCH64_ISA_TME)
+
/* Make sure this is always defined so we don't have to check for ifdefs
but rather use normal ifs. */
#ifndef TARGET_FIX_ERR_A53_835769_DEFAULT
@@ -556,6 +563,9 @@ extern unsigned aarch64_architecture_version;
#define FP_LO_REGNUM_P(REGNO) \
(((unsigned) (REGNO - V0_REGNUM)) <= (V15_REGNUM - V0_REGNUM))
+#define FP_LO8_REGNUM_P(REGNO) \
+ (((unsigned) (REGNO - V0_REGNUM)) <= (V7_REGNUM - V0_REGNUM))
+
#define PR_REGNUM_P(REGNO)\
(((unsigned) (REGNO - P0_REGNUM)) <= (P15_REGNUM - P0_REGNUM))
@@ -574,6 +584,7 @@ enum reg_class
GENERAL_REGS,
STACK_REG,
POINTER_REGS,
+ FP_LO8_REGS,
FP_LO_REGS,
FP_REGS,
POINTER_AND_FP_REGS,
@@ -593,6 +604,7 @@ enum reg_class
"GENERAL_REGS", \
"STACK_REG", \
"POINTER_REGS", \
+ "FP_LO8_REGS", \
"FP_LO_REGS", \
"FP_REGS", \
"POINTER_AND_FP_REGS", \
@@ -609,6 +621,7 @@ enum reg_class
{ 0x7fffffff, 0x00000000, 0x00000003 }, /* GENERAL_REGS */ \
{ 0x80000000, 0x00000000, 0x00000000 }, /* STACK_REG */ \
{ 0xffffffff, 0x00000000, 0x00000003 }, /* POINTER_REGS */ \
+ { 0x00000000, 0x000000ff, 0x00000000 }, /* FP_LO8_REGS */ \
{ 0x00000000, 0x0000ffff, 0x00000000 }, /* FP_LO_REGS */ \
{ 0x00000000, 0xffffffff, 0x00000000 }, /* FP_REGS */ \
{ 0xffffffff, 0xffffffff, 0x00000003 }, /* POINTER_AND_FP_REGS */\
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index d1b2c20..9a07f63 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -219,14 +219,14 @@
UNSPEC_LD1RQ
UNSPEC_LD1_GATHER
UNSPEC_ST1_SCATTER
- UNSPEC_MERGE_PTRUE
- UNSPEC_PTEST_PTRUE
+ UNSPEC_PRED_X
+ UNSPEC_PRED_Z
+ UNSPEC_PTEST
UNSPEC_UNPACKSHI
UNSPEC_UNPACKUHI
UNSPEC_UNPACKSLO
UNSPEC_UNPACKULO
UNSPEC_PACK
- UNSPEC_FLOAT_CONVERT
UNSPEC_WHILE_LO
UNSPEC_LDN
UNSPEC_STN
@@ -234,8 +234,10 @@
UNSPEC_CLASTB
UNSPEC_FADDA
UNSPEC_REV_SUBREG
+ UNSPEC_REINTERPRET
UNSPEC_SPECULATION_TRACKER
UNSPEC_COPYSIGN
+ UNSPEC_TTEST ; Represent transaction test.
])
(define_c_enum "unspecv" [
@@ -251,9 +253,33 @@
UNSPECV_BTI_C ; Represent BTI c.
UNSPECV_BTI_J ; Represent BTI j.
UNSPECV_BTI_JC ; Represent BTI jc.
+ UNSPECV_TSTART ; Represent transaction start.
+ UNSPECV_TCOMMIT ; Represent transaction commit.
+ UNSPECV_TCANCEL ; Represent transaction cancel.
]
)
+;; These constants are used as a const_int in various SVE unspecs
+;; to indicate whether the governing predicate is known to be a PTRUE.
+(define_constants
+ [; Indicates that the predicate might not be a PTRUE.
+ (SVE_MAYBE_NOT_PTRUE 0)
+
+ ; Indicates that the predicate is known to be a PTRUE.
+ (SVE_KNOWN_PTRUE 1)])
+
+;; These constants are used as a const_int in predicated SVE FP arithmetic
+;; to indicate whether the operation is allowed to make additional lanes
+;; active without worrying about the effect on faulting behavior.
+(define_constants
+ [; Indicates either that all lanes are active or that the instruction may
+ ; operate on inactive inputs even if doing so could induce a fault.
+ (SVE_RELAXED_GP 0)
+
+ ; Indicates that some lanes might be inactive and that the instruction
+ ; must not operate on inactive inputs if doing so could induce a fault.
+ (SVE_STRICT_GP 1)])
+
;; If further include files are added the defintion of MD_INCLUDES
;; must be updated.
@@ -1727,6 +1753,7 @@
/* If the constant is too large for a single instruction and isn't frame
based, split off the immediate so it is available for CSE. */
if (!aarch64_plus_immediate (operands[2], <MODE>mode)
+ && !(TARGET_SVE && aarch64_sve_plus_immediate (operands[2], <MODE>mode))
&& can_create_pseudo_p ()
&& (!REG_P (op1)
|| !REGNO_PTR_FRAME_P (REGNO (op1))))
@@ -1744,10 +1771,10 @@
(define_insn "*add<mode>3_aarch64"
[(set
- (match_operand:GPI 0 "register_operand" "=rk,rk,w,rk,r,rk")
+ (match_operand:GPI 0 "register_operand" "=rk,rk,w,rk,r,r,rk")
(plus:GPI
- (match_operand:GPI 1 "register_operand" "%rk,rk,w,rk,rk,rk")
- (match_operand:GPI 2 "aarch64_pluslong_operand" "I,r,w,J,Uaa,Uav")))]
+ (match_operand:GPI 1 "register_operand" "%rk,rk,w,rk,rk,0,rk")
+ (match_operand:GPI 2 "aarch64_pluslong_operand" "I,r,w,J,Uaa,Uai,Uav")))]
""
"@
add\\t%<w>0, %<w>1, %2
@@ -1755,10 +1782,11 @@
add\\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
sub\\t%<w>0, %<w>1, #%n2
#
- * return aarch64_output_sve_addvl_addpl (operands[0], operands[1], operands[2]);"
- ;; The "alu_imm" type for ADDVL/ADDPL is just a placeholder.
- [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm,multiple,alu_imm")
- (set_attr "arch" "*,*,simd,*,*,*")]
+ * return aarch64_output_sve_scalar_inc_dec (operands[2]);
+ * return aarch64_output_sve_addvl_addpl (operands[2]);"
+ ;; The "alu_imm" types for INC/DEC and ADDVL/ADDPL are just placeholders.
+ [(set_attr "type" "alu_imm,alu_sreg,neon_add,alu_imm,multiple,alu_imm,alu_imm")
+ (set_attr "arch" "*,*,simd,*,*,sve,sve")]
)
;; zero_extend version of above
@@ -1837,17 +1865,18 @@
;; this pattern.
(define_insn_and_split "*add<mode>3_poly_1"
[(set
- (match_operand:GPI 0 "register_operand" "=r,r,r,r,r,&r")
+ (match_operand:GPI 0 "register_operand" "=r,r,r,r,r,r,&r")
(plus:GPI
- (match_operand:GPI 1 "register_operand" "%rk,rk,rk,rk,rk,rk")
- (match_operand:GPI 2 "aarch64_pluslong_or_poly_operand" "I,r,J,Uaa,Uav,Uat")))]
+ (match_operand:GPI 1 "register_operand" "%rk,rk,rk,rk,rk,0,rk")
+ (match_operand:GPI 2 "aarch64_pluslong_or_poly_operand" "I,r,J,Uaa,Uav,Uai,Uat")))]
"TARGET_SVE && operands[0] != stack_pointer_rtx"
"@
add\\t%<w>0, %<w>1, %2
add\\t%<w>0, %<w>1, %<w>2
sub\\t%<w>0, %<w>1, #%n2
#
- * return aarch64_output_sve_addvl_addpl (operands[0], operands[1], operands[2]);
+ * return aarch64_output_sve_scalar_inc_dec (operands[2]);
+ * return aarch64_output_sve_addvl_addpl (operands[2]);
#"
"&& epilogue_completed
&& !reg_overlap_mentioned_p (operands[0], operands[1])
@@ -1858,8 +1887,8 @@
operands[2], operands[0], NULL_RTX);
DONE;
}
- ;; The "alu_imm" type for ADDVL/ADDPL is just a placeholder.
- [(set_attr "type" "alu_imm,alu_sreg,alu_imm,multiple,alu_imm,multiple")]
+ ;; The "alu_imm" types for INC/DEC and ADDVL/ADDPL are just placeholders.
+ [(set_attr "type" "alu_imm,alu_sreg,alu_imm,multiple,alu_imm,alu_imm,multiple")]
)
(define_split
@@ -6022,6 +6051,44 @@
[(set_attr "type" "f_cvtf2i")]
)
+;; Equal width integer to fp and multiply combine.
+(define_insn "*aarch64_<su_optab>cvtf<fcvt_target><GPF:mode>2_mult"
+ [(set (match_operand:GPF 0 "register_operand" "=w,w")
+ (mult:GPF (FLOATUORS:GPF
+ (match_operand:<FCVT_TARGET> 1 "register_operand" "w,?r"))
+ (match_operand:GPF 2 "aarch64_fp_pow2_recip" "Dt,Dt")))]
+ "TARGET_FLOAT"
+ {
+ operands[2] = GEN_INT (aarch64_fpconst_pow2_recip (operands[2]));
+ switch (which_alternative)
+ {
+ case 0:
+ return "<su_optab>cvtf\t%<GPF:s>0, %<s>1, #%2";
+ case 1:
+ return "<su_optab>cvtf\t%<GPF:s>0, %<w1>1, #%2";
+ default:
+ gcc_unreachable ();
+ }
+ }
+ [(set_attr "type" "neon_int_to_fp_<Vetype>,f_cvti2f")
+ (set_attr "arch" "simd,fp")]
+)
+
+;; Unequal width integer to fp and multiply combine.
+(define_insn "*aarch64_<su_optab>cvtf<fcvt_iesize><GPF:mode>2_mult"
+ [(set (match_operand:GPF 0 "register_operand" "=w")
+ (mult:GPF (FLOATUORS:GPF
+ (match_operand:<FCVT_IESIZE> 1 "register_operand" "r"))
+ (match_operand:GPF 2 "aarch64_fp_pow2_recip" "Dt")))]
+ "TARGET_FLOAT"
+ {
+ operands[2] = GEN_INT (aarch64_fpconst_pow2_recip (operands[2]));
+ return "<su_optab>cvtf\t%<GPF:s>0, %<w2>1, #%2";
+ }
+ [(set_attr "type" "f_cvti2f")]
+)
+
+;; Equal width integer to fp conversion.
(define_insn "<optab><fcvt_target><GPF:mode>2"
[(set (match_operand:GPF 0 "register_operand" "=w,w")
(FLOATUORS:GPF (match_operand:<FCVT_TARGET> 1 "register_operand" "w,?r")))]
@@ -6033,6 +6100,7 @@
(set_attr "arch" "simd,fp")]
)
+;; Unequal width integer to fp conversions.
(define_insn "<optab><fcvt_iesize><GPF:mode>2"
[(set (match_operand:GPF 0 "register_operand" "=w")
(FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" "r")))]
@@ -6318,7 +6386,7 @@
[(match_operand:GPI 0 "register_operand")
(match_operand:GPF 1 "register_operand")]
"TARGET_FLOAT
- && ((GET_MODE_SIZE (<GPF:MODE>mode) <= GET_MODE_SIZE (<GPI:MODE>mode))
+ && ((GET_MODE_BITSIZE (<GPF:MODE>mode) <= LONG_TYPE_SIZE)
|| !flag_trapping_math || flag_fp_int_builtin_inexact)"
{
rtx cvt = gen_reg_rtx (<GPF:MODE>mode);
@@ -7129,12 +7197,6 @@
[(set_attr "type" "no_insn")]
)
-;; Helper for aarch64.c code.
-(define_expand "set_clobber_cc_nzc"
- [(parallel [(set (match_operand 0)
- (match_operand 1))
- (clobber (reg:CC_NZC CC_REGNUM))])])
-
;; Hard speculation barrier.
(define_insn "speculation_barrier"
[(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
@@ -7242,6 +7304,43 @@
(set_attr "speculation_barrier" "true")]
)
+;; Transactional Memory Extension (TME) instructions.
+
+(define_insn "tstart"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec_volatile:DI [(const_int 0)] UNSPECV_TSTART))
+ (clobber (mem:BLK (scratch)))]
+ "TARGET_TME"
+ "tstart\\t%0"
+ [(set_attr "type" "tme")]
+)
+
+(define_insn "ttest"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec_volatile:DI [(const_int 0)] UNSPEC_TTEST))
+ (clobber (mem:BLK (scratch)))]
+ "TARGET_TME"
+ "ttest\\t%0"
+ [(set_attr "type" "tme")]
+)
+
+(define_insn "tcommit"
+ [(unspec_volatile:BLK [(const_int 0)] UNSPECV_TCOMMIT)
+ (clobber (mem:BLK (scratch)))]
+ "TARGET_TME"
+ "tcommit"
+ [(set_attr "type" "tme")]
+)
+
+(define_insn "tcancel"
+ [(unspec_volatile:BLK
+ [(match_operand 0 "const_int_operand" "n")] UNSPECV_TCANCEL)
+ (clobber (mem:BLK (scratch)))]
+ "TARGET_TME && (UINTVAL (operands[0]) <= 65535)"
+ "tcancel\\t#%0"
+ [(set_attr "type" "tme")]
+)
+
;; AdvSIMD Stuff
(include "aarch64-simd.md")
diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h
index 534a989..d4de691 100644
--- a/gcc/config/aarch64/arm_acle.h
+++ b/gcc/config/aarch64/arm_acle.h
@@ -29,14 +29,14 @@
#include <stdint.h>
-#pragma GCC push_options
-
-#pragma GCC target ("+nothing+crc")
-
#ifdef __cplusplus
extern "C" {
#endif
+#pragma GCC push_options
+
+#pragma GCC target ("+nothing+crc")
+
__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
__crc32b (uint32_t __a, uint8_t __b)
{
@@ -85,10 +85,53 @@ __crc32d (uint32_t __a, uint64_t __b)
return __builtin_aarch64_crc32x (__a, __b);
}
-#ifdef __cplusplus
+#pragma GCC pop_options
+
+#ifdef __ARM_FEATURE_TME
+#pragma GCC push_options
+#pragma GCC target ("+nothing+tme")
+
+#define _TMFAILURE_REASON 0x00007fffu
+#define _TMFAILURE_RTRY 0x00008000u
+#define _TMFAILURE_CNCL 0x00010000u
+#define _TMFAILURE_MEM 0x00020000u
+#define _TMFAILURE_IMP 0x00040000u
+#define _TMFAILURE_ERR 0x00080000u
+#define _TMFAILURE_SIZE 0x00100000u
+#define _TMFAILURE_NEST 0x00200000u
+#define _TMFAILURE_DBG 0x00400000u
+#define _TMFAILURE_INT 0x00800000u
+#define _TMFAILURE_TRIVIAL 0x01000000u
+
+__extension__ static __inline uint64_t __attribute__ ((__always_inline__))
+__tstart (void)
+{
+ return __builtin_aarch64_tstart ();
+}
+
+__extension__ static __inline void __attribute__ ((__always_inline__))
+__tcommit (void)
+{
+ __builtin_aarch64_tcommit ();
+}
+
+__extension__ static __inline void __attribute__ ((__always_inline__))
+__tcancel (const uint64_t __reason)
+{
+ __builtin_aarch64_tcancel (__reason);
+}
+
+__extension__ static __inline uint64_t __attribute__ ((__always_inline__))
+__ttest (void)
+{
+ return __builtin_aarch64_ttest ();
}
-#endif
#pragma GCC pop_options
+#endif
+
+#ifdef __cplusplus
+}
+#endif
#endif
diff --git a/gcc/config/aarch64/check-sve-md.awk b/gcc/config/aarch64/check-sve-md.awk
new file mode 100644
index 0000000..3da78f3
--- /dev/null
+++ b/gcc/config/aarch64/check-sve-md.awk
@@ -0,0 +1,66 @@
+#!/usr/bin/awk -f
+# Copyright (C) 2019 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# This awk script checks that aarch64-sve.md (passed either on the
+# command line or via stdin) has an up-to-date contents section.
+
+BEGIN {
+ seen1 = 0
+ seen2 = 0
+ errors = 0
+}
+
+# The headings in the comments use a two-level hierarchy: ";; == ..."
+# for major sections and ";; ---- ..." for minor sections. Each section
+# heading must be unique.
+#
+# The contents section should list all the section headings, using the
+# same text and in the same order. We should therefore see exactly two
+# copies of the section list.
+/^;; == / || /^;; ---- / {
+ if ($0 in seen || seen2 > 0)
+ {
+ if (seen2 >= seen1)
+ {
+ printf "error: line not in contents: %s\n", $0 > "/dev/stderr"
+ errors += 1
+ exit(1)
+ }
+ if ($0 != order[seen2])
+ {
+ printf "error: mismatched contents\n saw: %s\nexpected: %s\n", \
+ $0, order[seen2] > "/dev/stderr"
+ errors += 1
+ exit(1)
+ }
+ seen2 += 1
+ }
+ else
+ {
+ seen[$0] = 1
+ order[seen1] = $0
+ seen1 += 1
+ }
+}
+
+END {
+ if (seen2 < seen1 && errors == 0)
+ {
+ printf "error: line only in contents: %s\n", order[seen2] > "/dev/stderr"
+ exit(1)
+ }
+}
diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md
index 21f9549..9326bec 100644
--- a/gcc/config/aarch64/constraints.md
+++ b/gcc/config/aarch64/constraints.md
@@ -36,6 +36,9 @@
(define_register_constraint "x" "FP_LO_REGS"
"Floating point and SIMD vector registers V0 - V15.")
+(define_register_constraint "y" "FP_LO8_REGS"
+ "Floating point and SIMD vector registers V0 - V7.")
+
(define_constraint "I"
"A constant that can be used with an ADD operation."
(and (match_code "const_int")
@@ -46,6 +49,12 @@
(and (match_code "const_int")
(match_test "aarch64_pluslong_strict_immedate (op, VOIDmode)")))
+(define_constraint "Uai"
+ "@internal
+ A constraint that matches a VG-based constant that can be added by
+ a single INC or DEC."
+ (match_operand 0 "aarch64_sve_scalar_inc_dec_immediate"))
+
(define_constraint "Uav"
"@internal
A constraint that matches a VG-based constant that can be added by
@@ -114,8 +123,8 @@
(match_test "aarch64_float_const_zero_rtx_p (op)")))
(define_constraint "Z"
- "Integer constant zero."
- (match_test "op == const0_rtx"))
+ "Integer or floating-point constant zero."
+ (match_test "op == CONST0_RTX (GET_MODE (op))"))
(define_constraint "Ush"
"A constraint that matches an absolute symbolic address high part."
@@ -269,6 +278,12 @@
(match_test "aarch64_legitimate_address_p (V2DImode,
XEXP (op, 0), 1)")))
+(define_memory_constraint "UtQ"
+ "@internal
+ An address valid for SVE LD1RQs."
+ (and (match_code "mem")
+ (match_test "aarch64_sve_ld1rq_operand_p (op)")))
+
(define_memory_constraint "Uty"
"@internal
An address valid for SVE LD1Rs."
@@ -284,7 +299,7 @@
(define_constraint "Ufc"
"A floating point constant which can be used with an\
FMOV immediate operation."
- (and (match_code "const_double")
+ (and (match_code "const_double,const_vector")
(match_test "aarch64_float_const_representable_p (op)")))
(define_constraint "Uvi"
@@ -329,6 +344,13 @@
(match_test "aarch64_simd_scalar_immediate_valid_for_move (op,
QImode)")))
+(define_constraint "Dt"
+ "@internal
+ A const_double which is the reciprocal of an exact power of two, can be
+ used in an scvtf with fract bits operation"
+ (and (match_code "const_double")
+ (match_test "aarch64_fpconst_pow2_recip (op) > 0")))
+
(define_constraint "Dl"
"@internal
A constraint that matches vector of immediates for left shifts."
@@ -379,12 +401,24 @@
arithmetic instructions."
(match_operand 0 "aarch64_sve_arith_immediate"))
+(define_constraint "vsb"
+ "@internal
+ A constraint that matches an immediate operand valid for SVE UMAX
+ and UMIN operations."
+ (match_operand 0 "aarch64_sve_vsb_immediate"))
+
(define_constraint "vsc"
"@internal
A constraint that matches a signed immediate operand valid for SVE
CMP instructions."
(match_operand 0 "aarch64_sve_cmp_vsc_immediate"))
+(define_constraint "vss"
+ "@internal
+ A constraint that matches a signed immediate operand valid for SVE
+ DUP instructions."
+ (match_test "aarch64_sve_dup_immediate_p (op)"))
+
(define_constraint "vsd"
"@internal
A constraint that matches an unsigned immediate operand valid for SVE
@@ -395,7 +429,7 @@
"@internal
A constraint that matches a vector count operand valid for SVE INC and
DEC instructions."
- (match_operand 0 "aarch64_sve_inc_dec_immediate"))
+ (match_operand 0 "aarch64_sve_vector_inc_dec_immediate"))
(define_constraint "vsn"
"@internal
@@ -411,9 +445,9 @@
(define_constraint "vsm"
"@internal
- A constraint that matches an immediate operand valid for SVE MUL
- operations."
- (match_operand 0 "aarch64_sve_mul_immediate"))
+ A constraint that matches an immediate operand valid for SVE MUL,
+ SMAX and SMIN operations."
+ (match_operand 0 "aarch64_sve_vsm_immediate"))
(define_constraint "vsA"
"@internal
@@ -421,13 +455,20 @@
and FSUB operations."
(match_operand 0 "aarch64_sve_float_arith_immediate"))
+;; "B" for "bound".
+(define_constraint "vsB"
+ "@internal
+ A constraint that matches an immediate operand valid for SVE FMAX
+ and FMIN operations."
+ (match_operand 0 "aarch64_sve_float_maxmin_immediate"))
+
(define_constraint "vsM"
"@internal
- A constraint that matches an imediate operand valid for SVE FMUL
+ A constraint that matches an immediate operand valid for SVE FMUL
operations."
(match_operand 0 "aarch64_sve_float_mul_immediate"))
(define_constraint "vsN"
"@internal
A constraint that matches the negative of vsA"
- (match_operand 0 "aarch64_sve_float_arith_with_sub_immediate"))
+ (match_operand 0 "aarch64_sve_float_negated_arith_immediate"))
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 198fc5d..e8ba4f3 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -278,6 +278,10 @@
(define_mode_iterator SVE_ALL [VNx16QI VNx8HI VNx4SI VNx2DI
VNx8HF VNx4SF VNx2DF])
+;; Iterators for single modes, for "@" patterns.
+(define_mode_iterator VNx4SI_ONLY [VNx4SI])
+(define_mode_iterator VNx2DF_ONLY [VNx2DF])
+
;; All SVE vector structure modes.
(define_mode_iterator SVE_STRUCT [VNx32QI VNx16HI VNx8SI VNx4DI
VNx16HF VNx8SF VNx4DF
@@ -292,15 +296,24 @@
;; All SVE vector modes that have 8-bit, 16-bit or 32-bit elements.
(define_mode_iterator SVE_BHS [VNx16QI VNx8HI VNx4SI VNx8HF VNx4SF])
-;; All SVE integer vector modes that have 8-bit, 16-bit or 32-bit elements.
+;; SVE integer vector modes that have 8-bit, 16-bit or 32-bit elements.
(define_mode_iterator SVE_BHSI [VNx16QI VNx8HI VNx4SI])
-;; All SVE integer vector modes that have 16-bit, 32-bit or 64-bit elements.
-(define_mode_iterator SVE_HSDI [VNx16QI VNx8HI VNx4SI])
+;; SVE integer vector modes that have 16-bit, 32-bit or 64-bit elements.
+(define_mode_iterator SVE_HSDI [VNx8HI VNx4SI VNx2DI])
-;; All SVE floating-point vector modes that have 16-bit or 32-bit elements.
+;; SVE floating-point vector modes that have 16-bit or 32-bit elements.
(define_mode_iterator SVE_HSF [VNx8HF VNx4SF])
+;; SVE integer vector modes that have 32-bit or 64-bit elements.
+(define_mode_iterator SVE_SDI [VNx4SI VNx2DI])
+
+;; SVE floating-point vector modes that have 32-bit or 64-bit elements.
+(define_mode_iterator SVE_SDF [VNx4SF VNx2DF])
+
+;; All SVE vector modes that have 16-bit, 32-bit or 64-bit elements.
+(define_mode_iterator SVE_HSD [VNx8HI VNx4SI VNx2DI VNx8HF VNx4SF VNx2DF])
+
;; All SVE vector modes that have 32-bit or 64-bit elements.
(define_mode_iterator SVE_SD [VNx4SI VNx2DI VNx4SF VNx2DF])
@@ -310,9 +323,6 @@
;; All SVE vector modes that have 64-bit elements.
(define_mode_iterator SVE_D [VNx2DI VNx2DF])
-;; All SVE integer vector modes that have 32-bit or 64-bit elements.
-(define_mode_iterator SVE_SDI [VNx4SI VNx2DI])
-
;; All SVE integer vector modes.
(define_mode_iterator SVE_I [VNx16QI VNx8HI VNx4SI VNx2DI])
@@ -466,24 +476,43 @@
UNSPEC_ANDF ; Used in aarch64-sve.md.
UNSPEC_IORF ; Used in aarch64-sve.md.
UNSPEC_XORF ; Used in aarch64-sve.md.
+ UNSPEC_REVB ; Used in aarch64-sve.md.
+ UNSPEC_REVH ; Used in aarch64-sve.md.
+ UNSPEC_REVW ; Used in aarch64-sve.md.
UNSPEC_SMUL_HIGHPART ; Used in aarch64-sve.md.
UNSPEC_UMUL_HIGHPART ; Used in aarch64-sve.md.
- UNSPEC_COND_ADD ; Used in aarch64-sve.md.
- UNSPEC_COND_SUB ; Used in aarch64-sve.md.
- UNSPEC_COND_MUL ; Used in aarch64-sve.md.
- UNSPEC_COND_DIV ; Used in aarch64-sve.md.
- UNSPEC_COND_MAX ; Used in aarch64-sve.md.
- UNSPEC_COND_MIN ; Used in aarch64-sve.md.
+ UNSPEC_COND_FABS ; Used in aarch64-sve.md.
+ UNSPEC_COND_FADD ; Used in aarch64-sve.md.
+ UNSPEC_COND_FCMEQ ; Used in aarch64-sve.md.
+ UNSPEC_COND_FCMGE ; Used in aarch64-sve.md.
+ UNSPEC_COND_FCMGT ; Used in aarch64-sve.md.
+ UNSPEC_COND_FCMLE ; Used in aarch64-sve.md.
+ UNSPEC_COND_FCMLT ; Used in aarch64-sve.md.
+ UNSPEC_COND_FCMNE ; Used in aarch64-sve.md.
+ UNSPEC_COND_FCMUO ; Used in aarch64-sve.md.
+ UNSPEC_COND_FCVT ; Used in aarch64-sve.md.
+ UNSPEC_COND_FCVTZS ; Used in aarch64-sve.md.
+ UNSPEC_COND_FCVTZU ; Used in aarch64-sve.md.
+ UNSPEC_COND_FDIV ; Used in aarch64-sve.md.
+ UNSPEC_COND_FMAXNM ; Used in aarch64-sve.md.
+ UNSPEC_COND_FMINNM ; Used in aarch64-sve.md.
UNSPEC_COND_FMLA ; Used in aarch64-sve.md.
UNSPEC_COND_FMLS ; Used in aarch64-sve.md.
+ UNSPEC_COND_FMUL ; Used in aarch64-sve.md.
+ UNSPEC_COND_FNEG ; Used in aarch64-sve.md.
UNSPEC_COND_FNMLA ; Used in aarch64-sve.md.
UNSPEC_COND_FNMLS ; Used in aarch64-sve.md.
- UNSPEC_COND_LT ; Used in aarch64-sve.md.
- UNSPEC_COND_LE ; Used in aarch64-sve.md.
- UNSPEC_COND_EQ ; Used in aarch64-sve.md.
- UNSPEC_COND_NE ; Used in aarch64-sve.md.
- UNSPEC_COND_GE ; Used in aarch64-sve.md.
- UNSPEC_COND_GT ; Used in aarch64-sve.md.
+ UNSPEC_COND_FRINTA ; Used in aarch64-sve.md.
+ UNSPEC_COND_FRINTI ; Used in aarch64-sve.md.
+ UNSPEC_COND_FRINTM ; Used in aarch64-sve.md.
+ UNSPEC_COND_FRINTN ; Used in aarch64-sve.md.
+ UNSPEC_COND_FRINTP ; Used in aarch64-sve.md.
+ UNSPEC_COND_FRINTX ; Used in aarch64-sve.md.
+ UNSPEC_COND_FRINTZ ; Used in aarch64-sve.md.
+ UNSPEC_COND_FSQRT ; Used in aarch64-sve.md.
+ UNSPEC_COND_FSUB ; Used in aarch64-sve.md.
+ UNSPEC_COND_SCVTF ; Used in aarch64-sve.md.
+ UNSPEC_COND_UCVTF ; Used in aarch64-sve.md.
UNSPEC_LASTB ; Used in aarch64-sve.md.
UNSPEC_FCADD90 ; Used in aarch64-simd.md.
UNSPEC_FCADD270 ; Used in aarch64-simd.md.
@@ -610,6 +639,14 @@
(define_mode_attr sizem1 [(QI "#7") (HI "#15") (SI "#31") (DI "#63")
(HF "#15") (SF "#31") (DF "#63")])
+;; The number of bits in a vector element, or controlled by a predicate
+;; element.
+(define_mode_attr elem_bits [(VNx16BI "8") (VNx8BI "16")
+ (VNx4BI "32") (VNx2BI "64")
+ (VNx16QI "8") (VNx8HI "16")
+ (VNx4SI "32") (VNx2DI "64")
+ (VNx8HF "16") (VNx4SF "32") (VNx2DF "64")])
+
;; Attribute to describe constants acceptable in logical operations
(define_mode_attr lconst [(SI "K") (DI "L")])
@@ -918,9 +955,11 @@
])
;; Floating-point equivalent of selected modes.
-(define_mode_attr V_FP_EQUIV [(VNx4SI "VNx4SF") (VNx4SF "VNx4SF")
+(define_mode_attr V_FP_EQUIV [(VNx8HI "VNx8HF") (VNx8HF "VNx8HF")
+ (VNx4SI "VNx4SF") (VNx4SF "VNx4SF")
(VNx2DI "VNx2DF") (VNx2DF "VNx2DF")])
-(define_mode_attr v_fp_equiv [(VNx4SI "vnx4sf") (VNx4SF "vnx4sf")
+(define_mode_attr v_fp_equiv [(VNx8HI "vnx8hf") (VNx8HF "vnx8hf")
+ (VNx4SI "vnx4sf") (VNx4SF "vnx4sf")
(VNx2DI "vnx2df") (VNx2DF "vnx2df")])
;; Mode for vector conditional operations where the comparison has
@@ -1159,6 +1198,10 @@
(V4HF "<Vetype>[%4]") (V8HF "<Vetype>[%4]")
])
+;; The number of bytes controlled by a predicate
+(define_mode_attr data_bytes [(VNx16BI "1") (VNx8BI "2")
+ (VNx4BI "4") (VNx2BI "8")])
+
;; -------------------------------------------------------------------
;; Code Iterators
;; -------------------------------------------------------------------
@@ -1239,27 +1282,25 @@
(define_code_iterator FAC_COMPARISONS [lt le ge gt])
;; SVE integer unary operations.
-(define_code_iterator SVE_INT_UNARY [abs neg not popcount])
-
-;; SVE floating-point unary operations.
-(define_code_iterator SVE_FP_UNARY [abs neg sqrt])
+(define_code_iterator SVE_INT_UNARY [abs neg not clrsb clz popcount])
;; SVE integer binary operations.
(define_code_iterator SVE_INT_BINARY [plus minus mult smax umax smin umin
+ ashift ashiftrt lshiftrt
and ior xor])
;; SVE integer binary division operations.
(define_code_iterator SVE_INT_BINARY_SD [div udiv])
+;; SVE integer binary operations that have an immediate form.
+(define_code_iterator SVE_INT_BINARY_IMM [mult smax smin umax umin])
+
;; SVE floating-point operations with an unpredicated all-register form.
(define_code_iterator SVE_UNPRED_FP_BINARY [plus minus mult])
;; SVE integer comparisons.
(define_code_iterator SVE_INT_CMP [lt le eq ne ge gt ltu leu geu gtu])
-;; SVE floating-point comparisons.
-(define_code_iterator SVE_FP_CMP [lt le eq ne ge gt])
-
;; -------------------------------------------------------------------
;; Code Attributes
;; -------------------------------------------------------------------
@@ -1276,6 +1317,8 @@
(unsigned_fix "fixuns")
(float "float")
(unsigned_float "floatuns")
+ (clrsb "clrsb")
+ (clz "clz")
(popcount "popcount")
(and "and")
(ior "ior")
@@ -1307,8 +1350,7 @@
(leu "leu")
(geu "geu")
(gtu "gtu")
- (abs "abs")
- (sqrt "sqrt")])
+ (abs "abs")])
;; For comparison operators we use the FCM* and CM* instructions.
;; As there are no CMLE or CMLT instructions which act on 3 vector
@@ -1440,35 +1482,45 @@
(smax "smax")
(umin "umin")
(umax "umax")
+ (ashift "lsl")
+ (ashiftrt "asr")
+ (lshiftrt "lsr")
(and "and")
(ior "orr")
(xor "eor")
(not "not")
+ (clrsb "cls")
+ (clz "clz")
(popcount "cnt")])
(define_code_attr sve_int_op_rev [(plus "add")
- (minus "subr")
- (mult "mul")
- (div "sdivr")
- (udiv "udivr")
- (smin "smin")
- (smax "smax")
- (umin "umin")
- (umax "umax")
- (and "and")
- (ior "orr")
- (xor "eor")])
+ (minus "subr")
+ (mult "mul")
+ (div "sdivr")
+ (udiv "udivr")
+ (smin "smin")
+ (smax "smax")
+ (umin "umin")
+ (umax "umax")
+ (ashift "lslr")
+ (ashiftrt "asrr")
+ (lshiftrt "lsrr")
+ (and "and")
+ (ior "orr")
+ (xor "eor")])
;; The floating-point SVE instruction that implements an rtx code.
(define_code_attr sve_fp_op [(plus "fadd")
(minus "fsub")
- (mult "fmul")
- (neg "fneg")
- (abs "fabs")
- (sqrt "fsqrt")])
+ (mult "fmul")])
;; The SVE immediate constraint to use for an rtl code.
-(define_code_attr sve_imm_con [(eq "vsc")
+(define_code_attr sve_imm_con [(mult "vsm")
+ (smax "vsm")
+ (smin "vsm")
+ (umax "vsb")
+ (umin "vsb")
+ (eq "vsc")
(ne "vsc")
(lt "vsc")
(ge "vsc")
@@ -1479,6 +1531,30 @@
(geu "vsd")
(gtu "vsd")])
+;; The prefix letter to use when printing an immediate operand.
+(define_code_attr sve_imm_prefix [(mult "")
+ (smax "")
+ (smin "")
+ (umax "D")
+ (umin "D")])
+
+;; The predicate to use for the second input operand in a cond_<optab><mode>
+;; pattern.
+(define_code_attr sve_pred_int_rhs2_operand
+ [(plus "register_operand")
+ (minus "register_operand")
+ (mult "register_operand")
+ (smax "register_operand")
+ (umax "register_operand")
+ (smin "register_operand")
+ (umin "register_operand")
+ (ashift "aarch64_sve_lshift_operand")
+ (ashiftrt "aarch64_sve_rshift_operand")
+ (lshiftrt "aarch64_sve_rshift_operand")
+ (and "aarch64_sve_pred_and_operand")
+ (ior "register_operand")
+ (xor "register_operand")])
+
;; -------------------------------------------------------------------
;; Int Iterators.
;; -------------------------------------------------------------------
@@ -1498,8 +1574,6 @@
(define_int_iterator FMAXMINV [UNSPEC_FMAXV UNSPEC_FMINV
UNSPEC_FMAXNMV UNSPEC_FMINNMV])
-(define_int_iterator BITWISEV [UNSPEC_ANDV UNSPEC_IORV UNSPEC_XORV])
-
(define_int_iterator LOGICALF [UNSPEC_ANDF UNSPEC_IORF UNSPEC_XORF])
(define_int_iterator HADDSUB [UNSPEC_SHADD UNSPEC_UHADD
@@ -1609,18 +1683,72 @@
(define_int_iterator MUL_HIGHPART [UNSPEC_SMUL_HIGHPART UNSPEC_UMUL_HIGHPART])
-(define_int_iterator SVE_COND_FP_BINARY [UNSPEC_COND_ADD UNSPEC_COND_SUB
- UNSPEC_COND_MUL UNSPEC_COND_DIV
- UNSPEC_COND_MAX UNSPEC_COND_MIN])
+(define_int_iterator SVE_INT_UNARY [UNSPEC_REVB UNSPEC_REVH UNSPEC_REVW])
+
+(define_int_iterator SVE_INT_REDUCTION [UNSPEC_ANDV
+ UNSPEC_IORV
+ UNSPEC_SMAXV
+ UNSPEC_SMINV
+ UNSPEC_UMAXV
+ UNSPEC_UMINV
+ UNSPEC_XORV])
+
+(define_int_iterator SVE_FP_REDUCTION [UNSPEC_FADDV
+ UNSPEC_FMAXV
+ UNSPEC_FMAXNMV
+ UNSPEC_FMINV
+ UNSPEC_FMINNMV])
+
+(define_int_iterator SVE_COND_FP_UNARY [UNSPEC_COND_FABS
+ UNSPEC_COND_FNEG
+ UNSPEC_COND_FRINTA
+ UNSPEC_COND_FRINTI
+ UNSPEC_COND_FRINTM
+ UNSPEC_COND_FRINTN
+ UNSPEC_COND_FRINTP
+ UNSPEC_COND_FRINTX
+ UNSPEC_COND_FRINTZ
+ UNSPEC_COND_FSQRT])
+
+(define_int_iterator SVE_COND_FCVT [UNSPEC_COND_FCVT])
+(define_int_iterator SVE_COND_FCVTI [UNSPEC_COND_FCVTZS UNSPEC_COND_FCVTZU])
+(define_int_iterator SVE_COND_ICVTF [UNSPEC_COND_SCVTF UNSPEC_COND_UCVTF])
+
+(define_int_iterator SVE_COND_FP_BINARY [UNSPEC_COND_FADD
+ UNSPEC_COND_FDIV
+ UNSPEC_COND_FMAXNM
+ UNSPEC_COND_FMINNM
+ UNSPEC_COND_FMUL
+ UNSPEC_COND_FSUB])
+
+(define_int_iterator SVE_COND_FP_BINARY_I1 [UNSPEC_COND_FMAXNM
+ UNSPEC_COND_FMINNM
+ UNSPEC_COND_FMUL])
+
+(define_int_iterator SVE_COND_FP_BINARY_REG [UNSPEC_COND_FDIV])
+
+;; Floating-point max/min operations that correspond to optabs,
+;; as opposed to those that are internal to the port.
+(define_int_iterator SVE_COND_FP_MAXMIN_PUBLIC [UNSPEC_COND_FMAXNM
+ UNSPEC_COND_FMINNM])
(define_int_iterator SVE_COND_FP_TERNARY [UNSPEC_COND_FMLA
UNSPEC_COND_FMLS
UNSPEC_COND_FNMLA
UNSPEC_COND_FNMLS])
-(define_int_iterator SVE_COND_FP_CMP [UNSPEC_COND_LT UNSPEC_COND_LE
- UNSPEC_COND_EQ UNSPEC_COND_NE
- UNSPEC_COND_GE UNSPEC_COND_GT])
+;; SVE FP comparisons that accept #0.0.
+(define_int_iterator SVE_COND_FP_CMP_I0 [UNSPEC_COND_FCMEQ
+ UNSPEC_COND_FCMGE
+ UNSPEC_COND_FCMGT
+ UNSPEC_COND_FCMLE
+ UNSPEC_COND_FCMLT
+ UNSPEC_COND_FCMNE])
+
+(define_int_iterator SVE_COND_FP_ABS_CMP [UNSPEC_COND_FCMGE
+ UNSPEC_COND_FCMGT
+ UNSPEC_COND_FCMLE
+ UNSPEC_COND_FCMLT])
(define_int_iterator FCADD [UNSPEC_FCADD90
UNSPEC_FCADD270])
@@ -1657,16 +1785,43 @@
(UNSPEC_ANDV "and")
(UNSPEC_IORV "ior")
(UNSPEC_XORV "xor")
- (UNSPEC_COND_ADD "add")
- (UNSPEC_COND_SUB "sub")
- (UNSPEC_COND_MUL "mul")
- (UNSPEC_COND_DIV "div")
- (UNSPEC_COND_MAX "smax")
- (UNSPEC_COND_MIN "smin")
+ (UNSPEC_REVB "revb")
+ (UNSPEC_REVH "revh")
+ (UNSPEC_REVW "revw")
+ (UNSPEC_UMAXV "umax")
+ (UNSPEC_UMINV "umin")
+ (UNSPEC_SMAXV "smax")
+ (UNSPEC_SMINV "smin")
+ (UNSPEC_FADDV "plus")
+ (UNSPEC_FMAXNMV "smax")
+ (UNSPEC_FMAXV "smax_nan")
+ (UNSPEC_FMINNMV "smin")
+ (UNSPEC_FMINV "smin_nan")
+ (UNSPEC_COND_FABS "abs")
+ (UNSPEC_COND_FADD "add")
+ (UNSPEC_COND_FCVT "fcvt")
+ (UNSPEC_COND_FCVTZS "fix_trunc")
+ (UNSPEC_COND_FCVTZU "fixuns_trunc")
+ (UNSPEC_COND_FDIV "div")
+ (UNSPEC_COND_FMAXNM "smax")
+ (UNSPEC_COND_FMINNM "smin")
(UNSPEC_COND_FMLA "fma")
(UNSPEC_COND_FMLS "fnma")
+ (UNSPEC_COND_FMUL "mul")
+ (UNSPEC_COND_FNEG "neg")
(UNSPEC_COND_FNMLA "fnms")
- (UNSPEC_COND_FNMLS "fms")])
+ (UNSPEC_COND_FNMLS "fms")
+ (UNSPEC_COND_FRINTA "round")
+ (UNSPEC_COND_FRINTI "nearbyint")
+ (UNSPEC_COND_FRINTM "floor")
+ (UNSPEC_COND_FRINTN "frintn")
+ (UNSPEC_COND_FRINTP "ceil")
+ (UNSPEC_COND_FRINTX "rint")
+ (UNSPEC_COND_FRINTZ "btrunc")
+ (UNSPEC_COND_FSQRT "sqrt")
+ (UNSPEC_COND_FSUB "sub")
+ (UNSPEC_COND_SCVTF "float")
+ (UNSPEC_COND_UCVTF "floatuns")])
(define_int_attr maxmin_uns [(UNSPEC_UMAXV "umax")
(UNSPEC_UMINV "umin")
@@ -1679,7 +1834,9 @@
(UNSPEC_FMINNMV "smin")
(UNSPEC_FMINV "smin_nan")
(UNSPEC_FMAXNM "fmax")
- (UNSPEC_FMINNM "fmin")])
+ (UNSPEC_FMINNM "fmin")
+ (UNSPEC_COND_FMAXNM "fmax")
+ (UNSPEC_COND_FMINNM "fmin")])
(define_int_attr maxmin_uns_op [(UNSPEC_UMAXV "umax")
(UNSPEC_UMINV "umin")
@@ -1694,10 +1851,6 @@
(UNSPEC_FMAXNM "fmaxnm")
(UNSPEC_FMINNM "fminnm")])
-(define_int_attr bit_reduc_op [(UNSPEC_ANDV "andv")
- (UNSPEC_IORV "orv")
- (UNSPEC_XORV "eorv")])
-
;; The SVE logical instruction that implements an unspec.
(define_int_attr logicalf_op [(UNSPEC_ANDF "and")
(UNSPEC_IORF "orr")
@@ -1709,7 +1862,11 @@
(UNSPEC_UNPACKSLO "s")
(UNSPEC_UNPACKULO "u")
(UNSPEC_SMUL_HIGHPART "s")
- (UNSPEC_UMUL_HIGHPART "u")])
+ (UNSPEC_UMUL_HIGHPART "u")
+ (UNSPEC_COND_FCVTZS "s")
+ (UNSPEC_COND_FCVTZU "u")
+ (UNSPEC_COND_SCVTF "s")
+ (UNSPEC_COND_UCVTF "u")])
(define_int_attr sur [(UNSPEC_SHADD "s") (UNSPEC_UHADD "u")
(UNSPEC_SRHADD "sr") (UNSPEC_URHADD "ur")
@@ -1834,18 +1991,15 @@
(UNSPEC_AUTIA1716 "12")
(UNSPEC_AUTIB1716 "14")])
-(define_int_attr perm_insn [(UNSPEC_ZIP1 "zip") (UNSPEC_ZIP2 "zip")
- (UNSPEC_TRN1 "trn") (UNSPEC_TRN2 "trn")
- (UNSPEC_UZP1 "uzp") (UNSPEC_UZP2 "uzp")])
+(define_int_attr perm_insn [(UNSPEC_ZIP1 "zip1") (UNSPEC_ZIP2 "zip2")
+ (UNSPEC_TRN1 "trn1") (UNSPEC_TRN2 "trn2")
+ (UNSPEC_UZP1 "uzp1") (UNSPEC_UZP2 "uzp2")])
; op code for REV instructions (size within which elements are reversed).
(define_int_attr rev_op [(UNSPEC_REV64 "64") (UNSPEC_REV32 "32")
(UNSPEC_REV16 "16")])
-(define_int_attr perm_hilo [(UNSPEC_ZIP1 "1") (UNSPEC_ZIP2 "2")
- (UNSPEC_TRN1 "1") (UNSPEC_TRN2 "2")
- (UNSPEC_UZP1 "1") (UNSPEC_UZP2 "2")
- (UNSPEC_UNPACKSHI "hi") (UNSPEC_UNPACKUHI "hi")
+(define_int_attr perm_hilo [(UNSPEC_UNPACKSHI "hi") (UNSPEC_UNPACKUHI "hi")
(UNSPEC_UNPACKSLO "lo") (UNSPEC_UNPACKULO "lo")])
;; Return true if the associated optab refers to the high-numbered lanes,
@@ -1888,26 +2042,53 @@
(UNSPEC_FMLAL2 "a") (UNSPEC_FMLSL2 "s")])
;; The condition associated with an UNSPEC_COND_<xx>.
-(define_int_attr cmp_op [(UNSPEC_COND_LT "lt")
- (UNSPEC_COND_LE "le")
- (UNSPEC_COND_EQ "eq")
- (UNSPEC_COND_NE "ne")
- (UNSPEC_COND_GE "ge")
- (UNSPEC_COND_GT "gt")])
-
-(define_int_attr sve_fp_op [(UNSPEC_COND_ADD "fadd")
- (UNSPEC_COND_SUB "fsub")
- (UNSPEC_COND_MUL "fmul")
- (UNSPEC_COND_DIV "fdiv")
- (UNSPEC_COND_MAX "fmaxnm")
- (UNSPEC_COND_MIN "fminnm")])
-
-(define_int_attr sve_fp_op_rev [(UNSPEC_COND_ADD "fadd")
- (UNSPEC_COND_SUB "fsubr")
- (UNSPEC_COND_MUL "fmul")
- (UNSPEC_COND_DIV "fdivr")
- (UNSPEC_COND_MAX "fmaxnm")
- (UNSPEC_COND_MIN "fminnm")])
+(define_int_attr cmp_op [(UNSPEC_COND_FCMEQ "eq")
+ (UNSPEC_COND_FCMGE "ge")
+ (UNSPEC_COND_FCMGT "gt")
+ (UNSPEC_COND_FCMLE "le")
+ (UNSPEC_COND_FCMLT "lt")
+ (UNSPEC_COND_FCMNE "ne")
+ (UNSPEC_COND_FCMUO "uo")])
+
+(define_int_attr sve_int_op [(UNSPEC_ANDV "andv")
+ (UNSPEC_IORV "orv")
+ (UNSPEC_XORV "eorv")
+ (UNSPEC_UMAXV "umaxv")
+ (UNSPEC_UMINV "uminv")
+ (UNSPEC_SMAXV "smaxv")
+ (UNSPEC_SMINV "sminv")
+ (UNSPEC_REVB "revb")
+ (UNSPEC_REVH "revh")
+ (UNSPEC_REVW "revw")])
+
+(define_int_attr sve_fp_op [(UNSPEC_FADDV "faddv")
+ (UNSPEC_FMAXNMV "fmaxnmv")
+ (UNSPEC_FMAXV "fmaxv")
+ (UNSPEC_FMINNMV "fminnmv")
+ (UNSPEC_FMINV "fminv")
+ (UNSPEC_COND_FABS "fabs")
+ (UNSPEC_COND_FADD "fadd")
+ (UNSPEC_COND_FDIV "fdiv")
+ (UNSPEC_COND_FMAXNM "fmaxnm")
+ (UNSPEC_COND_FMINNM "fminnm")
+ (UNSPEC_COND_FMUL "fmul")
+ (UNSPEC_COND_FNEG "fneg")
+ (UNSPEC_COND_FRINTA "frinta")
+ (UNSPEC_COND_FRINTI "frinti")
+ (UNSPEC_COND_FRINTM "frintm")
+ (UNSPEC_COND_FRINTN "frintn")
+ (UNSPEC_COND_FRINTP "frintp")
+ (UNSPEC_COND_FRINTX "frintx")
+ (UNSPEC_COND_FRINTZ "frintz")
+ (UNSPEC_COND_FSQRT "fsqrt")
+ (UNSPEC_COND_FSUB "fsub")])
+
+(define_int_attr sve_fp_op_rev [(UNSPEC_COND_FADD "fadd")
+ (UNSPEC_COND_FDIV "fdivr")
+ (UNSPEC_COND_FMAXNM "fmaxnm")
+ (UNSPEC_COND_FMINNM "fminnm")
+ (UNSPEC_COND_FMUL "fmul")
+ (UNSPEC_COND_FSUB "fsubr")])
(define_int_attr rot [(UNSPEC_FCADD90 "90")
(UNSPEC_FCADD270 "270")
@@ -1926,9 +2107,33 @@
(UNSPEC_COND_FNMLA "fnmad")
(UNSPEC_COND_FNMLS "fnmsb")])
-(define_int_attr commutative [(UNSPEC_COND_ADD "true")
- (UNSPEC_COND_SUB "false")
- (UNSPEC_COND_MUL "true")
- (UNSPEC_COND_DIV "false")
- (UNSPEC_COND_MIN "true")
- (UNSPEC_COND_MAX "true")])
+;; The predicate to use for the first input operand in a floating-point
+;; <optab><mode>3 pattern.
+(define_int_attr sve_pred_fp_rhs1_operand
+ [(UNSPEC_COND_FADD "register_operand")
+ (UNSPEC_COND_FDIV "register_operand")
+ (UNSPEC_COND_FMAXNM "register_operand")
+ (UNSPEC_COND_FMINNM "register_operand")
+ (UNSPEC_COND_FMUL "register_operand")
+ (UNSPEC_COND_FSUB "aarch64_sve_float_arith_operand")])
+
+;; The predicate to use for the second input operand in a floating-point
+;; <optab><mode>3 pattern.
+(define_int_attr sve_pred_fp_rhs2_operand
+ [(UNSPEC_COND_FADD "aarch64_sve_float_arith_with_sub_operand")
+ (UNSPEC_COND_FDIV "register_operand")
+ (UNSPEC_COND_FMAXNM "aarch64_sve_float_maxmin_operand")
+ (UNSPEC_COND_FMINNM "aarch64_sve_float_maxmin_operand")
+ (UNSPEC_COND_FMUL "aarch64_sve_float_mul_operand")
+ (UNSPEC_COND_FSUB "register_operand")])
+
+;; Likewise for immediates only.
+(define_int_attr sve_pred_fp_rhs2_immediate
+ [(UNSPEC_COND_FMAXNM "aarch64_sve_float_maxmin_immediate")
+ (UNSPEC_COND_FMINNM "aarch64_sve_float_maxmin_immediate")
+ (UNSPEC_COND_FMUL "aarch64_sve_float_mul_immediate")])
+
+;; The minimum number of element bits that an instruction can handle.
+(define_int_attr min_elem_bits [(UNSPEC_REVB "16")
+ (UNSPEC_REVH "32")
+ (UNSPEC_REVW "64")])
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 10100ca..d8c3779 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -39,6 +39,13 @@
(and (match_code "const_int")
(match_test "op == CONST0_RTX (mode)")))
+(define_predicate "const_1_to_3_operand"
+ (match_code "const_int,const_vector")
+{
+ op = unwrap_const_vec_duplicate (op);
+ return CONST_INT_P (op) && IN_RANGE (INTVAL (op), 1, 3);
+})
+
(define_special_predicate "subreg_lowpart_operator"
(and (match_code "subreg")
(match_test "subreg_lowpart_p (op)")))
@@ -53,13 +60,12 @@
(define_predicate "aarch64_simd_register"
(and (match_code "reg")
- (ior (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_LO_REGS")
- (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_REGS"))))
+ (match_test "FP_REGNUM_P (REGNO (op))")))
(define_predicate "aarch64_reg_or_zero"
- (and (match_code "reg,subreg,const_int")
+ (and (match_code "reg,subreg,const_int,const_double")
(ior (match_operand 0 "register_operand")
- (match_test "op == const0_rtx"))))
+ (match_test "op == CONST0_RTX (GET_MODE (op))"))))
(define_predicate "aarch64_reg_or_fp_zero"
(ior (match_operand 0 "register_operand")
@@ -98,6 +104,10 @@
(and (match_code "const_double")
(match_test "aarch64_fpconst_pow_of_2 (op) > 0")))
+(define_predicate "aarch64_fp_pow2_recip"
+ (and (match_code "const_double")
+ (match_test "aarch64_fpconst_pow2_recip (op) > 0")))
+
(define_predicate "aarch64_fp_vec_pow2"
(match_test "aarch64_vec_fpconst_pow_of_2 (op) > 0"))
@@ -138,10 +148,18 @@
(and (match_operand 0 "aarch64_pluslong_immediate")
(not (match_operand 0 "aarch64_plus_immediate"))))
+(define_predicate "aarch64_sve_scalar_inc_dec_immediate"
+ (and (match_code "const_poly_int")
+ (match_test "aarch64_sve_scalar_inc_dec_immediate_p (op)")))
+
(define_predicate "aarch64_sve_addvl_addpl_immediate"
(and (match_code "const_poly_int")
(match_test "aarch64_sve_addvl_addpl_immediate_p (op)")))
+(define_predicate "aarch64_sve_plus_immediate"
+ (ior (match_operand 0 "aarch64_sve_scalar_inc_dec_immediate")
+ (match_operand 0 "aarch64_sve_addvl_addpl_immediate")))
+
(define_predicate "aarch64_split_add_offset_immediate"
(and (match_code "const_poly_int")
(match_test "aarch64_add_offset_temporaries (op) == 1")))
@@ -149,7 +167,8 @@
(define_predicate "aarch64_pluslong_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "aarch64_pluslong_immediate")
- (match_operand 0 "aarch64_sve_addvl_addpl_immediate")))
+ (and (match_test "TARGET_SVE")
+ (match_operand 0 "aarch64_sve_plus_immediate"))))
(define_predicate "aarch64_pluslong_or_poly_operand"
(ior (match_operand 0 "aarch64_pluslong_operand")
@@ -432,6 +451,12 @@
return aarch64_simd_check_vect_par_cnst_half (op, mode, false);
})
+(define_predicate "descending_int_parallel"
+ (match_code "parallel")
+{
+ return aarch64_stepped_int_parallel_p (op, -1);
+})
+
(define_special_predicate "aarch64_simd_lshift_imm"
(match_code "const,const_vector")
{
@@ -448,6 +473,10 @@
(and (match_code "const,const_vector")
(match_test "op == CONST0_RTX (GET_MODE (op))")))
+(define_predicate "aarch64_simd_imm_one"
+ (and (match_code "const_vector")
+ (match_test "op == CONST1_RTX (GET_MODE (op))")))
+
(define_predicate "aarch64_simd_or_scalar_imm_zero"
(and (match_code "const_int,const_double,const,const_vector")
(match_test "op == CONST0_RTX (GET_MODE (op))")))
@@ -544,6 +573,10 @@
(and (match_operand 0 "memory_operand")
(match_test "aarch64_sve_ld1r_operand_p (op)")))
+(define_predicate "aarch64_sve_ld1rq_operand"
+ (and (match_code "mem")
+ (match_test "aarch64_sve_ld1rq_operand_p (op)")))
+
;; Like memory_operand, but restricted to addresses that are valid for
;; SVE LDR and STR instructions.
(define_predicate "aarch64_sve_ldr_operand"
@@ -582,21 +615,50 @@
(and (match_code "const,const_vector")
(match_test "aarch64_sve_arith_immediate_p (op, true)")))
-(define_predicate "aarch64_sve_inc_dec_immediate"
+(define_predicate "aarch64_sve_vector_inc_dec_immediate"
(and (match_code "const,const_vector")
- (match_test "aarch64_sve_inc_dec_immediate_p (op)")))
+ (match_test "aarch64_sve_vector_inc_dec_immediate_p (op)")))
+
+(define_predicate "aarch64_sve_uxtb_immediate"
+ (and (match_code "const_vector")
+ (match_test "GET_MODE_UNIT_BITSIZE (GET_MODE (op)) > 8")
+ (match_test "aarch64_const_vec_all_same_int_p (op, 0xff)")))
+
+(define_predicate "aarch64_sve_uxth_immediate"
+ (and (match_code "const_vector")
+ (match_test "GET_MODE_UNIT_BITSIZE (GET_MODE (op)) > 16")
+ (match_test "aarch64_const_vec_all_same_int_p (op, 0xffff)")))
+
+(define_predicate "aarch64_sve_uxtw_immediate"
+ (and (match_code "const_vector")
+ (match_test "GET_MODE_UNIT_BITSIZE (GET_MODE (op)) > 32")
+ (match_test "aarch64_const_vec_all_same_int_p (op, 0xffffffff)")))
+
+(define_predicate "aarch64_sve_uxt_immediate"
+ (ior (match_operand 0 "aarch64_sve_uxtb_immediate")
+ (match_operand 0 "aarch64_sve_uxth_immediate")
+ (match_operand 0 "aarch64_sve_uxtw_immediate")))
(define_predicate "aarch64_sve_logical_immediate"
(and (match_code "const,const_vector")
(match_test "aarch64_sve_bitmask_immediate_p (op)")))
-(define_predicate "aarch64_sve_mul_immediate"
+;; Used for SVE UMAX and UMIN.
+(define_predicate "aarch64_sve_vsb_immediate"
+ (and (match_code "const_vector")
+ (match_test "GET_MODE_INNER (GET_MODE (op)) == QImode
+ ? aarch64_const_vec_all_same_in_range_p (op, -128, 127)
+ : aarch64_const_vec_all_same_in_range_p (op, 0, 255)")))
+
+;; Used for SVE MUL, SMAX and SMIN.
+(define_predicate "aarch64_sve_vsm_immediate"
(and (match_code "const,const_vector")
(match_test "aarch64_const_vec_all_same_in_range_p (op, -128, 127)")))
(define_predicate "aarch64_sve_dup_immediate"
(and (match_code "const,const_vector")
- (match_test "aarch64_sve_dup_immediate_p (op)")))
+ (ior (match_test "aarch64_sve_dup_immediate_p (op)")
+ (match_test "aarch64_float_const_representable_p (op)"))))
(define_predicate "aarch64_sve_cmp_vsc_immediate"
(and (match_code "const,const_vector")
@@ -614,14 +676,23 @@
(and (match_code "const,const_vector")
(match_test "aarch64_sve_float_arith_immediate_p (op, false)")))
-(define_predicate "aarch64_sve_float_arith_with_sub_immediate"
+(define_predicate "aarch64_sve_float_negated_arith_immediate"
(and (match_code "const,const_vector")
(match_test "aarch64_sve_float_arith_immediate_p (op, true)")))
+(define_predicate "aarch64_sve_float_arith_with_sub_immediate"
+ (ior (match_operand 0 "aarch64_sve_float_arith_immediate")
+ (match_operand 0 "aarch64_sve_float_negated_arith_immediate")))
+
(define_predicate "aarch64_sve_float_mul_immediate"
(and (match_code "const,const_vector")
(match_test "aarch64_sve_float_mul_immediate_p (op)")))
+(define_predicate "aarch64_sve_float_maxmin_immediate"
+ (and (match_code "const_vector")
+ (ior (match_test "op == CONST0_RTX (GET_MODE (op))")
+ (match_test "op == CONST1_RTX (GET_MODE (op))"))))
+
(define_predicate "aarch64_sve_arith_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "aarch64_sve_arith_immediate")))
@@ -629,7 +700,11 @@
(define_predicate "aarch64_sve_add_operand"
(ior (match_operand 0 "aarch64_sve_arith_operand")
(match_operand 0 "aarch64_sve_sub_arith_immediate")
- (match_operand 0 "aarch64_sve_inc_dec_immediate")))
+ (match_operand 0 "aarch64_sve_vector_inc_dec_immediate")))
+
+(define_predicate "aarch64_sve_pred_and_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "aarch64_sve_uxt_immediate")))
(define_predicate "aarch64_sve_logical_operand"
(ior (match_operand 0 "register_operand")
@@ -643,9 +718,17 @@
(ior (match_operand 0 "register_operand")
(match_operand 0 "aarch64_simd_rshift_imm")))
-(define_predicate "aarch64_sve_mul_operand"
+(define_predicate "aarch64_sve_vsb_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "aarch64_sve_vsb_immediate")))
+
+(define_predicate "aarch64_sve_vsm_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "aarch64_sve_vsm_immediate")))
+
+(define_predicate "aarch64_sve_reg_or_dup_imm"
(ior (match_operand 0 "register_operand")
- (match_operand 0 "aarch64_sve_mul_immediate")))
+ (match_operand 0 "aarch64_sve_dup_immediate")))
(define_predicate "aarch64_sve_cmp_vsc_operand"
(ior (match_operand 0 "register_operand")
@@ -664,17 +747,31 @@
(match_operand 0 "aarch64_sve_float_arith_immediate")))
(define_predicate "aarch64_sve_float_arith_with_sub_operand"
- (ior (match_operand 0 "aarch64_sve_float_arith_operand")
+ (ior (match_operand 0 "register_operand")
(match_operand 0 "aarch64_sve_float_arith_with_sub_immediate")))
(define_predicate "aarch64_sve_float_mul_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "aarch64_sve_float_mul_immediate")))
+(define_predicate "aarch64_sve_float_maxmin_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "aarch64_sve_float_maxmin_immediate")))
+
(define_predicate "aarch64_sve_vec_perm_operand"
(ior (match_operand 0 "register_operand")
(match_operand 0 "aarch64_constant_vector_operand")))
+(define_predicate "aarch64_sve_ptrue_flag"
+ (and (match_code "const_int")
+ (ior (match_test "INTVAL (op) == SVE_MAYBE_NOT_PTRUE")
+ (match_test "INTVAL (op) == SVE_KNOWN_PTRUE"))))
+
+(define_predicate "aarch64_sve_gp_strictness"
+ (and (match_code "const_int")
+ (ior (match_test "INTVAL (op) == SVE_RELAXED_GP")
+ (match_test "INTVAL (op) == SVE_STRICT_GP"))))
+
(define_predicate "aarch64_gather_scale_operand_w"
(and (match_code "const_int")
(match_test "INTVAL (op) == 1 || INTVAL (op) == 4")))
diff --git a/gcc/config/aarch64/t-aarch64 b/gcc/config/aarch64/t-aarch64
index ee471f8..391b4a2 100644
--- a/gcc/config/aarch64/t-aarch64
+++ b/gcc/config/aarch64/t-aarch64
@@ -103,3 +103,10 @@ aarch64-bti-insert.o: $(srcdir)/config/aarch64/aarch64-bti-insert.c \
comma=,
MULTILIB_OPTIONS = $(subst $(comma),/, $(patsubst %, mabi=%, $(subst $(comma),$(comma)mabi=,$(TM_MULTILIB_CONFIG))))
MULTILIB_DIRNAMES = $(subst $(comma), ,$(TM_MULTILIB_CONFIG))
+
+insn-conditions.md: s-check-sve-md
+s-check-sve-md: $(srcdir)/config/aarch64/check-sve-md.awk \
+ $(srcdir)/config/aarch64/aarch64-sve.md
+ $(AWK) -f $(srcdir)/config/aarch64/check-sve-md.awk \
+ $(srcdir)/config/aarch64/aarch64-sve.md
+ $(STAMP) s-check-sve-md
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 10656be..d551af7 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -526,7 +526,7 @@ alpha_option_override (void)
alpha_fptm = ALPHA_FPTM_SU;
}
if (target_flags_explicit & MASK_LONG_DOUBLE_128)
- warning (0, "128-bit long double not supported for VAX floats");
+ warning (0, "128-bit %<long double%> not supported for VAX floats");
target_flags &= ~MASK_LONG_DOUBLE_128;
}
@@ -6657,7 +6657,7 @@ alpha_expand_builtin (tree exp, rtx target,
#define MAX_ARGS 2
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
tree arg;
call_expr_arg_iterator iter;
enum insn_code icode;
@@ -7056,7 +7056,7 @@ alpha_fold_builtin (tree fndecl, int n_args, tree *op,
}
}
- switch (DECL_FUNCTION_CODE (fndecl))
+ switch (DECL_MD_FUNCTION_CODE (fndecl))
{
case ALPHA_BUILTIN_CMPBGE:
return alpha_fold_builtin_cmpbge (opint, op_const);
@@ -7172,7 +7172,7 @@ alpha_gimple_fold_builtin (gimple_stmt_iterator *gsi)
{
tree arg0, arg1;
- switch (DECL_FUNCTION_CODE (fndecl))
+ switch (DECL_MD_FUNCTION_CODE (fndecl))
{
case ALPHA_BUILTIN_UMULH:
arg0 = gimple_call_arg (stmt, 0);
diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index 74e5247..1220e77 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -25,7 +25,6 @@ extern machine_mode arc_select_cc_mode (enum rtx_code, rtx, rtx);
extern struct rtx_def *gen_compare_reg (rtx, machine_mode);
/* Declarations for various fns used in the .md file. */
-extern void arc_output_function_epilogue (FILE *, HOST_WIDE_INT, int);
extern const char *output_shift (rtx *);
extern bool compact_sda_memory_operand (rtx, machine_mode, bool);
extern bool arc_double_limm_p (rtx);
@@ -42,8 +41,6 @@ extern void arc_expand_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx);
extern void arc_split_compare_and_swap (rtx *);
extern void arc_expand_compare_and_swap (rtx *);
extern bool compact_memory_operand_p (rtx, machine_mode, bool, bool);
-extern int arc_return_address_register (unsigned int);
-extern unsigned int arc_compute_function_type (struct function *);
extern bool arc_is_uncached_mem_p (rtx);
extern bool gen_operands_ldd_std (rtx *operands, bool load, bool commute);
extern bool arc_check_multi (rtx, bool);
@@ -52,9 +49,9 @@ extern bool arc_check_ior_const (HOST_WIDE_INT );
extern void arc_split_ior (rtx *);
extern bool arc_check_mov_const (HOST_WIDE_INT );
extern bool arc_split_mov_const (rtx *);
+extern bool arc_can_use_return_insn (void);
#endif /* RTX_CODE */
-extern unsigned int arc_compute_frame_size (int);
extern bool arc_ccfsm_branch_deleted_p (void);
extern void arc_ccfsm_record_branch_deleted (void);
@@ -71,7 +68,6 @@ extern bool arc_is_longcall_p (rtx);
extern bool arc_is_shortcall_p (rtx);
extern bool valid_brcc_with_delay_p (rtx *);
extern bool arc_ccfsm_cond_exec_p (void);
-struct secondary_reload_info;
extern rtx disi_highpart (rtx);
extern int arc_adjust_insn_length (rtx_insn *, int, bool);
extern int arc_corereg_hazard (rtx, rtx);
@@ -89,7 +85,6 @@ extern void arc_expand_prologue (void);
extern void arc_expand_epilogue (int);
extern void arc_init_expanders (void);
extern int arc_check_millicode (rtx op, int offset, int load_p);
-extern int arc_get_unalign (void);
extern void arc_clear_unalign (void);
extern void arc_toggle_unalign (void);
extern void split_addsi (rtx *);
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 71e6576..98fbfea 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -206,6 +206,13 @@ static int rgf_banked_register_count;
this to be no less than the 1/p */
#define MAX_INSNS_SKIPPED 3
+/* ZOL control registers. */
+#define AUX_LP_START 0x02
+#define AUX_LP_END 0x03
+
+/* FPX AUX registers. */
+#define AUX_DPFP_START 0x301
+
/* A nop is needed between a 4 byte insn that sets the condition codes and
a branch that uses them (the same isn't true for an 8 byte insn that sets
the condition codes). Set by arc_ccfsm_advance. Used by
@@ -298,6 +305,129 @@ static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
/* Globally visible information about currently selected cpu. */
const arc_cpu_t *arc_selected_cpu;
+/* Traditionally, we push saved registers first in the prologue,
+ then we allocate the rest of the frame - and reverse in the epilogue.
+ This has still its merits for ease of debugging, or saving code size
+ or even execution time if the stack frame is so large that some accesses
+ can't be encoded anymore with offsets in the instruction code when using
+ a different scheme.
+ Also, it would be a good starting point if we got instructions to help
+ with register save/restore.
+
+ However, often stack frames are small, and the pushing / popping has
+ some costs:
+ - the stack modification prevents a lot of scheduling.
+ - frame allocation / deallocation may need extra instructions.
+ - we need to place a memory barrier after frame allocation to avoid
+ the delay slot scheduler to reschedule a frame related info and
+ messing up with dwarf unwinding. The barrier before deallocation
+ is for flushing all pending sp operations.
+
+ Thus, for small frames, we'd like to use a different scheme:
+ - The frame is allocated in full with the first prologue instruction,
+ and deallocated in full with the last epilogue instruction.
+ Thus, the instructions in-between can be freely scheduled.
+ - If the function has no outgoing arguments on the stack, we can allocate
+ one register save slot at the top of the stack. This register can then
+ be saved simultaneously with frame allocation, and restored with
+ frame deallocation.
+ This register can be picked depending on scheduling considerations,
+ although same though should go into having some set of registers
+ to be potentially lingering after a call, and others to be available
+ immediately - i.e. in the absence of interprocedual optimization, we
+ can use an ABI-like convention for register allocation to reduce
+ stalls after function return. */
+
+/* ARCompact stack frames look like:
+
+ Before call After call
+ high +-----------------------+ +-----------------------+
+ mem | reg parm save area | | reg parm save area |
+ | only created for | | only created for |
+ | variable arg fns | | variable arg fns |
+ AP +-----------------------+ +-----------------------+
+ | return addr register | | return addr register |
+ | (if required) | | (if required) |
+ +-----------------------+ +-----------------------+
+ | | | |
+ | reg save area | | reg save area |
+ | | | |
+ +-----------------------+ +-----------------------+
+ | frame pointer | | frame pointer |
+ | (if required) | | (if required) |
+ FP +-----------------------+ +-----------------------+
+ | | | |
+ | local/temp variables | | local/temp variables |
+ | | | |
+ +-----------------------+ +-----------------------+
+ | | | |
+ | arguments on stack | | arguments on stack |
+ | | | |
+ SP +-----------------------+ +-----------------------+
+ | reg parm save area |
+ | only created for |
+ | variable arg fns |
+ AP +-----------------------+
+ | return addr register |
+ | (if required) |
+ +-----------------------+
+ | |
+ | reg save area |
+ | |
+ +-----------------------+
+ | frame pointer |
+ | (if required) |
+ FP +-----------------------+
+ | |
+ | local/temp variables |
+ | |
+ +-----------------------+
+ | |
+ | arguments on stack |
+ low | |
+ mem SP +-----------------------+
+
+Notes:
+1) The "reg parm save area" does not exist for non variable argument fns.
+ The "reg parm save area" can be eliminated completely if we created our
+ own va-arc.h, but that has tradeoffs as well (so it's not done). */
+
+/* Structure to be filled in by arc_compute_frame_size with register
+ save masks, and offsets for the current function. */
+struct GTY (()) arc_frame_info
+{
+ unsigned int total_size; /* # bytes that the entire frame takes up. */
+ unsigned int extra_size; /* # bytes of extra stuff. */
+ unsigned int pretend_size; /* # bytes we push and pretend caller did. */
+ unsigned int args_size; /* # bytes that outgoing arguments take up. */
+ unsigned int reg_size; /* # bytes needed to store regs. */
+ unsigned int var_size; /* # bytes that variables take up. */
+ uint64_t gmask; /* Mask of saved gp registers. */
+ bool initialized; /* FALSE if frame size already calculated. */
+ short millicode_start_reg;
+ short millicode_end_reg;
+ bool save_return_addr;
+};
+
+/* GMASK bit length -1. */
+#define GMASK_LEN 63
+
+/* Defining data structures for per-function information. */
+
+typedef struct GTY (()) machine_function
+{
+ unsigned int fn_type;
+ struct arc_frame_info frame_info;
+ /* To keep track of unalignment caused by short insns. */
+ int unalign;
+ struct arc_ccfsm ccfsm_current;
+ /* Map from uid to ccfsm state during branch shortening. */
+ rtx ccfsm_current_insn;
+ char arc_reorg_started;
+ char prescan_initialized;
+} machine_function;
+
+
/* Given a symbol RTX (const (symb <+ const_int>), returns its
alignment. */
@@ -1996,6 +2126,50 @@ arc_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
return NULL_TREE;
}
+/* Type of function DECL.
+
+ The result is cached. To reset the cache at the end of a function,
+ call with DECL = NULL_TREE. */
+
+static unsigned int
+arc_compute_function_type (struct function *fun)
+{
+ tree attr, decl = fun->decl;
+ unsigned int fn_type = fun->machine->fn_type;
+
+ if (fn_type != ARC_FUNCTION_UNKNOWN)
+ return fn_type;
+
+ /* Check if it is a naked function. */
+ if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) != NULL_TREE)
+ fn_type |= ARC_FUNCTION_NAKED;
+ else
+ fn_type |= ARC_FUNCTION_NORMAL;
+
+ /* Now see if this is an interrupt handler. */
+ attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
+ if (attr != NULL_TREE)
+ {
+ tree value, args = TREE_VALUE (attr);
+
+ gcc_assert (list_length (args) == 1);
+ value = TREE_VALUE (args);
+ gcc_assert (TREE_CODE (value) == STRING_CST);
+
+ if (!strcmp (TREE_STRING_POINTER (value), "ilink1")
+ || !strcmp (TREE_STRING_POINTER (value), "ilink"))
+ fn_type |= ARC_FUNCTION_ILINK1;
+ else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
+ fn_type |= ARC_FUNCTION_ILINK2;
+ else if (!strcmp (TREE_STRING_POINTER (value), "firq"))
+ fn_type |= ARC_FUNCTION_FIRQ;
+ else
+ gcc_unreachable ();
+ }
+
+ return fun->machine->fn_type = fn_type;
+}
+
/* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
static bool
@@ -2402,174 +2576,6 @@ frame_stack_add (HOST_WIDE_INT offset)
return frame_add (stack_pointer_rtx, offset);
}
-/* Traditionally, we push saved registers first in the prologue,
- then we allocate the rest of the frame - and reverse in the epilogue.
- This has still its merits for ease of debugging, or saving code size
- or even execution time if the stack frame is so large that some accesses
- can't be encoded anymore with offsets in the instruction code when using
- a different scheme.
- Also, it would be a good starting point if we got instructions to help
- with register save/restore.
-
- However, often stack frames are small, and the pushing / popping has
- some costs:
- - the stack modification prevents a lot of scheduling.
- - frame allocation / deallocation needs extra instructions.
- - unless we know that we compile ARC700 user code, we need to put
- a memory barrier after frame allocation / before deallocation to
- prevent interrupts clobbering our data in the frame.
- In particular, we don't have any such guarantees for library functions,
- which tend to, on the other hand, to have small frames.
-
- Thus, for small frames, we'd like to use a different scheme:
- - The frame is allocated in full with the first prologue instruction,
- and deallocated in full with the last epilogue instruction.
- Thus, the instructions in-betwen can be freely scheduled.
- - If the function has no outgoing arguments on the stack, we can allocate
- one register save slot at the top of the stack. This register can then
- be saved simultanously with frame allocation, and restored with
- frame deallocation.
- This register can be picked depending on scheduling considerations,
- although same though should go into having some set of registers
- to be potentially lingering after a call, and others to be available
- immediately - i.e. in the absence of interprocedual optimization, we
- can use an ABI-like convention for register allocation to reduce
- stalls after function return. */
-/* Function prologue/epilogue handlers. */
-
-/* ARCompact stack frames look like:
-
- Before call After call
- high +-----------------------+ +-----------------------+
- mem | reg parm save area | | reg parm save area |
- | only created for | | only created for |
- | variable arg fns | | variable arg fns |
- AP +-----------------------+ +-----------------------+
- | return addr register | | return addr register |
- | (if required) | | (if required) |
- +-----------------------+ +-----------------------+
- | | | |
- | reg save area | | reg save area |
- | | | |
- +-----------------------+ +-----------------------+
- | frame pointer | | frame pointer |
- | (if required) | | (if required) |
- FP +-----------------------+ +-----------------------+
- | | | |
- | local/temp variables | | local/temp variables |
- | | | |
- +-----------------------+ +-----------------------+
- | | | |
- | arguments on stack | | arguments on stack |
- | | | |
- SP +-----------------------+ +-----------------------+
- | reg parm save area |
- | only created for |
- | variable arg fns |
- AP +-----------------------+
- | return addr register |
- | (if required) |
- +-----------------------+
- | |
- | reg save area |
- | |
- +-----------------------+
- | frame pointer |
- | (if required) |
- FP +-----------------------+
- | |
- | local/temp variables |
- | |
- +-----------------------+
- | |
- | arguments on stack |
- low | |
- mem SP +-----------------------+
-
-Notes:
-1) The "reg parm save area" does not exist for non variable argument fns.
- The "reg parm save area" can be eliminated completely if we created our
- own va-arc.h, but that has tradeoffs as well (so it's not done). */
-
-/* Structure to be filled in by arc_compute_frame_size with register
- save masks, and offsets for the current function. */
-struct GTY (()) arc_frame_info
-{
- unsigned int total_size; /* # bytes that the entire frame takes up. */
- unsigned int extra_size; /* # bytes of extra stuff. */
- unsigned int pretend_size; /* # bytes we push and pretend caller did. */
- unsigned int args_size; /* # bytes that outgoing arguments take up. */
- unsigned int reg_size; /* # bytes needed to store regs. */
- unsigned int var_size; /* # bytes that variables take up. */
- unsigned int gmask; /* Mask of saved gp registers. */
- bool initialized; /* FALSE if frame size already calculated. */
- short millicode_start_reg;
- short millicode_end_reg;
- bool save_return_addr;
-};
-
-/* GMASK bit length -1. */
-#define GMASK_LEN 31
-
-/* Defining data structures for per-function information. */
-
-typedef struct GTY (()) machine_function
-{
- unsigned int fn_type;
- struct arc_frame_info frame_info;
- /* To keep track of unalignment caused by short insns. */
- int unalign;
- struct arc_ccfsm ccfsm_current;
- /* Map from uid to ccfsm state during branch shortening. */
- rtx ccfsm_current_insn;
- char arc_reorg_started;
- char prescan_initialized;
-} machine_function;
-
-/* Type of function DECL.
-
- The result is cached. To reset the cache at the end of a function,
- call with DECL = NULL_TREE. */
-
-unsigned int
-arc_compute_function_type (struct function *fun)
-{
- tree attr, decl = fun->decl;
- unsigned int fn_type = fun->machine->fn_type;
-
- if (fn_type != ARC_FUNCTION_UNKNOWN)
- return fn_type;
-
- /* Check if it is a naked function. */
- if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) != NULL_TREE)
- fn_type |= ARC_FUNCTION_NAKED;
- else
- fn_type |= ARC_FUNCTION_NORMAL;
-
- /* Now see if this is an interrupt handler. */
- attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
- if (attr != NULL_TREE)
- {
- tree value, args = TREE_VALUE (attr);
-
- gcc_assert (list_length (args) == 1);
- value = TREE_VALUE (args);
- gcc_assert (TREE_CODE (value) == STRING_CST);
-
- if (!strcmp (TREE_STRING_POINTER (value), "ilink1")
- || !strcmp (TREE_STRING_POINTER (value), "ilink"))
- fn_type |= ARC_FUNCTION_ILINK1;
- else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
- fn_type |= ARC_FUNCTION_ILINK2;
- else if (!strcmp (TREE_STRING_POINTER (value), "firq"))
- fn_type |= ARC_FUNCTION_FIRQ;
- else
- gcc_unreachable ();
- }
-
- return fun->machine->fn_type = fn_type;
-}
-
/* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
Register Allocator) pass, while we want to get the frame size
@@ -2619,14 +2625,12 @@ arc_frame_pointer_needed (void)
}
/* Tell prologue and epilogue if register REGNO should be saved /
- restored. The return address, stack pointer and frame pointer are
- treated separately. Don't consider them here. Addition for pic:
- The gp register needs to be saved if the current function changes
- it to access gotoff variables. FIXME: This will not be needed if
- we used some arbitrary register instead of r26. */
+ restored. The SPECIAL_P is true when the register may need special
+ ld/st sequence. The return address, and stack pointer are treated
+ separately. Don't consider them here. */
static bool
-arc_must_save_register (int regno, struct function *func)
+arc_must_save_register (int regno, struct function *func, bool special_p)
{
unsigned int fn_type = arc_compute_function_type (func);
bool irq_auto_save_p = ((irq_ctrl_saved.irq_save_last_reg >= regno)
@@ -2656,8 +2660,69 @@ arc_must_save_register (int regno, struct function *func)
switch (regno)
{
+ case ILINK1_REG:
case RETURN_ADDR_REGNUM:
case STACK_POINTER_REGNUM:
+ /* The stack pointer and the return address are handled
+ separately. */
+ return false;
+
+ case R30_REG:
+ /* r30 is either used as ilink2 by ARCv1 or as a free register
+ by ARCv2. */
+ if (!TARGET_V2)
+ return false;
+ break;
+
+ case R40_REG:
+ case R41_REG:
+ case R42_REG:
+ case R43_REG:
+ case R44_REG:
+ /* If those ones are used by the FPX machinery, we handle them
+ separately. */
+ if (TARGET_DPFP && !special_p)
+ return false;
+ /* FALLTHRU. */
+
+ case R32_REG:
+ case R33_REG:
+ case R34_REG:
+ case R35_REG:
+ case R36_REG:
+ case R37_REG:
+ case R38_REG:
+ case R39_REG:
+ case R45_REG:
+ case R46_REG:
+ case R47_REG:
+ case R48_REG:
+ case R49_REG:
+ case R50_REG:
+ case R51_REG:
+ case R52_REG:
+ case R53_REG:
+ case R54_REG:
+ case R55_REG:
+ case R56_REG:
+ case R57_REG:
+ case R58_REG:
+ case R59_REG:
+ /* The Extension Registers. */
+ if (ARC_INTERRUPT_P (fn_type)
+ && (df_regs_ever_live_p (RETURN_ADDR_REGNUM)
+ || df_regs_ever_live_p (regno))
+ /* Not all extension registers are available, choose the
+ real ones. */
+ && !fixed_regs[regno])
+ return true;
+ return false;
+
+ case 61:
+ case 62:
+ case 63:
+ /* Fixed/control register, nothing to do. LP_COUNT is
+ different. */
return false;
case HARD_FRAME_POINTER_REGNUM:
@@ -2665,18 +2730,21 @@ arc_must_save_register (int regno, struct function *func)
regular reg. */
if (arc_frame_pointer_needed ())
return false;
+ break;
- /* FALLTHRU */
default:
- if (df_regs_ever_live_p (regno)
- && (!call_used_regs[regno]
- || ARC_INTERRUPT_P (fn_type))
- /* Do not emit code for auto saved regs. */
- && !irq_auto_save_p
- && !firq_auto_save_p)
- return true;
+ break;
}
+ if (((df_regs_ever_live_p (regno) && !call_used_regs[regno])
+ /* In an interrupt save everything. */
+ || (ARC_INTERRUPT_P (fn_type)
+ && (df_regs_ever_live_p (RETURN_ADDR_REGNUM)
+ || df_regs_ever_live_p (regno))))
+ /* Do not emit code for auto saved regs. */
+ && !irq_auto_save_p
+ && !firq_auto_save_p)
+ return true;
return false;
}
@@ -2700,14 +2768,14 @@ arc_must_save_return_addr (struct function *func)
of registers to be saved / restored with a millicode call. */
static int
-arc_compute_millicode_save_restore_regs (unsigned int gmask,
+arc_compute_millicode_save_restore_regs (uint64_t gmask,
struct arc_frame_info *frame)
{
int regno;
int start_reg = 13, end_reg = 25;
- for (regno = start_reg; regno <= end_reg && (gmask & (1L << regno));)
+ for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
regno++;
end_reg = regno - 1;
/* There is no point in using millicode thunks if we don't save/restore
@@ -2731,7 +2799,7 @@ arc_compute_frame_size (void)
int regno;
unsigned int total_size, var_size, args_size, pretend_size, extra_size;
unsigned int reg_size;
- unsigned int gmask;
+ uint64_t gmask;
struct arc_frame_info *frame_info;
int size;
unsigned int extra_plus_reg_size;
@@ -2759,12 +2827,13 @@ arc_compute_frame_size (void)
reg_size = 0;
gmask = 0;
- for (regno = 0; regno <= 31; regno++)
+ /* The last 4 regs are special, avoid them. */
+ for (regno = 0; regno <= (GMASK_LEN - 4); regno++)
{
- if (arc_must_save_register (regno, cfun))
+ if (arc_must_save_register (regno, cfun, false))
{
reg_size += UNITS_PER_WORD;
- gmask |= 1L << regno;
+ gmask |= 1ULL << regno;
}
}
@@ -2779,7 +2848,7 @@ arc_compute_frame_size (void)
for (regno = 0; EH_RETURN_DATA_REGNO (regno) != INVALID_REGNUM; regno++)
{
reg_size += UNITS_PER_WORD;
- gmask |= 1L << regno;
+ gmask |= 1ULL << regno;
}
/* Check if we need to save the return address. */
@@ -2789,12 +2858,25 @@ arc_compute_frame_size (void)
/* Saving blink reg for millicode thunk calls. */
if (TARGET_MILLICODE_THUNK_SET
- && !crtl->calls_eh_return)
+ && !crtl->calls_eh_return
+ && !ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
{
if (arc_compute_millicode_save_restore_regs (gmask, frame_info))
frame_info->save_return_addr = true;
}
+ /* Save lp_count, lp_start and lp_end. */
+ if (arc_lpcwidth != 0 && arc_must_save_register (LP_COUNT, cfun, true))
+ reg_size += UNITS_PER_WORD * 3;
+
+ /* Check for the special R40-R44 regs used by FPX extension. */
+ if (arc_must_save_register (TARGET_BIG_ENDIAN ? R41_REG : R40_REG,
+ cfun, TARGET_DPFP))
+ reg_size += UNITS_PER_WORD * 2;
+ if (arc_must_save_register (TARGET_BIG_ENDIAN ? R43_REG : R42_REG,
+ cfun, TARGET_DPFP))
+ reg_size += UNITS_PER_WORD * 2;
+
/* 4) Calculate extra size made up of the blink + fp size. */
extra_size = 0;
if (arc_must_save_return_addr (cfun))
@@ -2929,6 +3011,22 @@ frame_save_reg (rtx reg, HOST_WIDE_INT offset)
return GET_MODE_SIZE (GET_MODE (reg)) - offset;
}
+/* Helper used when saving AUX regs during ISR. */
+
+static int
+push_reg (rtx reg)
+{
+ rtx stkslot = gen_rtx_MEM (GET_MODE (reg), gen_rtx_PRE_DEC (Pmode,
+ stack_pointer_rtx));
+ rtx insn = emit_move_insn (stkslot, reg);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ add_reg_note (insn, REG_CFA_ADJUST_CFA,
+ gen_rtx_SET (stack_pointer_rtx,
+ plus_constant (Pmode, stack_pointer_rtx,
+ -GET_MODE_SIZE (GET_MODE (reg)))));
+ return GET_MODE_SIZE (GET_MODE (reg));
+}
+
/* Helper for epilogue: emit frame load with post_modify or post_inc
to restore register REG from stack. The initial offset is passed
via OFFSET. */
@@ -2967,12 +3065,29 @@ frame_restore_reg (rtx reg, HOST_WIDE_INT offset)
return GET_MODE_SIZE (GET_MODE (reg)) + offset;
}
+/* Helper used when restoring AUX regs during ISR. */
+
+static int
+pop_reg (rtx reg)
+{
+ rtx stkslot = gen_rtx_MEM (GET_MODE (reg), gen_rtx_POST_INC (Pmode,
+ stack_pointer_rtx));
+ rtx insn = emit_move_insn (reg, stkslot);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ add_reg_note (insn, REG_CFA_ADJUST_CFA,
+ gen_rtx_SET (stack_pointer_rtx,
+ plus_constant (Pmode, stack_pointer_rtx,
+ GET_MODE_SIZE (GET_MODE (reg)))));
+ return GET_MODE_SIZE (GET_MODE (reg));
+}
+
+
/* Check if we have a continous range to be save/restored with the
help of enter/leave instructions. A vaild register range starts
from $r13 and is up to (including) $r26. */
static bool
-arc_enter_leave_p (unsigned int gmask)
+arc_enter_leave_p (uint64_t gmask)
{
int regno;
unsigned int rmask = 0;
@@ -2981,8 +3096,8 @@ arc_enter_leave_p (unsigned int gmask)
return false;
for (regno = ENTER_LEAVE_START_REG;
- regno <= ENTER_LEAVE_END_REG && (gmask & (1L << regno)); regno++)
- rmask |= 1L << regno;
+ regno <= ENTER_LEAVE_END_REG && (gmask & (1ULL << regno)); regno++)
+ rmask |= 1ULL << regno;
if (rmask ^ gmask)
return false;
@@ -2995,13 +3110,14 @@ arc_enter_leave_p (unsigned int gmask)
instructions. */
static int
-arc_save_callee_saves (unsigned int gmask,
+arc_save_callee_saves (uint64_t gmask,
bool save_blink,
bool save_fp,
HOST_WIDE_INT offset)
{
rtx reg;
int frame_allocated = 0;
+ int i;
/* The home-grown ABI says link register is saved first. */
if (save_blink)
@@ -3013,19 +3129,19 @@ arc_save_callee_saves (unsigned int gmask,
/* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
if (gmask)
- for (int i = 31; i >= 0; i--)
+ for (i = GMASK_LEN; i >= 0; i--)
{
machine_mode save_mode = SImode;
if (TARGET_LL64
&& ((i - 1) % 2 == 0)
- && ((gmask & (1L << i)) != 0)
- && ((gmask & (1L << (i - 1))) != 0))
+ && ((gmask & (1ULL << i)) != 0)
+ && ((gmask & (1ULL << (i - 1))) != 0))
{
save_mode = DImode;
--i;
}
- else if ((gmask & (1L << i)) == 0)
+ else if ((gmask & (1ULL << i)) == 0)
continue;
reg = gen_rtx_REG (save_mode, i);
@@ -3033,6 +3149,41 @@ arc_save_callee_saves (unsigned int gmask,
offset = 0;
}
+ /* Check if we need to save the ZOL machinery. */
+ if (arc_lpcwidth != 0 && arc_must_save_register (LP_COUNT, cfun, true))
+ {
+ rtx reg0 = gen_rtx_REG (SImode, R0_REG);
+ emit_insn (gen_rtx_SET (reg0,
+ gen_rtx_UNSPEC_VOLATILE
+ (Pmode, gen_rtvec (1, GEN_INT (AUX_LP_START)),
+ VUNSPEC_ARC_LR)));
+ frame_allocated += push_reg (reg0);
+ emit_insn (gen_rtx_SET (reg0,
+ gen_rtx_UNSPEC_VOLATILE
+ (Pmode, gen_rtvec (1, GEN_INT (AUX_LP_END)),
+ VUNSPEC_ARC_LR)));
+ frame_allocated += push_reg (reg0);
+ emit_move_insn (reg0, gen_rtx_REG (SImode, LP_COUNT));
+ frame_allocated += push_reg (reg0);
+ }
+
+ /* Save AUX regs used by FPX machinery. */
+ if (arc_must_save_register (TARGET_BIG_ENDIAN ? R41_REG : R40_REG,
+ cfun, TARGET_DPFP))
+ {
+ rtx reg0 = gen_rtx_REG (SImode, R0_REG);
+
+ for (i = 0; i < 4; i++)
+ {
+ emit_insn (gen_rtx_SET (reg0,
+ gen_rtx_UNSPEC_VOLATILE
+ (Pmode, gen_rtvec (1, GEN_INT (AUX_DPFP_START
+ + i)),
+ VUNSPEC_ARC_LR)));
+ frame_allocated += push_reg (reg0);
+ }
+ }
+
/* Save frame pointer if needed. First save the FP on stack, if not
autosaved. Unfortunately, I cannot add it to gmask and use the
above loop to save fp because our ABI states fp goes aftert all
@@ -3054,7 +3205,7 @@ arc_save_callee_saves (unsigned int gmask,
if it is for an interrupt handler) using LD/LDD instructions. */
static int
-arc_restore_callee_saves (unsigned int gmask,
+arc_restore_callee_saves (uint64_t gmask,
bool restore_blink,
bool restore_fp,
HOST_WIDE_INT offset,
@@ -3064,6 +3215,7 @@ arc_restore_callee_saves (unsigned int gmask,
int frame_deallocated = 0;
HOST_WIDE_INT offs = cfun->machine->frame_info.reg_size;
bool early_blink_restore;
+ int i;
/* Emit mov fp,sp. */
if (arc_frame_pointer_needed () && offset)
@@ -3080,6 +3232,43 @@ arc_restore_callee_saves (unsigned int gmask,
frame_deallocated += frame_restore_reg (hard_frame_pointer_rtx, 0);
}
+ /* Restore AUX-regs used by FPX machinery. */
+ if (arc_must_save_register (TARGET_BIG_ENDIAN ? R41_REG : R40_REG,
+ cfun, TARGET_DPFP))
+ {
+ rtx reg0 = gen_rtx_REG (SImode, R0_REG);
+
+ gcc_assert (offset == 0);
+ for (i = 0; i < 4; i++)
+ {
+ frame_deallocated += pop_reg (reg0);
+ emit_insn (gen_rtx_UNSPEC_VOLATILE
+ (VOIDmode, gen_rtvec (2, reg0, GEN_INT (AUX_DPFP_START
+ + i)),
+ VUNSPEC_ARC_SR));
+ }
+ }
+
+ /* Check if we need to restore the ZOL machinery. */
+ if (arc_lpcwidth !=0 && arc_must_save_register (LP_COUNT, cfun, true))
+ {
+ rtx reg0 = gen_rtx_REG (SImode, R0_REG);
+
+ gcc_assert (offset == 0);
+ frame_deallocated += pop_reg (reg0);
+ emit_move_insn (gen_rtx_REG (SImode, LP_COUNT), reg0);
+
+ frame_deallocated += pop_reg (reg0);
+ emit_insn (gen_rtx_UNSPEC_VOLATILE
+ (VOIDmode, gen_rtvec (2, reg0, GEN_INT (AUX_LP_END)),
+ VUNSPEC_ARC_SR));
+
+ frame_deallocated += pop_reg (reg0);
+ emit_insn (gen_rtx_UNSPEC_VOLATILE
+ (VOIDmode, gen_rtvec (2, reg0, GEN_INT (AUX_LP_START)),
+ VUNSPEC_ARC_SR));
+ }
+
if (offset)
{
/* No $fp involved, we need to do an add to set the $sp to the
@@ -3090,7 +3279,8 @@ arc_restore_callee_saves (unsigned int gmask,
}
/* When we do not optimize for size, restore first blink. */
- early_blink_restore = restore_blink && !optimize_size && offs;
+ early_blink_restore = restore_blink && !optimize_size && offs
+ && !ARC_INTERRUPT_P (arc_compute_function_type (cfun));
if (early_blink_restore)
{
rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs);
@@ -3103,16 +3293,16 @@ arc_restore_callee_saves (unsigned int gmask,
/* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
if (gmask)
- for (int i = 0; i <= GMASK_LEN; i++)
+ for (i = 0; i <= GMASK_LEN; i++)
{
machine_mode restore_mode = SImode;
if (TARGET_LL64
&& ((i % 2) == 0)
- && ((gmask & (1L << i)) != 0)
- && ((gmask & (1L << (i + 1))) != 0))
+ && ((gmask & (1ULL << i)) != 0)
+ && ((gmask & (1ULL << (i + 1))) != 0))
restore_mode = DImode;
- else if ((gmask & (1L << i)) == 0)
+ else if ((gmask & (1ULL << i)) == 0)
continue;
reg = gen_rtx_REG (restore_mode, i);
@@ -3120,12 +3310,12 @@ arc_restore_callee_saves (unsigned int gmask,
switch (restore_mode)
{
case E_DImode:
- if ((GMASK_LEN - __builtin_clz (gmask)) == (i + 1)
+ if ((GMASK_LEN - __builtin_clzll (gmask)) == (i + 1)
&& early_blink_restore)
offs = 4;
break;
case E_SImode:
- if ((GMASK_LEN - __builtin_clz (gmask)) == i
+ if ((GMASK_LEN - __builtin_clzll (gmask)) == i
&& early_blink_restore)
offs = 4;
break;
@@ -3158,7 +3348,7 @@ arc_restore_callee_saves (unsigned int gmask,
register. */
static int
-arc_save_callee_enter (unsigned int gmask,
+arc_save_callee_enter (uint64_t gmask,
bool save_blink,
bool save_fp,
HOST_WIDE_INT offset)
@@ -3169,7 +3359,7 @@ arc_save_callee_enter (unsigned int gmask,
rtx insn, reg, mem;
int frame_allocated = 0;
- for (regno = start_reg; regno <= end_reg && (gmask & (1L << regno));)
+ for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
regno++;
end_reg = regno - 1;
@@ -3214,7 +3404,7 @@ arc_save_callee_enter (unsigned int gmask,
off));
XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, reg);
RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
- gmask = gmask & ~(1L << regno);
+ gmask = gmask & ~(1ULL << regno);
}
if (save_fp)
@@ -3249,7 +3439,7 @@ arc_save_callee_enter (unsigned int gmask,
(RESTORE_FP), and can automatic return (RETURN_P). */
static int
-arc_restore_callee_leave (unsigned int gmask,
+arc_restore_callee_leave (uint64_t gmask,
bool restore_blink,
bool restore_fp,
bool return_p,
@@ -3261,7 +3451,7 @@ arc_restore_callee_leave (unsigned int gmask,
rtx insn, reg, mem;
int frame_allocated = 0;
- for (regno = start_reg; regno <= end_reg && (gmask & (1L << regno));)
+ for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
regno++;
end_reg = regno - 1;
@@ -3322,7 +3512,7 @@ arc_restore_callee_leave (unsigned int gmask,
off));
XVECEXP (insn, 0, indx) = gen_rtx_SET (reg, mem);
RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
- gmask = gmask & ~(1L << regno);
+ gmask = gmask & ~(1ULL << regno);
}
if (restore_fp)
@@ -3385,7 +3575,7 @@ arc_restore_callee_leave (unsigned int gmask,
*/
static int
-arc_save_callee_milli (unsigned int gmask,
+arc_save_callee_milli (uint64_t gmask,
bool save_blink,
bool save_fp,
HOST_WIDE_INT offset,
@@ -3397,7 +3587,7 @@ arc_save_callee_milli (unsigned int gmask,
rtx insn, reg, mem;
int frame_allocated = 0;
- for (regno = start_reg; regno <= end_reg && (gmask & (1L << regno));)
+ for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
regno++;
end_reg = regno - 1;
@@ -3440,7 +3630,7 @@ arc_save_callee_milli (unsigned int gmask,
off));
XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, reg);
RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
- gmask = gmask & ~(1L << regno);
+ gmask = gmask & ~(1ULL << regno);
}
insn = frame_insn (insn);
@@ -3468,9 +3658,9 @@ arc_save_callee_milli (unsigned int gmask,
}
/* Save remaining registers using st instructions. */
- for (regno = 0; regno <= 31; regno++)
+ for (regno = 0; regno <= GMASK_LEN; regno++)
{
- if ((gmask & (1L << regno)) == 0)
+ if ((gmask & (1ULL << regno)) == 0)
continue;
reg = gen_rtx_REG (SImode, regno);
@@ -3499,7 +3689,7 @@ arc_save_callee_milli (unsigned int gmask,
/* Like the previous function but restore. */
static int
-arc_restore_callee_milli (unsigned int gmask,
+arc_restore_callee_milli (uint64_t gmask,
bool restore_blink,
bool restore_fp,
bool return_p,
@@ -3511,7 +3701,7 @@ arc_restore_callee_milli (unsigned int gmask,
rtx insn, reg, mem;
int frame_allocated = 0;
- for (regno = start_reg; regno <= end_reg && (gmask & (1L << regno));)
+ for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
regno++;
end_reg = regno - 1;
@@ -3571,13 +3761,13 @@ arc_restore_callee_milli (unsigned int gmask,
off));
XVECEXP (insn, 0, indx) = gen_rtx_SET (reg, mem);
RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
- gmask = gmask & ~(1L << regno);
+ gmask = gmask & ~(1ULL << regno);
}
/* Restore remaining registers using LD instructions. */
- for (regno = 0; regno <= 31; regno++)
+ for (regno = 0; regno <= GMASK_LEN; regno++)
{
- if ((gmask & (1L << regno)) == 0)
+ if ((gmask & (1ULL << regno)) == 0)
continue;
reg = gen_rtx_REG (SImode, regno);
@@ -3627,7 +3817,7 @@ void
arc_expand_prologue (void)
{
int size;
- unsigned int gmask = cfun->machine->frame_info.gmask;
+ uint64_t gmask = cfun->machine->frame_info.gmask;
struct arc_frame_info *frame = &cfun->machine->frame_info;
unsigned int frame_size_to_allocate;
int first_offset = 0;
@@ -3700,6 +3890,30 @@ arc_expand_prologue (void)
emit_insn (gen_blockage ());
}
+/* Return the register number of the register holding the return address
+ for a function of type TYPE. */
+
+static int
+arc_return_address_register (unsigned int fn_type)
+{
+ int regno = 0;
+
+ if (ARC_INTERRUPT_P (fn_type))
+ {
+ if ((fn_type & (ARC_FUNCTION_ILINK1 | ARC_FUNCTION_FIRQ)) != 0)
+ regno = ILINK1_REG;
+ else if ((fn_type & ARC_FUNCTION_ILINK2) != 0)
+ regno = ILINK2_REG;
+ else
+ gcc_unreachable ();
+ }
+ else if (ARC_NORMAL_P (fn_type) || ARC_NAKED_P (fn_type))
+ regno = RETURN_ADDR_REGNUM;
+
+ gcc_assert (regno != 0);
+ return regno;
+}
+
/* Do any necessary cleanup after a function to restore stack, frame,
and regs. */
@@ -3715,12 +3929,11 @@ arc_expand_epilogue (int sibcall_p)
bool restore_fp = arc_frame_pointer_needed () && !ARC_AUTOFP_IRQ_P (fn_type);
bool restore_blink = arc_must_save_return_addr (cfun)
&& !ARC_AUTOBLINK_IRQ_P (fn_type);
- unsigned int gmask = cfun->machine->frame_info.gmask;
+ uint64_t gmask = cfun->machine->frame_info.gmask;
bool return_p = !sibcall_p && fn_type == ARC_FUNCTION_NORMAL
&& !cfun->machine->frame_info.pretend_size;
struct arc_frame_info *frame = &cfun->machine->frame_info;
-
/* Naked functions don't have epilogue. */
if (ARC_NAKED_P (fn_type))
return;
@@ -3795,7 +4008,18 @@ arc_expand_epilogue (int sibcall_p)
EH_RETURN_STACKADJ_RTX));
/* Emit the return instruction. */
- if (sibcall_p == FALSE)
+ if (ARC_INTERRUPT_P (fn_type))
+ {
+ rtx ra = gen_rtx_REG (Pmode, arc_return_address_register (fn_type));
+
+ if (TARGET_V2)
+ emit_jump_insn (gen_rtie ());
+ else if (TARGET_ARC700)
+ emit_jump_insn (gen_rtie ());
+ else
+ emit_jump_insn (gen_arc600_rtie (ra));
+ }
+ else if (sibcall_p == FALSE)
emit_jump_insn (gen_simple_return ());
}
@@ -6772,7 +6996,7 @@ arc_expand_builtin (tree exp,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int id = DECL_FUNCTION_CODE (fndecl);
+ unsigned int id = DECL_MD_FUNCTION_CODE (fndecl);
const struct arc_builtin_description *d = &arc_bdesc[id];
int i, j, n_args = call_expr_nargs (exp);
rtx pat = NULL_RTX;
@@ -9702,12 +9926,6 @@ arc_check_millicode (rtx op, int offset, int load_p)
/* Accessor functions for cfun->machine->unalign. */
-int
-arc_get_unalign (void)
-{
- return cfun->machine->unalign;
-}
-
void
arc_clear_unalign (void)
{
@@ -10142,29 +10360,6 @@ arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee)
return true;
}
-/* Return the register number of the register holding the return address
- for a function of type TYPE. */
-
-int
-arc_return_address_register (unsigned int fn_type)
-{
- int regno = 0;
-
- if (ARC_INTERRUPT_P (fn_type))
- {
- if ((fn_type & (ARC_FUNCTION_ILINK1 | ARC_FUNCTION_FIRQ)) != 0)
- regno = ILINK1_REG;
- else if ((fn_type & ARC_FUNCTION_ILINK2) != 0)
- regno = ILINK2_REG;
- else
- gcc_unreachable ();
- }
- else if (ARC_NORMAL_P (fn_type) || ARC_NAKED_P (fn_type))
- regno = RETURN_ADDR_REGNUM;
-
- gcc_assert (regno != 0);
- return regno;
-}
/* Implement EPILOGUE_USES.
Return true if REGNO should be added to the deemed uses of the epilogue.
@@ -10177,25 +10372,25 @@ bool
arc_epilogue_uses (int regno)
{
unsigned int fn_type;
+ fn_type = arc_compute_function_type (cfun);
if (regno == arc_tp_regno)
return true;
- fn_type = arc_compute_function_type (cfun);
- if (reload_completed)
+ if (regno == RETURN_ADDR_REGNUM)
+ return true;
+
+ if (regno == arc_return_address_register (fn_type))
+ return true;
+
+ if (epilogue_completed && ARC_INTERRUPT_P (fn_type))
{
- if (ARC_INTERRUPT_P (cfun->machine->fn_type))
- {
- if (!fixed_regs[regno])
- return true;
- return ((regno == arc_return_address_register (fn_type))
- || (regno == RETURN_ADDR_REGNUM));
- }
- else
- return regno == RETURN_ADDR_REGNUM;
+ /* An interrupt function restores more registers. */
+ if (df_regs_ever_live_p (regno) || call_used_regs[regno])
+ return true;
}
- else
- return regno == arc_return_address_register (fn_type);
+
+ return false;
}
/* Helper for EH_USES macro. */
@@ -11491,6 +11686,16 @@ arc_check_mov_const (HOST_WIDE_INT ival)
return false;
}
+/* Return nonzero if this function is known to have a null epilogue.
+ This allows the optimizer to omit jumps to jumps if no stack
+ was created. */
+
+bool
+arc_can_use_return_insn (void)
+{
+ return (reload_completed && cfun->machine->frame_info.total_size == 0
+ && !ARC_INTERRUPT_P (arc_compute_function_type (cfun)));
+}
#undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
#define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index b793e5b..7cd4733 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -163,6 +163,7 @@
VUNSPEC_ARC_LL
VUNSPEC_ARC_BLOCKAGE
VUNSPEC_ARC_EH_RETURN
+ VUNSPEC_ARC_ARC600_RTIE
])
(define_constants
@@ -187,17 +188,37 @@
(R30_REG 30)
(RETURN_ADDR_REGNUM 31)
(R32_REG 32)
+ (R33_REG 33)
+ (R34_REG 34)
+ (R35_REG 35)
+ (R36_REG 36)
+ (R37_REG 37)
+ (R38_REG 38)
+ (R39_REG 39)
(R40_REG 40)
(R41_REG 41)
(R42_REG 42)
(R43_REG 43)
(R44_REG 44)
+ (R45_REG 45)
+ (R46_REG 46)
+ (R47_REG 47)
+ (R48_REG 48)
+ (R49_REG 49)
+ (R50_REG 50)
+ (R51_REG 51)
+ (R52_REG 52)
+ (R53_REG 53)
+ (R54_REG 54)
+ (R55_REG 55)
+ (R56_REG 56)
(R57_REG 57)
+ (R58_REG 58)
+ (R59_REG 59)
+
(MUL64_OUT_REG 58)
(MUL32x16_REG 56)
(ARCV2_ACC 58)
- (R59_REG 59)
-
(LP_COUNT 60)
(CC_REG 61)
(PCL_REG 63)
@@ -214,7 +235,7 @@
(define_attr "type"
"move,load,store,cmove,unary,binary,compare,shift,uncond_branch,jump,branch,
- brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot,
+ brcc,brcc_no_delay_slot,call,sfunc,call_no_delay_slot,rtie,
multi,umulti, two_cycle_core,lr,sr,divaw,loop_setup,loop_end,return,
misc,spfp,dpfp_mult,dpfp_addsub,mulmac_600,cc_arith,
simd_vload, simd_vload128, simd_vstore, simd_vmove, simd_vmove_else_zero,
@@ -531,9 +552,7 @@
(cond [(eq_attr "in_delay_slot" "false")
(const_string "no")
(match_test "regno_clobbered_p
- (arc_return_address_register
- (arc_compute_function_type (cfun)),
- insn, SImode, 1)")
+ (RETURN_ADDR_REGNUM, insn, SImode, 1)")
(const_string "no")]
(const_string "yes")))
@@ -757,9 +776,9 @@ core_3, archs4x, archs4xd, archs4xd_slow"
; execution must reflect this, lest out-of-range branches are created.
; the iscompact attribute allows the epilogue expander to know for which
; insns it should lengthen the return insn.
-(define_insn_and_split "*movsi_insn" ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
- [(set (match_operand:SI 0 "move_dest_operand" "=q, q,r,q, h,rl, r, r, r, r, ?r, r, q, h, rl, q, S, Us<,RcqRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m, m,VUsc")
- (match_operand:SI 1 "move_src_operand" "rL,rP,q,P,hCm1,rL, I,Clo,Chi,Cbi,Cpc,Clb,Cax,Cal,Cal,Uts,Rcq,RcqRck, Us>,Usd,Ucm, Usd, Ucd,m, r,!*Rzd,r,Cm3, C32"))]
+(define_insn_and_split "*movsi_insn" ; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
+ [(set (match_operand:SI 0 "move_dest_operand" "=q, q,r,q, h, rl,r, r, r, r, ?r, r, q, h, rl, q, S, Us<,RcqRck,!*x, r,!*Rsd,!*Rcd,r,Ucm, Usd,m, m,VUsc")
+ (match_operand:SI 1 "move_src_operand" "rL,rP,q,P,hCm1,rLl,I,Clo,Chi,Cbi,Cpc,Clb,Cax,Cal,Cal,Uts,Rcq,RcqRck, Us>,Usd,Ucm, Usd, Ucd,m, r,!*Rzd,r,Cm3, C32"))]
"register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode)
|| (CONSTANT_P (operands[1])
@@ -775,8 +794,8 @@ core_3, archs4x, archs4xd, archs4xd_slow"
mov%?\\t%0,%1 ;4
mov%?\\t%0,%1 ;5
mov%?\\t%0,%1 ;6
- movl.cl\\t %0,%1 ;7
- movh.cl\\t %0,%L1>>16 ;8
+ movl.cl\\t%0,%1 ;7
+ movh.cl\\t%0,%L1>>16 ;8
* return INTVAL (operands[1]) & 0xffffff ? \"movbi.cl\\t%0,%1 >> %p1,%p1,8;9\" : \"movbi.cl\\t%0,%L1 >> 24,24,8;9\";
add\\t%0,%1 ;10
add\\t%0,pcl,%1@pcl ;11
@@ -784,7 +803,7 @@ core_3, archs4x, archs4xd, archs4xd_slow"
mov%?\\t%0,%j1 ;13
mov%?\\t%0,%j1 ;14
ld%?\\t%0,%1 ;15
- st%?\\t %1,%0 ;16
+ st%?\\t%1,%0 ;16
* return arc_short_long (insn, \"push%?\\t%1%&\", \"st%U0\\t%1,%0%&\");
* return arc_short_long (insn, \"pop%?\\t%0%&\", \"ld%U1\\t%0,%1%&\");
ld%?\\t%0,%1 ;19
@@ -4560,13 +4579,13 @@ core_3, archs4x, archs4xd, archs4xd_slow"
(set_attr "type" "misc")])
(define_insn "rtie"
- [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
- VUNSPEC_ARC_RTIE)]
- ""
+ [(return)
+ (unspec_volatile [(const_int 0)] VUNSPEC_ARC_RTIE)]
+ "!TARGET_ARC600_FAMILY"
"rtie"
[(set_attr "length" "4")
- (set_attr "type" "misc")
- (set_attr "cond" "clob")])
+ (set_attr "type" "rtie")
+ (set_attr "cond" "clob")])
(define_insn "sync"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand" "N")]
@@ -4788,88 +4807,52 @@ core_3, archs4x, archs4xd, archs4xd_slow"
; forbid instructions that change blink in the return / sibcall delay slot.
(define_insn "simple_return"
[(simple_return)]
- "reload_completed"
-{
- rtx reg
- = gen_rtx_REG (Pmode,
- arc_return_address_register (arc_compute_function_type
- (cfun)));
+ ""
+ "j%!%*\\t[blink]"
+ [(set_attr "type" "return")
+ (set_attr "cond" "canuse")
+ (set_attr "iscompact" "maybe")
+ (set_attr "length" "*")])
- if (TARGET_V2
- && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
- {
- return \"rtie\";
- }
- output_asm_insn (\"j%!%* [%0]%&\", &reg);
- return \"\";
-}
- [(set (attr "type")
- (cond [(and (match_test "ARC_INTERRUPT_P (arc_compute_function_type (cfun))")
- (match_test "TARGET_V2"))
- (const_string "brcc_no_delay_slot")]
- (const_string "return")))
- ; predicable won't help here since the canonical rtl looks different
- ; for branches.
- (set (attr "cond")
- (cond [(and (eq (symbol_ref "arc_compute_function_type (cfun)")
- (symbol_ref "ARC_FUNCTION_ILINK1"))
- (match_test "TARGET_V2"))
- (const_string "nocond")]
- (const_string "canuse")))
- (set (attr "iscompact")
- (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
- (symbol_ref "ARC_FUNCTION_NORMAL"))
- (const_string "maybe")]
- (const_string "false")))
- (set (attr "length")
- (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
- (symbol_ref "ARC_FUNCTION_NORMAL"))
- (const_int 4)]
- (const_int 2)))])
+(define_insn "arc600_rtie"
+ [(return)
+ (unspec_volatile [(match_operand 0 "pmode_register_operand" "")]
+ VUNSPEC_ARC_ARC600_RTIE)]
+ "TARGET_ARC600_FAMILY"
+ "j.f\\t[%0]"
+ [(set_attr "length" "4")
+ (set_attr "type" "rtie")
+ (set_attr "cond" "clob")])
(define_insn "p_return_i"
[(set (pc)
(if_then_else (match_operator 0 "proper_comparison_operator"
[(reg CC_REG) (const_int 0)])
(simple_return) (pc)))]
- "reload_completed
- && !(TARGET_V2
- && ARC_INTERRUPT_P (arc_compute_function_type (cfun)))"
+ "reload_completed"
{
- rtx xop[2];
- xop[0] = operands[0];
- xop[1]
- = gen_rtx_REG (Pmode,
- arc_return_address_register (arc_compute_function_type
- (cfun)));
-
- output_asm_insn (\"j%d0%!%# [%1]%&\", xop);
+ output_asm_insn (\"j%d0%!%#\\t[blink]\", operands);
/* record the condition in case there is a delay insn. */
- arc_ccfsm_record_condition (xop[0], false, insn, 0);
+ arc_ccfsm_record_condition (operands[0], false, insn, 0);
return \"\";
}
[(set_attr "type" "return")
(set_attr "cond" "use")
- (set (attr "iscompact")
- (cond [(eq (symbol_ref "arc_compute_function_type (cfun)")
- (symbol_ref "ARC_FUNCTION_NORMAL"))
- (const_string "maybe")]
- (const_string "false")))
+ (set_attr "iscompact" "maybe" )
(set (attr "length")
- (cond [(ne (symbol_ref "arc_compute_function_type (cfun)")
- (symbol_ref "ARC_FUNCTION_NORMAL"))
- (const_int 4)
- (not (match_operand 0 "equality_comparison_operator" ""))
+ (cond [(not (match_operand 0 "equality_comparison_operator" ""))
(const_int 4)
(eq_attr "delay_slot_filled" "yes")
(const_int 4)]
(const_int 2)))])
-;; ??? #ifdefs in function.c require the presence of this pattern, with a
-;; non-constant predicate.
+;; Return nonzero if this function is known to have a null epilogue.
+;; This allows the optimizer to omit jumps to jumps if no stack
+;; was created.
(define_expand "return"
[(return)]
- "optimize < 0")
+ "arc_can_use_return_insn ()"
+ "")
;; Comment in final.c (insn_current_reference_address) says
;; forward branch addresses are calculated from the next insn after branch
diff --git a/gcc/config/arc/builtins.def b/gcc/config/arc/builtins.def
index 2ab43f6..f1c59d5 100644
--- a/gcc/config/arc/builtins.def
+++ b/gcc/config/arc/builtins.def
@@ -33,7 +33,7 @@
/* Special builtins. */
DEF_BUILTIN (NOP, 0, void_ftype_void, nothing, 1)
-DEF_BUILTIN (RTIE, 0, void_ftype_void, rtie, 1)
+DEF_BUILTIN (RTIE, 0, void_ftype_void, rtie, !TARGET_ARC600_FAMILY)
DEF_BUILTIN (SYNC, 0, void_ftype_void, sync, 1)
DEF_BUILTIN (BRK, 0, void_ftype_void, brk, 1)
DEF_BUILTIN (SWI, 0, void_ftype_void, swi, 1)
diff --git a/gcc/config/arc/predicates.md b/gcc/config/arc/predicates.md
index 72fbf2a..e0013b3 100644
--- a/gcc/config/arc/predicates.md
+++ b/gcc/config/arc/predicates.md
@@ -285,6 +285,8 @@
return GET_MODE (op) == SFmode;
return 0;
case REG :
+ if (REGNO (op) == LP_COUNT)
+ return 1;
return register_operand (op, mode);
case SUBREG :
/* (subreg (mem ...) ...) can occur here if the inner part was once a
diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index 8f2c937..c5cdb7b 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -376,7 +376,7 @@ static arm_builtin_datum neon_builtin_data[] =
#undef CF
#undef VAR1
#define VAR1(T, N, A) \
- {#N, UP (A), CODE_FOR_##N, 0, T##_QUALIFIERS},
+ {#N, UP (A), CODE_FOR_arm_##N, 0, T##_QUALIFIERS},
static arm_builtin_datum acle_builtin_data[] =
{
@@ -2555,7 +2555,7 @@ arm_expand_builtin (tree exp,
rtx op1;
rtx op2;
rtx pat;
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
size_t i;
machine_mode tmode;
machine_mode mode0;
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index dcb5737..50e1b90 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -930,35 +930,49 @@
(define_insn "*addsi3_compare_op1"
[(set (reg:CC_C CC_REGNUM)
(compare:CC_C
- (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
- (match_operand:SI 2 "arm_add_operand" "I,L,r"))
+ (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,r,r,r")
+ (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,I,L,r"))
(match_dup 1)))
- (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
+ (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,r,r,r")
(plus:SI (match_dup 1) (match_dup 2)))]
"TARGET_32BIT"
"@
adds%?\\t%0, %1, %2
+ adds%?\\t%0, %0, %2
+ subs%?\\t%0, %1, #%n2
+ subs%?\\t%0, %0, #%n2
+ adds%?\\t%0, %1, %2
subs%?\\t%0, %1, #%n2
adds%?\\t%0, %1, %2"
[(set_attr "conds" "set")
- (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
+ (set_attr "arch" "t2,t2,t2,t2,*,*,*")
+ (set_attr "length" "2,2,2,2,4,4,4")
+ (set_attr "type"
+ "alus_sreg,alus_imm,alus_sreg,alus_imm,alus_imm,alus_imm,alus_sreg")]
)
(define_insn "*addsi3_compare_op2"
[(set (reg:CC_C CC_REGNUM)
(compare:CC_C
- (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
- (match_operand:SI 2 "arm_add_operand" "I,L,r"))
+ (plus:SI (match_operand:SI 1 "s_register_operand" "l,0,l,0,r,r,r")
+ (match_operand:SI 2 "arm_add_operand" "lPd,Py,lPx,Pw,I,L,r"))
(match_dup 2)))
- (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
+ (set (match_operand:SI 0 "s_register_operand" "=l,l,l,l,r,r,r")
(plus:SI (match_dup 1) (match_dup 2)))]
"TARGET_32BIT"
"@
adds%?\\t%0, %1, %2
+ adds%?\\t%0, %0, %2
+ subs%?\\t%0, %1, #%n2
+ subs%?\\t%0, %0, #%n2
+ adds%?\\t%0, %1, %2
subs%?\\t%0, %1, #%n2
adds%?\\t%0, %1, %2"
[(set_attr "conds" "set")
- (set_attr "type" "alus_imm,alus_imm,alus_sreg")]
+ (set_attr "arch" "t2,t2,t2,t2,*,*,*")
+ (set_attr "length" "2,2,2,2,4,4,4")
+ (set_attr "type"
+ "alus_sreg,alus_imm,alus_sreg,alus_imm,alus_imm,alus_imm,alus_sreg")]
)
(define_insn "*compare_addsi2_op0"
@@ -3981,16 +3995,16 @@
)
(define_code_iterator SAT [smin smax])
-(define_code_iterator SATrev [smin smax])
+(define_code_attr SATrev [(smin "smax") (smax "smin")])
(define_code_attr SATlo [(smin "1") (smax "2")])
(define_code_attr SAThi [(smin "2") (smax "1")])
(define_insn "*satsi_<SAT:code>"
[(set (match_operand:SI 0 "s_register_operand" "=r")
- (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r")
+ (SAT:SI (<SATrev>:SI (match_operand:SI 3 "s_register_operand" "r")
(match_operand:SI 1 "const_int_operand" "i"))
(match_operand:SI 2 "const_int_operand" "i")))]
- "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
+ "TARGET_32BIT && arm_arch6
&& arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
{
int mask;
@@ -4011,12 +4025,12 @@
(define_insn "*satsi_<SAT:code>_shift"
[(set (match_operand:SI 0 "s_register_operand" "=r")
- (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator"
+ (SAT:SI (<SATrev>:SI (match_operator:SI 3 "sat_shift_operator"
[(match_operand:SI 4 "s_register_operand" "r")
(match_operand:SI 5 "const_int_operand" "i")])
(match_operand:SI 1 "const_int_operand" "i"))
(match_operand:SI 2 "const_int_operand" "i")))]
- "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE>
+ "TARGET_32BIT && arm_arch6
&& arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)"
{
int mask;
@@ -12062,7 +12076,7 @@
(set_attr "predicable" "yes")])
;; ARMv8 CRC32 instructions.
-(define_insn "<crc_variant>"
+(define_insn "arm_<crc_variant>"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "s_register_operand" "r")
(match_operand:<crc_mode> 2 "s_register_operand" "r")]
@@ -12178,7 +12192,7 @@
DONE;
})
-(define_insn "<cdp>"
+(define_insn "arm_<cdp>"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
(match_operand:SI 1 "immediate_operand" "n")
(match_operand:SI 2 "immediate_operand" "n")
@@ -12224,19 +12238,19 @@
[(set_attr "length" "4")
(set_attr "type" "coproc")])
-(define_expand "<ldc>"
+(define_expand "arm_<ldc>"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand")
(match_operand:SI 1 "immediate_operand")
(mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)]
"arm_coproc_builtin_available (VUNSPEC_<LDC>)")
-(define_expand "<stc>"
+(define_expand "arm_<stc>"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand")
(match_operand:SI 1 "immediate_operand")
(mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)]
"arm_coproc_builtin_available (VUNSPEC_<STC>)")
-(define_insn "<mcr>"
+(define_insn "arm_<mcr>"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
(match_operand:SI 1 "immediate_operand" "n")
(match_operand:SI 2 "s_register_operand" "r")
@@ -12256,7 +12270,7 @@
[(set_attr "length" "4")
(set_attr "type" "coproc")])
-(define_insn "<mrc>"
+(define_insn "arm_<mrc>"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n")
(match_operand:SI 2 "immediate_operand" "n")
@@ -12275,7 +12289,7 @@
[(set_attr "length" "4")
(set_attr "type" "coproc")])
-(define_insn "<mcrr>"
+(define_insn "arm_<mcrr>"
[(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n")
(match_operand:SI 1 "immediate_operand" "n")
(match_operand:DI 2 "s_register_operand" "r")
@@ -12291,7 +12305,7 @@
[(set_attr "length" "4")
(set_attr "type" "coproc")])
-(define_insn "<mrrc>"
+(define_insn "arm_<mrrc>"
[(set (match_operand:DI 0 "s_register_operand" "=r")
(unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n")
(match_operand:SI 2 "immediate_operand" "n")
diff --git a/gcc/config/arm/arm_cmse.h b/gcc/config/arm/arm_cmse.h
index b543cbf..a72c46f 100644
--- a/gcc/config/arm/arm_cmse.h
+++ b/gcc/config/arm/arm_cmse.h
@@ -164,6 +164,7 @@ __CMSE_TT_ASM (at)
/* FIXME: diagnose use outside cmse_nonsecure_entry functions. */
__extension__ static __inline int __attribute__ ((__always_inline__))
+__attribute__ ((warn_unused_result))
cmse_nonsecure_caller (void)
{
return __builtin_arm_cmse_nonsecure_caller ();
@@ -184,6 +185,7 @@ cmse_nonsecure_caller (void)
#define CMSE_MPU_READ 8
__extension__ void *
+__attribute__ ((warn_unused_result))
cmse_check_address_range (void *, size_t, int);
#define cmse_check_pointed_object(p, f) \
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index b283a7b..608ea70 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -247,8 +247,8 @@
;; regs. The high register alternatives are not taken into account when
;; choosing register preferences in order to reflect their expense.
(define_insn "*thumb2_movsi_insn"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r,l ,*hk,m,*m")
- (match_operand:SI 1 "general_operand" "rk,I,Py,K,j,mi,*mi,l,*hk"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r,lk*r,m")
+ (match_operand:SI 1 "general_operand" "rk,I,Py,K,j,mi,lk*r"))]
"TARGET_THUMB2 && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
&& ( register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
@@ -262,22 +262,20 @@
case 3: return \"mvn%?\\t%0, #%B1\";
case 4: return \"movw%?\\t%0, %1\";
case 5:
- case 6:
/* Cannot load it directly, split to load it via MOV / MOVT. */
if (!MEM_P (operands[1]) && arm_disable_literal_pool)
return \"#\";
return \"ldr%?\\t%0, %1\";
- case 7:
- case 8: return \"str%?\\t%1, %0\";
+ case 6: return \"str%?\\t%1, %0\";
default: gcc_unreachable ();
}
}
- [(set_attr "type" "mov_reg,mov_imm,mov_imm,mvn_imm,mov_imm,load_4,load_4,store_4,store_4")
- (set_attr "length" "2,4,2,4,4,4,4,4,4")
+ [(set_attr "type" "mov_reg,mov_imm,mov_imm,mvn_imm,mov_imm,load_4,store_4")
+ (set_attr "length" "2,4,2,4,4,4,4")
(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no")
- (set_attr "pool_range" "*,*,*,*,*,1018,4094,*,*")
- (set_attr "neg_pool_range" "*,*,*,*,*,0,0,*,*")]
+ (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no")
+ (set_attr "pool_range" "*,*,*,*,*,1018,*")
+ (set_attr "neg_pool_range" "*,*,*,*,*,0,*")]
)
(define_insn "tls_load_dot_plus_four"
diff --git a/gcc/config/arm/types.md b/gcc/config/arm/types.md
index f8f8dd0..03d6b67 100644
--- a/gcc/config/arm/types.md
+++ b/gcc/config/arm/types.md
@@ -546,6 +546,10 @@
; The classification below is for coprocessor instructions
;
; coproc
+;
+; The classification below is for TME instructions
+;
+; tme
(define_attr "type"
"adc_imm,\
@@ -1091,7 +1095,8 @@
crypto_sha3,\
crypto_sm3,\
crypto_sm4,\
- coproc"
+ coproc,\
+ tme"
(const_string "untyped"))
; Is this an (integer side) multiply with a 32-bit (or smaller) result?
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index e0aaa7b..661919e 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -258,8 +258,8 @@
;; is chosen with length 2 when the instruction is predicated for
;; arm_restrict_it.
(define_insn "*thumb2_movsi_vfp"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r, l,*hk,m, *m,*t, r,*t,*t, *Uv")
- (match_operand:SI 1 "general_operand" "rk,I,Py,K,j,mi,*mi,l,*hk, r,*t,*t,*UvTu,*t"))]
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r,lk*r,m,*t, r,*t,*t, *Uv")
+ (match_operand:SI 1 "general_operand" "rk,I,Py,K,j,mi,lk*r, r,*t,*t,*UvTu,*t"))]
"TARGET_THUMB2 && TARGET_HARD_FLOAT
&& ( s_register_operand (operands[0], SImode)
|| s_register_operand (operands[1], SImode))"
@@ -275,32 +275,30 @@
case 4:
return \"movw%?\\t%0, %1\";
case 5:
- case 6:
/* Cannot load it directly, split to load it via MOV / MOVT. */
if (!MEM_P (operands[1]) && arm_disable_literal_pool)
return \"#\";
return \"ldr%?\\t%0, %1\";
- case 7:
- case 8:
+ case 6:
return \"str%?\\t%1, %0\";
- case 9:
+ case 7:
return \"vmov%?\\t%0, %1\\t%@ int\";
- case 10:
+ case 8:
return \"vmov%?\\t%0, %1\\t%@ int\";
- case 11:
+ case 9:
return \"vmov%?.f32\\t%0, %1\\t%@ int\";
- case 12: case 13:
+ case 10: case 11:
return output_move_vfp (operands);
default:
gcc_unreachable ();
}
"
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no,no,no,no,no,no")
- (set_attr "type" "mov_reg,mov_reg,mov_reg,mvn_reg,mov_imm,load_4,load_4,store_4,store_4,f_mcr,f_mrc,fmov,f_loads,f_stores")
- (set_attr "length" "2,4,2,4,4,4,4,4,4,4,4,4,4,4")
- (set_attr "pool_range" "*,*,*,*,*,1018,4094,*,*,*,*,*,1018,*")
- (set_attr "neg_pool_range" "*,*,*,*,*, 0, 0,*,*,*,*,*,1008,*")]
+ (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no,no,no,no")
+ (set_attr "type" "mov_reg,mov_reg,mov_reg,mvn_reg,mov_imm,load_4,store_4,f_mcr,f_mrc,fmov,f_loads,f_stores")
+ (set_attr "length" "2,4,2,4,4,4,4,4,4,4,4,4")
+ (set_attr "pool_range" "*,*,*,*,*,1018,*,*,*,*,1018,*")
+ (set_attr "neg_pool_range" "*,*,*,*,*, 0,*,*,*,*,1008,*")]
)
diff --git a/gcc/config/avr/avr-c.c b/gcc/config/avr/avr-c.c
index de02910..e0ba5bd 100644
--- a/gcc/config/avr/avr-c.c
+++ b/gcc/config/avr/avr-c.c
@@ -54,7 +54,7 @@ avr_resolve_overloaded_builtin (unsigned int iloc, tree fndecl, void *vargs)
location_t loc = (location_t) iloc;
vec<tree, va_gc> &args = * (vec<tree, va_gc>*) vargs;
- switch (DECL_FUNCTION_CODE (fndecl))
+ switch (DECL_MD_FUNCTION_CODE (fndecl))
{
default:
break;
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 760e937..ba49e3d 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -14243,7 +14243,7 @@ avr_expand_builtin (tree exp, rtx target,
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
const char *bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
- unsigned int id = DECL_FUNCTION_CODE (fndecl);
+ unsigned int id = DECL_MD_FUNCTION_CODE (fndecl);
const struct avr_builtin_description *d = &avr_bdesc[id];
tree arg0;
rtx op0;
@@ -14395,7 +14395,7 @@ static tree
avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
bool ignore ATTRIBUTE_UNUSED)
{
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
tree val_type = TREE_TYPE (TREE_TYPE (fndecl));
if (!optimize)
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index 319d7e2..d1a6832 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -5498,7 +5498,7 @@ bfin_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
enum insn_code icode;
const struct builtin_description *d;
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
tree arg0, arg1, arg2;
rtx op0, op1, op2, accvec, pat, tmp1, tmp2, a0reg, a1reg;
machine_mode tmode, mode0;
diff --git a/gcc/config/c6x/c6x.c b/gcc/config/c6x/c6x.c
index f6c9bbf..516a7c7 100644
--- a/gcc/config/c6x/c6x.c
+++ b/gcc/config/c6x/c6x.c
@@ -6661,7 +6661,7 @@ c6x_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
size_t i;
const struct builtin_description *d;
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
if (d->code == fcode)
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 5ac0925..e1017be 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -788,7 +788,7 @@ machopic_indirect_data_reference (rtx orig, rtx reg)
rtx
machopic_indirect_call_target (rtx target)
{
- if (! darwin_picsymbol_stubs)
+ if (! darwin_symbol_stubs)
return target;
if (GET_CODE (target) != MEM)
@@ -3268,13 +3268,13 @@ darwin_override_options (void)
Linkers that don't need stubs, don't need the EH symbol markers either.
*/
- if (!global_options_set.x_darwin_picsymbol_stubs)
+ if (!global_options_set.x_darwin_symbol_stubs)
{
if (darwin_target_linker)
{
if (strverscmp (darwin_target_linker, MIN_LD64_OMIT_STUBS) < 0)
{
- darwin_picsymbol_stubs = true;
+ darwin_symbol_stubs = true;
ld_needs_eh_markers = true;
}
}
@@ -3283,15 +3283,15 @@ darwin_override_options (void)
/* If we don't know the linker version and we're targeting an old
system, we know no better than to assume the use of an earlier
linker. */
- darwin_picsymbol_stubs = true;
+ darwin_symbol_stubs = true;
ld_needs_eh_markers = true;
}
}
- else if (DARWIN_X86 && darwin_picsymbol_stubs && TARGET_64BIT)
+ else if (DARWIN_X86 && darwin_symbol_stubs && TARGET_64BIT)
{
inform (input_location,
"%<-mpic-symbol-stubs%> is not required for 64b code (ignored)");
- darwin_picsymbol_stubs = false;
+ darwin_symbol_stubs = false;
}
if (generating_for_darwin_version >= 9)
@@ -3439,8 +3439,7 @@ darwin_init_cfstring_builtins (unsigned builtin_cfstring)
in place of the existing, which may be NULL. */
DECL_LANG_SPECIFIC (cfsfun) = NULL;
(*lang_hooks.dup_lang_specific_decl) (cfsfun);
- DECL_BUILT_IN_CLASS (cfsfun) = BUILT_IN_MD;
- DECL_FUNCTION_CODE (cfsfun) = darwin_builtin_cfstring;
+ set_decl_built_in_function (cfsfun, BUILT_IN_MD, darwin_builtin_cfstring);
lang_hooks.builtin_function (cfsfun);
/* extern int __CFConstantStringClassReference[]; */
@@ -3464,7 +3463,7 @@ tree
darwin_fold_builtin (tree fndecl, int n_args, tree *argp,
bool ARG_UNUSED (ignore))
{
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
if (fcode == darwin_builtin_cfstring)
{
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index ed87984..93dc638 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -125,7 +125,8 @@ extern GTY(()) int darwin_ms_struct;
However, a few can be handled and we can elide options that are silently-
ignored defaults, plus warn on obsolete ones that no longer function. */
-#define DRIVER_SELF_SPECS \
+#undef SUBTARGET_DRIVER_SELF_SPECS
+#define SUBTARGET_DRIVER_SELF_SPECS \
"%{fapple-kext|mkernel:-static}", \
"%{gfull:-g -fno-eliminate-unused-debug-symbols} %<gfull", \
"%{gsplit-dwarf:%ngsplit-dwarf is not supported on this platform} \
@@ -1018,7 +1019,7 @@ extern void darwin_driver_init (unsigned int *,struct cl_decoded_option **);
_tested_ version known to support this so far. */
#define MIN_LD64_NO_COAL_SECTS "236.4"
-/* From at least version 62.1, ld64 can build PIC indirection stubs as
+/* From at least version 62.1, ld64 can build symbol indirection stubs as
needed, and there is no need for the compiler to emit them. */
#define MIN_LD64_OMIT_STUBS "62.1"
diff --git a/gcc/config/darwin.opt b/gcc/config/darwin.opt
index d7e5e7b..7f5616c 100644
--- a/gcc/config/darwin.opt
+++ b/gcc/config/darwin.opt
@@ -75,9 +75,9 @@ mone-byte-bool
Target RejectNegative Report Var(darwin_one_byte_bool)
Set sizeof(bool) to 1.
-mpic-symbol-stubs
-Target Report Var(darwin_picsymbol_stubs) Init(0)
-Force generation of PIC symbol stubs.
+msymbol-stubs
+Target Report Var(darwin_symbol_stubs) Init(0)
+Force generation of external symbol indirection stubs.
; Some code-gen may be improved / adjusted if the linker is sufficiently modern.
mtarget-linker=
diff --git a/gcc/config/frv/frv.c b/gcc/config/frv/frv.c
index f0c9351..f8a3a075 100644
--- a/gcc/config/frv/frv.c
+++ b/gcc/config/frv/frv.c
@@ -9113,7 +9113,7 @@ frv_expand_builtin (tree exp,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned fcode = (unsigned)DECL_FUNCTION_CODE (fndecl);
+ unsigned fcode = DECL_MD_FUNCTION_CODE (fndecl);
unsigned i;
struct builtin_description *d;
diff --git a/gcc/config/gcn/gcn-valu.md b/gcc/config/gcn/gcn-valu.md
index c7e8b16..66b8229 100644
--- a/gcc/config/gcn/gcn-valu.md
+++ b/gcc/config/gcn/gcn-valu.md
@@ -863,15 +863,12 @@
if (AS_FLAT_P (as))
{
if (TARGET_GCN5_PLUS)
- sprintf (buf, "flat_store%%s2\t%%0, %%2 offset:%%1%s\;"
- "s_waitcnt\texpcnt(0)", glc);
+ sprintf (buf, "flat_store%%s2\t%%0, %%2 offset:%%1%s", glc);
else
- sprintf (buf, "flat_store%%s2\t%%0, %%2%s\;s_waitcnt\texpcnt(0)",
- glc);
+ sprintf (buf, "flat_store%%s2\t%%0, %%2%s", glc);
}
else if (AS_GLOBAL_P (as))
- sprintf (buf, "global_store%%s2\t%%0, %%2, off offset:%%1%s\;"
- "s_waitcnt\texpcnt(0)", glc);
+ sprintf (buf, "global_store%%s2\t%%0, %%2, off offset:%%1%s", glc);
else
gcc_unreachable ();
@@ -895,7 +892,7 @@
{
addr_space_t as = INTVAL (operands[3]);
static char buf[200];
- sprintf (buf, "ds_write%%b2\t%%0, %%2 offset:%%1%s\;s_waitcnt\texpcnt(0)",
+ sprintf (buf, "ds_write%%b2\t%%0, %%2 offset:%%1%s",
(AS_GDS_P (as) ? " gds" : ""));
return buf;
}
@@ -929,8 +926,8 @@
/* Work around assembler bug in which a 64-bit register is expected,
but a 32-bit value would be correct. */
int reg = REGNO (operands[1]) - FIRST_VGPR_REG;
- sprintf (buf, "global_store%%s3\tv[%d:%d], %%3, %%0 offset:%%2%s\;"
- "s_waitcnt\texpcnt(0)", reg, reg + 1, glc);
+ sprintf (buf, "global_store%%s3\tv[%d:%d], %%3, %%0 offset:%%2%s",
+ reg, reg + 1, glc);
}
else
gcc_unreachable ();
diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c
index e528b64..2c1158f 100644
--- a/gcc/config/gcn/gcn.c
+++ b/gcc/config/gcn/gcn.c
@@ -3546,7 +3546,7 @@ gcn_expand_builtin_1 (tree exp, rtx target, rtx /*subtarget */ ,
struct gcn_builtin_description *)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- switch (DECL_FUNCTION_CODE (fndecl))
+ switch (DECL_MD_FUNCTION_CODE (fndecl))
{
case GCN_BUILTIN_FLAT_LOAD_INT32:
{
@@ -3773,7 +3773,7 @@ gcn_expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode,
int ignore)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
struct gcn_builtin_description *d;
gcc_assert (fcode < GCN_BUILTIN_MAX);
@@ -4516,7 +4516,9 @@ gcn_md_reorg (void)
{
rtx_insn *insn;
attr_unit unit;
+ attr_delayeduse delayeduse;
HARD_REG_SET writes;
+ HARD_REG_SET reads;
int age;
} back[max_waits];
int oldest = 0;
@@ -4535,6 +4537,7 @@ gcn_md_reorg (void)
attr_type itype = get_attr_type (insn);
attr_unit iunit = get_attr_unit (insn);
+ attr_delayeduse idelayeduse = get_attr_delayeduse (insn);
HARD_REG_SET ireads, iwrites;
CLEAR_HARD_REG_SET (ireads);
CLEAR_HARD_REG_SET (iwrites);
@@ -4610,6 +4613,14 @@ gcn_md_reorg (void)
(regs, reg_class_contents[(int) VGPR_REGS]))
nops_rqd = 2 - prev_insn->age;
}
+
+ /* Store that requires input registers are not overwritten by
+ following instruction. */
+ if ((prev_insn->age + nops_rqd) < 1
+ && prev_insn->delayeduse == DELAYEDUSE_YES
+ && ((hard_reg_set_intersect_p
+ (prev_insn->reads, iwrites))))
+ nops_rqd = 1 - prev_insn->age;
}
/* Insert the required number of NOPs. */
@@ -4637,7 +4648,9 @@ gcn_md_reorg (void)
/* Track the current instruction as a previous instruction. */
back[oldest].insn = insn;
back[oldest].unit = iunit;
+ back[oldest].delayeduse = idelayeduse;
COPY_HARD_REG_SET (back[oldest].writes, iwrites);
+ COPY_HARD_REG_SET (back[oldest].reads, ireads);
back[oldest].age = 0;
oldest = (oldest + 1) % max_waits;
diff --git a/gcc/config/gcn/gcn.md b/gcc/config/gcn/gcn.md
index 7e5cf17..bbd2db2 100644
--- a/gcc/config/gcn/gcn.md
+++ b/gcc/config/gcn/gcn.md
@@ -285,6 +285,11 @@
(define_attr "laneselect" "yes,no" (const_string "no"))
+; Identify instructions that require a "Manually Inserted Wait State" if
+; their inputs are overwritten by subsequent instructions.
+
+(define_attr "delayeduse" "yes,no" (const_string "no"))
+
;; }}}
;; {{{ Iterators useful across the wole machine description
@@ -475,15 +480,15 @@
case 6:
return "s_load_dword\t%0, %A1\;s_waitcnt\tlgkmcnt(0)";
case 7:
- return "s_store_dword\t%1, %A0\;s_waitcnt\texpcnt(0)";
+ return "s_store_dword\t%1, %A0";
case 8:
return "flat_load_dword\t%0, %A1%O1%g1\;s_waitcnt\t0";
case 9:
- return "flat_store_dword\t%A0, %1%O0%g0\;s_waitcnt\texpcnt(0)";
+ return "flat_store_dword\t%A0, %1%O0%g0";
case 10:
return "global_load_dword\t%0, %A1%O1%g1\;s_waitcnt\tvmcnt(0)";
case 11:
- return "global_store_dword\t%A0, %1%O0%g0\;s_waitcnt\texpcnt(0)";
+ return "global_store_dword\t%A0, %1%O0%g0";
default:
gcc_unreachable ();
}
@@ -506,20 +511,20 @@
s_movk_i32\t%0, %1
s_mov_b32\t%0, %1
s_buffer_load%s0\t%0, s[0:3], %1\;s_waitcnt\tlgkmcnt(0)
- s_buffer_store%s1\t%1, s[0:3], %0\;s_waitcnt\texpcnt(0)
+ s_buffer_store%s1\t%1, s[0:3], %0
s_load_dword\t%0, %A1\;s_waitcnt\tlgkmcnt(0)
- s_store_dword\t%1, %A0\;s_waitcnt\texpcnt(0)
+ s_store_dword\t%1, %A0
v_mov_b32\t%0, %1
v_readlane_b32\t%0, %1, 0
v_writelane_b32\t%0, %1, 0
flat_load_dword\t%0, %A1%O1%g1\;s_waitcnt\t0
- flat_store_dword\t%A0, %1%O0%g0\;s_waitcnt\texpcnt(0)
+ flat_store_dword\t%A0, %1%O0%g0
v_mov_b32\t%0, %1
- ds_write_b32\t%A0, %1%O0\;s_waitcnt\texpcnt(0)
+ ds_write_b32\t%A0, %1%O0
ds_read_b32\t%0, %A1%O1\;s_waitcnt\tlgkmcnt(0)
s_mov_b32\t%0, %1
global_load_dword\t%0, %A1%O1%g1\;s_waitcnt\tvmcnt(0)
- global_store_dword\t%A0, %1%O0%g0\;s_waitcnt\texpcnt(0)"
+ global_store_dword\t%A0, %1%O0%g0"
[(set_attr "type" "sop1,sopk,sop1,smem,smem,smem,smem,vop1,vop3a,vop3a,flat,
flat,vop1,ds,ds,sop1,flat,flat")
(set_attr "exec" "*,*,*,*,*,*,*,*,none,none,*,*,*,*,*,*,*,*")
@@ -541,12 +546,12 @@
v_readlane_b32\t%0, %1, 0
v_writelane_b32\t%0, %1, 0
flat_load%o1\t%0, %A1%O1%g1\;s_waitcnt\t0
- flat_store%s0\t%A0, %1%O0%g0\;s_waitcnt\texpcnt(0)
+ flat_store%s0\t%A0, %1%O0%g0
v_mov_b32\t%0, %1
- ds_write%b0\t%A0, %1%O0\;s_waitcnt\texpcnt(0)
+ ds_write%b0\t%A0, %1%O0
ds_read%u1\t%0, %A1%O1\;s_waitcnt\tlgkmcnt(0)
global_load%o1\t%0, %A1%O1%g1\;s_waitcnt\tvmcnt(0)
- global_store%s0\t%A0, %1%O0%g0\;s_waitcnt\texpcnt(0)"
+ global_store%s0\t%A0, %1%O0%g0"
[(set_attr "type"
"sop1,sopk,sop1,vop1,vop3a,vop3a,flat,flat,vop1,ds,ds,flat,flat")
(set_attr "exec" "*,*,*,*,none,none,*,*,*,*,*,*,*")
@@ -564,18 +569,18 @@
s_mov_b64\t%0, %1
s_mov_b64\t%0, %1
#
- s_store_dwordx2\t%1, %A0\;s_waitcnt\texpcnt(0)
+ s_store_dwordx2\t%1, %A0
s_load_dwordx2\t%0, %A1\;s_waitcnt\tlgkmcnt(0)
#
#
#
#
flat_load_dwordx2\t%0, %A1%O1%g1\;s_waitcnt\t0
- flat_store_dwordx2\t%A0, %1%O0%g0\;s_waitcnt\texpcnt(0)
- ds_write_b64\t%A0, %1%O0\;s_waitcnt\texpcnt(0)
+ flat_store_dwordx2\t%A0, %1%O0%g0
+ ds_write_b64\t%A0, %1%O0
ds_read_b64\t%0, %A1%O1\;s_waitcnt\tlgkmcnt(0)
global_load_dwordx2\t%0, %A1%O1%g1\;s_waitcnt\tvmcnt(0)
- global_store_dwordx2\t%A0, %1%O0%g0\;s_waitcnt\texpcnt(0)"
+ global_store_dwordx2\t%A0, %1%O0%g0"
"(reload_completed && !MEM_P (operands[0]) && !MEM_P (operands[1])
&& !gcn_sgpr_move_p (operands[0], operands[1]))
|| (GET_CODE (operands[1]) == CONST_INT && !gcn_constant64_p (operands[1]))"
@@ -617,16 +622,16 @@
""
"@
#
- s_store_dwordx4\t%1, %A0\;s_waitcnt\texpcnt(0)
+ s_store_dwordx4\t%1, %A0
s_load_dwordx4\t%0, %A1\;s_waitcnt\tlgkmcnt(0)
- flat_store_dwordx4\t%A0, %1%O0%g0\;s_waitcnt\texpcnt(0)
+ flat_store_dwordx4\t%A0, %1%O0%g0
flat_load_dwordx4\t%0, %A1%O1%g1\;s_waitcnt\t0
#
#
#
- global_store_dwordx4\t%A0, %1%O0%g0\;s_waitcnt\texpcnt(0)
+ global_store_dwordx4\t%A0, %1%O0%g0
global_load_dwordx4\t%0, %A1%O1%g1\;s_waitcnt\tvmcnt(0)
- ds_write_b128\t%A0, %1%O0\;s_waitcnt\texpcnt(0)
+ ds_write_b128\t%A0, %1%O0
ds_read_b128\t%0, %A1%O1\;s_waitcnt\tlgkmcnt(0)"
"reload_completed
&& REG_P (operands[0])
@@ -647,6 +652,7 @@
}
[(set_attr "type" "mult,smem,smem,flat,flat,vmult,vmult,vmult,flat,flat,\
ds,ds")
+ (set_attr "delayeduse" "*,*,yes,*,*,*,*,*,*,*,*,*")
(set_attr "length" "*,12,12,12,12,*,*,*,12,12,12,12")])
;; }}}
@@ -1612,7 +1618,8 @@
global_atomic_cmpswap<X>\t%0, %A1, %2%O1 glc\;s_waitcnt\tvmcnt(0)"
[(set_attr "type" "smem,flat,flat")
(set_attr "length" "12")
- (set_attr "gcn_version" "gcn5,*,gcn5")])
+ (set_attr "gcn_version" "gcn5,*,gcn5")
+ (set_attr "delayeduse" "*,yes,*")])
(define_insn "sync_compare_and_swap<mode>_lds_insn"
[(set (match_operand:SIDI 0 "register_operand" "= v")
@@ -1715,14 +1722,11 @@
switch (which_alternative)
{
case 0:
- return "s_dcache_wb_vol\;s_store%o1\t%1, %A0 glc\;"
- "s_waitcnt\texpcnt(0)";
+ return "s_dcache_wb_vol\;s_store%o1\t%1, %A0 glc";
case 1:
- return "buffer_wbinvl1_vol\;flat_store%o1\t%A0, %1%O0 glc\;"
- "s_waitcnt\texpcnt(0)";
+ return "buffer_wbinvl1_vol\;flat_store%o1\t%A0, %1%O0 glc";
case 2:
- return "buffer_wbinvl1_vol\;global_store%o1\t%A0, %1%O0 glc\;"
- "s_waitcnt\texpcnt(0)";
+ return "buffer_wbinvl1_vol\;global_store%o1\t%A0, %1%O0 glc";
}
break;
case MEMMODEL_ACQ_REL:
@@ -1732,13 +1736,13 @@
{
case 0:
return "s_dcache_wb_vol\;s_store%o1\t%1, %A0 glc\;"
- "s_waitcnt\texpcnt(0)\;s_dcache_inv_vol";
+ "s_waitcnt\tlgkmcnt(0)\;s_dcache_inv_vol";
case 1:
return "buffer_wbinvl1_vol\;flat_store%o1\t%A0, %1%O0 glc\;"
- "s_waitcnt\texpcnt(0)\;buffer_wbinvl1_vol";
+ "s_waitcnt\t0\;buffer_wbinvl1_vol";
case 2:
return "buffer_wbinvl1_vol\;global_store%o1\t%A0, %1%O0 glc\;"
- "s_waitcnt\texpcnt(0)\;buffer_wbinvl1_vol";
+ "s_waitcnt\tvmcnt(0)\;buffer_wbinvl1_vol";
}
break;
}
diff --git a/gcc/config/gnu-user.h b/gcc/config/gnu-user.h
index 055a4f0..95a3c29 100644
--- a/gcc/config/gnu-user.h
+++ b/gcc/config/gnu-user.h
@@ -73,9 +73,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
GNU userspace "finalizer" file, `crtn.o'. */
#define GNU_USER_TARGET_ENDFILE_SPEC \
- "%{fvtable-verify=none:%s; \
+ "%{!static:%{fvtable-verify=none:%s; \
fvtable-verify=preinit:vtv_end_preinit.o%s; \
- fvtable-verify=std:vtv_end.o%s} \
+ fvtable-verify=std:vtv_end.o%s}} \
%{static:crtend.o%s; \
shared|static-pie|" PIE_SPEC ":crtendS.o%s; \
:crtend.o%s} " \
diff --git a/gcc/config/i386/avx512fintrin.h b/gcc/config/i386/avx512fintrin.h
index 454fd3d..c2ca4e1 100644
--- a/gcc/config/i386/avx512fintrin.h
+++ b/gcc/config/i386/avx512fintrin.h
@@ -15437,6 +15437,48 @@ _mm512_castsi256_si512 (__m256i __A)
return (__m512i)__builtin_ia32_si512_256si ((__v8si)__A);
}
+extern __inline __m512d
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm512_zextpd128_pd512 (__m128d __A)
+{
+ return (__m512d) _mm512_insertf32x4 (_mm512_setzero_ps (), (__m128) __A, 0);
+}
+
+extern __inline __m512
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm512_zextps128_ps512 (__m128 __A)
+{
+ return _mm512_insertf32x4 (_mm512_setzero_ps (), __A, 0);
+}
+
+extern __inline __m512i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm512_zextsi128_si512 (__m128i __A)
+{
+ return _mm512_inserti32x4 (_mm512_setzero_si512 (), __A, 0);
+}
+
+extern __inline __m512d
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm512_zextpd256_pd512 (__m256d __A)
+{
+ return _mm512_insertf64x4 (_mm512_setzero_pd (), __A, 0);
+}
+
+extern __inline __m512
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm512_zextps256_ps512 (__m256 __A)
+{
+ return (__m512) _mm512_insertf64x4 (_mm512_setzero_pd (), (__m256d) __A, 0);
+}
+
+extern __inline __m512i
+__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
+_mm512_zextsi256_si512 (__m256i __A)
+{
+ return _mm512_inserti64x4 (_mm512_setzero_si512 (), __A, 0);
+}
+
extern __inline __mmask16
__attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
_mm512_cmpeq_epu32_mask (__m512i __A, __m512i __B)
diff --git a/gcc/config/i386/avxintrin.h b/gcc/config/i386/avxintrin.h
index 29115a1..c8f8d53 100644
--- a/gcc/config/i386/avxintrin.h
+++ b/gcc/config/i386/avxintrin.h
@@ -1484,6 +1484,26 @@ _mm256_castsi128_si256 (__m128i __A)
return (__m256i) __builtin_ia32_si256_si ((__v4si)__A);
}
+/* Similarly, but with zero extension instead of undefined values. */
+
+extern __inline __m256d __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_zextpd128_pd256 (__m128d __A)
+{
+ return _mm256_insertf128_pd (_mm256_setzero_pd (), __A, 0);
+}
+
+extern __inline __m256 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_zextps128_ps256 (__m128 __A)
+{
+ return _mm256_insertf128_ps (_mm256_setzero_ps (), __A, 0);
+}
+
+extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_zextsi128_si256 (__m128i __A)
+{
+ return _mm256_insertf128_si256 (_mm256_setzero_si256 (), __A, 0);
+}
+
extern __inline __m256 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm256_set_m128 ( __m128 __H, __m128 __L)
{
@@ -1520,6 +1540,48 @@ _mm256_setr_m128i (__m128i __L, __m128i __H)
return _mm256_set_m128i (__H, __L);
}
+extern __inline __m256 __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_loadu2_m128 (float const *__PH, float const *__PL)
+{
+ return _mm256_insertf128_ps (_mm256_castps128_ps256 (_mm_loadu_ps (__PL)),
+ _mm_loadu_ps (__PH), 1);
+}
+
+extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_storeu2_m128 (float *__PH, float *__PL, __m256 __A)
+{
+ _mm_storeu_ps (__PL, _mm256_castps256_ps128 (__A));
+ _mm_storeu_ps (__PH, _mm256_extractf128_ps (__A, 1));
+}
+
+extern __inline __m256d __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_loadu2_m128d (double const *__PH, double const *__PL)
+{
+ return _mm256_insertf128_pd (_mm256_castpd128_pd256 (_mm_loadu_pd (__PL)),
+ _mm_loadu_pd (__PH), 1);
+}
+
+extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_storeu2_m128d (double *__PH, double *__PL, __m256d __A)
+{
+ _mm_storeu_pd (__PL, _mm256_castpd256_pd128 (__A));
+ _mm_storeu_pd (__PH, _mm256_extractf128_pd (__A, 1));
+}
+
+extern __inline __m256i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_loadu2_m128i (__m128i_u const *__PH, __m128i_u const *__PL)
+{
+ return _mm256_insertf128_si256 (_mm256_castsi128_si256 (_mm_loadu_si128 (__PL)),
+ _mm_loadu_si128 (__PH), 1);
+}
+
+extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm256_storeu2_m128i (__m128i_u *__PH, __m128i_u *__PL, __m256i __A)
+{
+ _mm_storeu_si128 (__PL, _mm256_castsi256_si128 (__A));
+ _mm_storeu_si128 (__PH, _mm256_extractf128_si256 (__A, 1));
+}
+
#ifdef __DISABLE_AVX__
#undef __DISABLE_AVX__
#pragma GCC pop_options
diff --git a/gcc/config/i386/darwin.h b/gcc/config/i386/darwin.h
index 93bd558..385d253 100644
--- a/gcc/config/i386/darwin.h
+++ b/gcc/config/i386/darwin.h
@@ -47,12 +47,13 @@ along with GCC; see the file COPYING3. If not see
image.
Therefore, for 64b exes at least, we must use the libunwind implementation,
even when static-libgcc is specified. We put libSystem first so that
- unwinder symbols are satisfied from there. */
+ unwinder symbols are satisfied from there.
+ We default to 64b for single-arch builds, so apply this unconditionally. */
#undef REAL_LIBGCC_SPEC
#define REAL_LIBGCC_SPEC \
"%{static-libgcc|static: \
- %{m64:%:version-compare(>= 10.6 mmacosx-version-min= -lSystem)} \
- -lgcc_eh -lgcc; \
+ %:version-compare(>= 10.6 mmacosx-version-min= -lSystem) \
+ -lgcc_eh -lgcc; \
shared-libgcc|fexceptions|fgnu-runtime: \
%:version-compare(!> 10.5 mmacosx-version-min= -lgcc_s.10.4) \
%:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5) \
@@ -90,8 +91,8 @@ along with GCC; see the file COPYING3. If not see
#define WCHAR_TYPE_SIZE 32
/* Generate pic symbol indirection stubs if this is true. */
-#undef TARGET_MACHO_PICSYM_STUBS
-#define TARGET_MACHO_PICSYM_STUBS (darwin_picsymbol_stubs)
+#undef TARGET_MACHO_SYMBOL_STUBS
+#define TARGET_MACHO_SYMBOL_STUBS (darwin_symbol_stubs)
/* For compatibility with OSX system tools, use the new style of pic stub
if this is set (default). */
@@ -139,9 +140,6 @@ along with GCC; see the file COPYING3. If not see
" ASM_OPTIONS " -force_cpusubtype_ALL \
%{static}" ASM_MMACOSX_VERSION_MIN_SPEC
-#define DARWIN_ARCH_SPEC "%{m64:x86_64;:i386}"
-#define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC
-
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
"%{Ofast|ffast-math|funsafe-math-optimizations:crtfastmath.o%s} \
@@ -149,12 +147,15 @@ along with GCC; see the file COPYING3. If not see
%{mpc64:crtprec64.o%s} \
%{mpc80:crtprec80.o%s}" TM_DESTRUCTOR
+/* We default to x86_64 for single-arch builds, bi-arch overrides. */
+#define DARWIN_ARCH_SPEC "x86_64"
+
#undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
DARWIN_EXTRA_SPECS \
- { "darwin_arch", DARWIN_ARCH_SPEC }, \
+ { "darwin_arch", DARWIN_ARCH_SPEC }, \
{ "darwin_crt2", "" }, \
- { "darwin_subarch", DARWIN_SUBARCH_SPEC },
+ { "darwin_subarch", DARWIN_ARCH_SPEC },
/* The Darwin assembler mostly follows AT&T syntax. */
#undef ASSEMBLER_DIALECT
@@ -242,7 +243,7 @@ along with GCC; see the file COPYING3. If not see
#undef FUNCTION_PROFILER
#define FUNCTION_PROFILER(FILE, LABELNO) \
do { \
- if (TARGET_MACHO_PICSYM_STUBS \
+ if (TARGET_MACHO_SYMBOL_STUBS \
&& MACHOPIC_INDIRECT && !TARGET_64BIT) \
{ \
const char *name = machopic_mcount_stub_name (); \
diff --git a/gcc/config/i386/darwin32-biarch.h b/gcc/config/i386/darwin32-biarch.h
new file mode 100644
index 0000000..8dcc4a3
--- /dev/null
+++ b/gcc/config/i386/darwin32-biarch.h
@@ -0,0 +1,58 @@
+/* Target definitions for i386 running Darwin with a 32b host and supporting
+ a 64b multilib.
+ Copyright (C) 2019 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/>. */
+
+#undef DARWIN_ARCH_SPEC
+#define DARWIN_ARCH_SPEC "%{m64:x86_64;:i386}"
+
+/* WORKAROUND pr80556:
+ For x86_64 Darwin10 and later, the unwinder is in libunwind (redirected
+ from libSystem). This doesn't use the keymgr (see keymgr.c) and therefore
+ the calls that libgcc makes to obtain the KEYMGR_GCC3_DW2_OBJ_LIST are not
+ updated to include new images, and might not even be valid for a single
+ image.
+ Therefore, for 64b exes at least, we must use the libunwind implementation,
+ even when static-libgcc is specified. We put libSystem first so that
+ unwinder symbols are satisfied from there. */
+#undef REAL_LIBGCC_SPEC
+#define REAL_LIBGCC_SPEC \
+ "%{static-libgcc|static: \
+ %{m64:%:version-compare(>= 10.6 mmacosx-version-min= -lSystem)} \
+ -lgcc_eh -lgcc; \
+ shared-libgcc|fexceptions|fgnu-runtime: \
+ %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_s.10.4) \
+ %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5) \
+ %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4) \
+ %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5) \
+ -lgcc ; \
+ :%:version-compare(>< 10.3.9 10.5 mmacosx-version-min= -lgcc_s.10.4) \
+ %:version-compare(>< 10.5 10.6 mmacosx-version-min= -lgcc_s.10.5) \
+ %:version-compare(!> 10.5 mmacosx-version-min= -lgcc_ext.10.4) \
+ %:version-compare(>= 10.5 mmacosx-version-min= -lgcc_ext.10.5) \
+ -lgcc }"
+
+#undef DARWIN_SUBARCH_SPEC
+#define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC
+
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ DARWIN_EXTRA_SPECS \
+ { "darwin_arch", DARWIN_ARCH_SPEC }, \
+ { "darwin_crt2", "" }, \
+ { "darwin_subarch", DARWIN_SUBARCH_SPEC },
diff --git a/gcc/config/i386/darwin64.h b/gcc/config/i386/darwin64-biarch.h
index ebd65f9..5af7665c 100644
--- a/gcc/config/i386/darwin64.h
+++ b/gcc/config/i386/darwin64-biarch.h
@@ -1,4 +1,5 @@
-/* Target definitions for x86_64 running Darwin.
+/* Target definitions for x86_64 running Darwin with a 64b host supporting a
+ 32b multilib.
Copyright (C) 2006-2019 Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
diff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c
index 9b6a59d..9736a75 100644
--- a/gcc/config/i386/i386-builtins.c
+++ b/gcc/config/i386/i386-builtins.c
@@ -1833,7 +1833,7 @@ tree
ix86_builtin_reciprocal (tree fndecl)
{
enum ix86_builtins fn_code
- = (enum ix86_builtins) DECL_FUNCTION_CODE (fndecl);
+ = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
switch (fn_code)
{
/* Vectorized version of sqrt to rsqrt conversion. */
@@ -2407,8 +2407,8 @@ tree
fold_builtin_cpu (tree fndecl, tree *args)
{
unsigned int i;
- enum ix86_builtins fn_code = (enum ix86_builtins)
- DECL_FUNCTION_CODE (fndecl);
+ enum ix86_builtins fn_code
+ = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
tree param_string_cst = NULL;
tree __processor_model_type = build_processor_model_struct ();
diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c
index d50e21e..b6a2dbf 100644
--- a/gcc/config/i386/i386-expand.c
+++ b/gcc/config/i386/i386-expand.c
@@ -2286,16 +2286,16 @@ ix86_unordered_fp_compare (enum rtx_code code)
switch (code)
{
- case GT:
- case GE:
case LT:
case LE:
+ case GT:
+ case GE:
+ case LTGT:
return false;
case EQ:
case NE:
- case LTGT:
case UNORDERED:
case ORDERED:
case UNLT:
@@ -10978,7 +10978,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
tree arg0, arg1, arg2, arg3, arg4;
rtx op0, op1, op2, op3, op4, pat, pat2, insn;
machine_mode mode0, mode1, mode2, mode3, mode4;
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
/* For CPU builtins that can be folded, fold first and expand the fold. */
switch (fcode)
@@ -12535,7 +12535,7 @@ rdseed_step:
tree fndecl = gimple_call_fndecl (def_stmt);
if (fndecl
&& fndecl_built_in_p (fndecl, BUILT_IN_MD))
- switch ((unsigned int) DECL_FUNCTION_CODE (fndecl))
+ switch (DECL_MD_FUNCTION_CODE (fndecl))
{
case IX86_BUILTIN_CMPPD:
case IX86_BUILTIN_CMPPS:
@@ -13383,6 +13383,9 @@ ix86_expand_vector_init_one_nonzero (bool mmx_ok, machine_mode mode,
case E_V8HImode:
use_vector_set = TARGET_SSE2;
break;
+ case E_V8QImode:
+ use_vector_set = TARGET_MMX_WITH_SSE && TARGET_SSE4_1;
+ break;
case E_V4HImode:
use_vector_set = TARGET_SSE || TARGET_3DNOW_A;
break;
@@ -13590,6 +13593,8 @@ ix86_expand_vector_init_one_var (bool mmx_ok, machine_mode mode,
wmode = V8HImode;
goto widen;
case E_V8QImode:
+ if (TARGET_MMX_WITH_SSE && TARGET_SSE4_1)
+ break;
wmode = V4HImode;
goto widen;
widen:
@@ -14243,8 +14248,13 @@ ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt)
switch (mode)
{
- case E_V2SFmode:
case E_V2SImode:
+ use_vec_merge = TARGET_MMX_WITH_SSE && TARGET_SSE4_1;
+ if (use_vec_merge)
+ break;
+ /* FALLTHRU */
+
+ case E_V2SFmode:
if (mmx_ok)
{
tmp = gen_reg_rtx (GET_MODE_INNER (mode));
@@ -14409,6 +14419,7 @@ ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt)
break;
case E_V8QImode:
+ use_vec_merge = TARGET_MMX_WITH_SSE && TARGET_SSE4_1;
break;
case E_V32QImode:
@@ -14611,6 +14622,11 @@ ix86_expand_vector_extract (bool mmx_ok, rtx target, rtx vec, int elt)
switch (mode)
{
case E_V2SImode:
+ use_vec_extr = TARGET_MMX_WITH_SSE && TARGET_SSE4_1;
+ if (use_vec_extr)
+ break;
+ /* FALLTHRU */
+
case E_V2SFmode:
if (!mmx_ok)
break;
@@ -14706,6 +14722,17 @@ ix86_expand_vector_extract (bool mmx_ok, rtx target, rtx vec, int elt)
case E_V16QImode:
use_vec_extr = TARGET_SSE4_1;
+ if (!use_vec_extr
+ && TARGET_SSE2
+ && elt == 0
+ && (optimize_insn_for_size_p () || TARGET_INTER_UNIT_MOVES_FROM_VEC))
+ {
+ tmp = gen_reg_rtx (SImode);
+ ix86_expand_vector_extract (false, tmp, gen_lowpart (V4SImode, vec),
+ 0);
+ emit_insn (gen_rtx_SET (target, gen_lowpart (QImode, tmp)));
+ return;
+ }
break;
case E_V8SFmode:
@@ -14849,7 +14876,10 @@ ix86_expand_vector_extract (bool mmx_ok, rtx target, rtx vec, int elt)
return;
case E_V8QImode:
+ use_vec_extr = TARGET_MMX_WITH_SSE && TARGET_SSE4_1;
/* ??? Could extract the appropriate HImode element and shift. */
+ break;
+
default:
break;
}
@@ -16385,7 +16415,8 @@ static bool
expand_vec_perm_blend (struct expand_vec_perm_d *d)
{
machine_mode mmode, vmode = d->vmode;
- unsigned i, mask, nelt = d->nelt;
+ unsigned i, nelt = d->nelt;
+ unsigned HOST_WIDE_INT mask;
rtx target, op0, op1, maskop, x;
rtx rperm[32], vperm;
@@ -16439,7 +16470,7 @@ expand_vec_perm_blend (struct expand_vec_perm_d *d)
case E_V16SImode:
case E_V8DImode:
for (i = 0; i < nelt; ++i)
- mask |= (d->perm[i] >= nelt) << i;
+ mask |= ((unsigned HOST_WIDE_INT) (d->perm[i] >= nelt)) << i;
break;
case E_V2DImode:
diff --git a/gcc/config/i386/i386-features.c b/gcc/config/i386/i386-features.c
index 6ccd42a..c4a3d30 100644
--- a/gcc/config/i386/i386-features.c
+++ b/gcc/config/i386/i386-features.c
@@ -276,8 +276,11 @@ unsigned scalar_chain::max_id = 0;
/* Initialize new chain. */
-scalar_chain::scalar_chain ()
+scalar_chain::scalar_chain (enum machine_mode smode_, enum machine_mode vmode_)
{
+ smode = smode_;
+ vmode = vmode_;
+
chain_id = ++max_id;
if (dump_file)
@@ -319,7 +322,7 @@ scalar_chain::add_to_queue (unsigned insn_uid)
conversion. */
void
-dimode_scalar_chain::mark_dual_mode_def (df_ref def)
+general_scalar_chain::mark_dual_mode_def (df_ref def)
{
gcc_assert (DF_REF_REG_DEF_P (def));
@@ -409,6 +412,9 @@ scalar_chain::add_insn (bitmap candidates, unsigned int insn_uid)
&& !HARD_REGISTER_P (SET_DEST (def_set)))
bitmap_set_bit (defs, REGNO (SET_DEST (def_set)));
+ /* ??? The following is quadratic since analyze_register_chain
+ iterates over all refs to look for dual-mode regs. Instead this
+ should be done separately for all regs mentioned in the chain once. */
df_ref ref;
df_ref def;
for (ref = DF_INSN_UID_DEFS (insn_uid); ref; ref = DF_REF_NEXT_LOC (ref))
@@ -469,19 +475,21 @@ scalar_chain::build (bitmap candidates, unsigned insn_uid)
instead of using a scalar one. */
int
-dimode_scalar_chain::vector_const_cost (rtx exp)
+general_scalar_chain::vector_const_cost (rtx exp)
{
gcc_assert (CONST_INT_P (exp));
- if (standard_sse_constant_p (exp, V2DImode))
- return COSTS_N_INSNS (1);
- return ix86_cost->sse_load[1];
+ if (standard_sse_constant_p (exp, vmode))
+ return ix86_cost->sse_op;
+ /* We have separate costs for SImode and DImode, use SImode costs
+ for smaller modes. */
+ return ix86_cost->sse_load[smode == DImode ? 1 : 0];
}
/* Compute a gain for chain conversion. */
int
-dimode_scalar_chain::compute_convert_gain ()
+general_scalar_chain::compute_convert_gain ()
{
bitmap_iterator bi;
unsigned insn_uid;
@@ -491,28 +499,37 @@ dimode_scalar_chain::compute_convert_gain ()
if (dump_file)
fprintf (dump_file, "Computing gain for chain #%d...\n", chain_id);
+ /* SSE costs distinguish between SImode and DImode loads/stores, for
+ int costs factor in the number of GPRs involved. When supporting
+ smaller modes than SImode the int load/store costs need to be
+ adjusted as well. */
+ unsigned sse_cost_idx = smode == DImode ? 1 : 0;
+ unsigned m = smode == DImode ? (TARGET_64BIT ? 1 : 2) : 1;
+
EXECUTE_IF_SET_IN_BITMAP (insns, 0, insn_uid, bi)
{
rtx_insn *insn = DF_INSN_UID_GET (insn_uid)->insn;
rtx def_set = single_set (insn);
rtx src = SET_SRC (def_set);
rtx dst = SET_DEST (def_set);
+ int igain = 0;
if (REG_P (src) && REG_P (dst))
- gain += COSTS_N_INSNS (2) - ix86_cost->xmm_move;
+ igain += 2 * m - ix86_cost->xmm_move;
else if (REG_P (src) && MEM_P (dst))
- gain += 2 * ix86_cost->int_store[2] - ix86_cost->sse_store[1];
+ igain
+ += m * ix86_cost->int_store[2] - ix86_cost->sse_store[sse_cost_idx];
else if (MEM_P (src) && REG_P (dst))
- gain += 2 * ix86_cost->int_load[2] - ix86_cost->sse_load[1];
+ igain += m * ix86_cost->int_load[2] - ix86_cost->sse_load[sse_cost_idx];
else if (GET_CODE (src) == ASHIFT
|| GET_CODE (src) == ASHIFTRT
|| GET_CODE (src) == LSHIFTRT)
{
if (CONST_INT_P (XEXP (src, 0)))
- gain -= vector_const_cost (XEXP (src, 0));
- gain += ix86_cost->shift_const;
+ igain -= vector_const_cost (XEXP (src, 0));
+ igain += m * ix86_cost->shift_const - ix86_cost->sse_op;
if (INTVAL (XEXP (src, 1)) >= 32)
- gain -= COSTS_N_INSNS (1);
+ igain -= COSTS_N_INSNS (1);
}
else if (GET_CODE (src) == PLUS
|| GET_CODE (src) == MINUS
@@ -520,20 +537,31 @@ dimode_scalar_chain::compute_convert_gain ()
|| GET_CODE (src) == XOR
|| GET_CODE (src) == AND)
{
- gain += ix86_cost->add;
+ igain += m * ix86_cost->add - ix86_cost->sse_op;
/* Additional gain for andnot for targets without BMI. */
if (GET_CODE (XEXP (src, 0)) == NOT
&& !TARGET_BMI)
- gain += 2 * ix86_cost->add;
+ igain += m * ix86_cost->add;
if (CONST_INT_P (XEXP (src, 0)))
- gain -= vector_const_cost (XEXP (src, 0));
+ igain -= vector_const_cost (XEXP (src, 0));
if (CONST_INT_P (XEXP (src, 1)))
- gain -= vector_const_cost (XEXP (src, 1));
+ igain -= vector_const_cost (XEXP (src, 1));
}
else if (GET_CODE (src) == NEG
|| GET_CODE (src) == NOT)
- gain += ix86_cost->add - COSTS_N_INSNS (1);
+ igain += m * ix86_cost->add - ix86_cost->sse_op - COSTS_N_INSNS (1);
+ else if (GET_CODE (src) == SMAX
+ || GET_CODE (src) == SMIN
+ || GET_CODE (src) == UMAX
+ || GET_CODE (src) == UMIN)
+ {
+ /* We do not have any conditional move cost, estimate it as a
+ reg-reg move. Comparisons are costed as adds. */
+ igain += m * (COSTS_N_INSNS (2) + ix86_cost->add);
+ /* Integer SSE ops are all costed the same. */
+ igain -= ix86_cost->sse_op;
+ }
else if (GET_CODE (src) == COMPARE)
{
/* Assume comparison cost is the same. */
@@ -541,18 +569,28 @@ dimode_scalar_chain::compute_convert_gain ()
else if (CONST_INT_P (src))
{
if (REG_P (dst))
- gain += COSTS_N_INSNS (2);
+ /* DImode can be immediate for TARGET_64BIT and SImode always. */
+ igain += m * COSTS_N_INSNS (1);
else if (MEM_P (dst))
- gain += 2 * ix86_cost->int_store[2] - ix86_cost->sse_store[1];
- gain -= vector_const_cost (src);
+ igain += (m * ix86_cost->int_store[2]
+ - ix86_cost->sse_store[sse_cost_idx]);
+ igain -= vector_const_cost (src);
}
else
gcc_unreachable ();
+
+ if (igain != 0 && dump_file)
+ {
+ fprintf (dump_file, " Instruction gain %d for ", igain);
+ dump_insn_slim (dump_file, insn);
+ }
+ gain += igain;
}
if (dump_file)
fprintf (dump_file, " Instruction conversion gain: %d\n", gain);
+ /* ??? What about integer to SSE? */
EXECUTE_IF_SET_IN_BITMAP (defs_conv, 0, insn_uid, bi)
cost += DF_REG_DEF_COUNT (insn_uid) * ix86_cost->sse_to_integer;
@@ -570,10 +608,14 @@ dimode_scalar_chain::compute_convert_gain ()
/* Replace REG in X with a V2DI subreg of NEW_REG. */
rtx
-dimode_scalar_chain::replace_with_subreg (rtx x, rtx reg, rtx new_reg)
+general_scalar_chain::replace_with_subreg (rtx x, rtx reg, rtx new_reg)
{
if (x == reg)
- return gen_rtx_SUBREG (V2DImode, new_reg, 0);
+ return gen_rtx_SUBREG (vmode, new_reg, 0);
+
+ /* But not in memory addresses. */
+ if (MEM_P (x))
+ return x;
const char *fmt = GET_RTX_FORMAT (GET_CODE (x));
int i, j;
@@ -593,7 +635,7 @@ dimode_scalar_chain::replace_with_subreg (rtx x, rtx reg, rtx new_reg)
/* Replace REG in INSN with a V2DI subreg of NEW_REG. */
void
-dimode_scalar_chain::replace_with_subreg_in_insn (rtx_insn *insn,
+general_scalar_chain::replace_with_subreg_in_insn (rtx_insn *insn,
rtx reg, rtx new_reg)
{
replace_with_subreg (single_set (insn), reg, new_reg);
@@ -620,14 +662,33 @@ scalar_chain::emit_conversion_insns (rtx insns, rtx_insn *after)
emit_insn_after (insns, BB_HEAD (new_bb));
}
+/* Generate the canonical SET_SRC to move GPR to a VMODE vector register,
+ zeroing the upper parts. */
+
+static rtx
+gen_gpr_to_xmm_move_src (enum machine_mode vmode, rtx gpr)
+{
+ switch (GET_MODE_NUNITS (vmode))
+ {
+ case 1:
+ return gen_rtx_SUBREG (vmode, gpr, 0);
+ case 2:
+ return gen_rtx_VEC_CONCAT (vmode, gpr,
+ CONST0_RTX (GET_MODE_INNER (vmode)));
+ default:
+ return gen_rtx_VEC_MERGE (vmode, gen_rtx_VEC_DUPLICATE (vmode, gpr),
+ CONST0_RTX (vmode), GEN_INT (HOST_WIDE_INT_1U));
+ }
+}
+
/* Make vector copies for all register REGNO definitions
and replace its uses in a chain. */
void
-dimode_scalar_chain::make_vector_copies (unsigned regno)
+general_scalar_chain::make_vector_copies (unsigned regno)
{
rtx reg = regno_reg_rtx[regno];
- rtx vreg = gen_reg_rtx (DImode);
+ rtx vreg = gen_reg_rtx (smode);
df_ref ref;
for (ref = DF_REG_DEF_CHAIN (regno); ref; ref = DF_REF_NEXT_REG (ref))
@@ -636,37 +697,49 @@ dimode_scalar_chain::make_vector_copies (unsigned regno)
start_sequence ();
if (!TARGET_INTER_UNIT_MOVES_TO_VEC)
{
- rtx tmp = assign_386_stack_local (DImode, SLOT_STV_TEMP);
- emit_move_insn (adjust_address (tmp, SImode, 0),
- gen_rtx_SUBREG (SImode, reg, 0));
- emit_move_insn (adjust_address (tmp, SImode, 4),
- gen_rtx_SUBREG (SImode, reg, 4));
- emit_move_insn (vreg, tmp);
+ rtx tmp = assign_386_stack_local (smode, SLOT_STV_TEMP);
+ if (smode == DImode && !TARGET_64BIT)
+ {
+ emit_move_insn (adjust_address (tmp, SImode, 0),
+ gen_rtx_SUBREG (SImode, reg, 0));
+ emit_move_insn (adjust_address (tmp, SImode, 4),
+ gen_rtx_SUBREG (SImode, reg, 4));
+ }
+ else
+ emit_move_insn (tmp, reg);
+ emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0),
+ gen_gpr_to_xmm_move_src (vmode, tmp)));
}
- else if (TARGET_SSE4_1)
+ else if (!TARGET_64BIT && smode == DImode)
{
- emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0),
- CONST0_RTX (V4SImode),
- gen_rtx_SUBREG (SImode, reg, 0)));
- emit_insn (gen_sse4_1_pinsrd (gen_rtx_SUBREG (V4SImode, vreg, 0),
- gen_rtx_SUBREG (V4SImode, vreg, 0),
- gen_rtx_SUBREG (SImode, reg, 4),
- GEN_INT (2)));
+ if (TARGET_SSE4_1)
+ {
+ emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0),
+ CONST0_RTX (V4SImode),
+ gen_rtx_SUBREG (SImode, reg, 0)));
+ emit_insn (gen_sse4_1_pinsrd (gen_rtx_SUBREG (V4SImode, vreg, 0),
+ gen_rtx_SUBREG (V4SImode, vreg, 0),
+ gen_rtx_SUBREG (SImode, reg, 4),
+ GEN_INT (2)));
+ }
+ else
+ {
+ rtx tmp = gen_reg_rtx (DImode);
+ emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0),
+ CONST0_RTX (V4SImode),
+ gen_rtx_SUBREG (SImode, reg, 0)));
+ emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, tmp, 0),
+ CONST0_RTX (V4SImode),
+ gen_rtx_SUBREG (SImode, reg, 4)));
+ emit_insn (gen_vec_interleave_lowv4si
+ (gen_rtx_SUBREG (V4SImode, vreg, 0),
+ gen_rtx_SUBREG (V4SImode, vreg, 0),
+ gen_rtx_SUBREG (V4SImode, tmp, 0)));
+ }
}
else
- {
- rtx tmp = gen_reg_rtx (DImode);
- emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, vreg, 0),
- CONST0_RTX (V4SImode),
- gen_rtx_SUBREG (SImode, reg, 0)));
- emit_insn (gen_sse2_loadld (gen_rtx_SUBREG (V4SImode, tmp, 0),
- CONST0_RTX (V4SImode),
- gen_rtx_SUBREG (SImode, reg, 4)));
- emit_insn (gen_vec_interleave_lowv4si
- (gen_rtx_SUBREG (V4SImode, vreg, 0),
- gen_rtx_SUBREG (V4SImode, vreg, 0),
- gen_rtx_SUBREG (V4SImode, tmp, 0)));
- }
+ emit_insn (gen_rtx_SET (gen_rtx_SUBREG (vmode, vreg, 0),
+ gen_gpr_to_xmm_move_src (vmode, reg)));
rtx_insn *seq = get_insns ();
end_sequence ();
rtx_insn *insn = DF_REF_INSN (ref);
@@ -695,7 +768,7 @@ dimode_scalar_chain::make_vector_copies (unsigned regno)
in case register is used in not convertible insn. */
void
-dimode_scalar_chain::convert_reg (unsigned regno)
+general_scalar_chain::convert_reg (unsigned regno)
{
bool scalar_copy = bitmap_bit_p (defs_conv, regno);
rtx reg = regno_reg_rtx[regno];
@@ -707,7 +780,7 @@ dimode_scalar_chain::convert_reg (unsigned regno)
bitmap_copy (conv, insns);
if (scalar_copy)
- scopy = gen_reg_rtx (DImode);
+ scopy = gen_reg_rtx (smode);
for (ref = DF_REG_DEF_CHAIN (regno); ref; ref = DF_REF_NEXT_REG (ref))
{
@@ -727,40 +800,55 @@ dimode_scalar_chain::convert_reg (unsigned regno)
start_sequence ();
if (!TARGET_INTER_UNIT_MOVES_FROM_VEC)
{
- rtx tmp = assign_386_stack_local (DImode, SLOT_STV_TEMP);
+ rtx tmp = assign_386_stack_local (smode, SLOT_STV_TEMP);
emit_move_insn (tmp, reg);
- emit_move_insn (gen_rtx_SUBREG (SImode, scopy, 0),
- adjust_address (tmp, SImode, 0));
- emit_move_insn (gen_rtx_SUBREG (SImode, scopy, 4),
- adjust_address (tmp, SImode, 4));
+ if (!TARGET_64BIT && smode == DImode)
+ {
+ emit_move_insn (gen_rtx_SUBREG (SImode, scopy, 0),
+ adjust_address (tmp, SImode, 0));
+ emit_move_insn (gen_rtx_SUBREG (SImode, scopy, 4),
+ adjust_address (tmp, SImode, 4));
+ }
+ else
+ emit_move_insn (scopy, tmp);
}
- else if (TARGET_SSE4_1)
+ else if (!TARGET_64BIT && smode == DImode)
{
- rtx tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const0_rtx));
- emit_insn
- (gen_rtx_SET
- (gen_rtx_SUBREG (SImode, scopy, 0),
- gen_rtx_VEC_SELECT (SImode,
- gen_rtx_SUBREG (V4SImode, reg, 0), tmp)));
-
- tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const1_rtx));
- emit_insn
- (gen_rtx_SET
- (gen_rtx_SUBREG (SImode, scopy, 4),
- gen_rtx_VEC_SELECT (SImode,
- gen_rtx_SUBREG (V4SImode, reg, 0), tmp)));
+ if (TARGET_SSE4_1)
+ {
+ rtx tmp = gen_rtx_PARALLEL (VOIDmode,
+ gen_rtvec (1, const0_rtx));
+ emit_insn
+ (gen_rtx_SET
+ (gen_rtx_SUBREG (SImode, scopy, 0),
+ gen_rtx_VEC_SELECT (SImode,
+ gen_rtx_SUBREG (V4SImode, reg, 0),
+ tmp)));
+
+ tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (1, const1_rtx));
+ emit_insn
+ (gen_rtx_SET
+ (gen_rtx_SUBREG (SImode, scopy, 4),
+ gen_rtx_VEC_SELECT (SImode,
+ gen_rtx_SUBREG (V4SImode, reg, 0),
+ tmp)));
+ }
+ else
+ {
+ rtx vcopy = gen_reg_rtx (V2DImode);
+ emit_move_insn (vcopy, gen_rtx_SUBREG (V2DImode, reg, 0));
+ emit_move_insn (gen_rtx_SUBREG (SImode, scopy, 0),
+ gen_rtx_SUBREG (SImode, vcopy, 0));
+ emit_move_insn (vcopy,
+ gen_rtx_LSHIFTRT (V2DImode,
+ vcopy, GEN_INT (32)));
+ emit_move_insn (gen_rtx_SUBREG (SImode, scopy, 4),
+ gen_rtx_SUBREG (SImode, vcopy, 0));
+ }
}
else
- {
- rtx vcopy = gen_reg_rtx (V2DImode);
- emit_move_insn (vcopy, gen_rtx_SUBREG (V2DImode, reg, 0));
- emit_move_insn (gen_rtx_SUBREG (SImode, scopy, 0),
- gen_rtx_SUBREG (SImode, vcopy, 0));
- emit_move_insn (vcopy,
- gen_rtx_LSHIFTRT (V2DImode, vcopy, GEN_INT (32)));
- emit_move_insn (gen_rtx_SUBREG (SImode, scopy, 4),
- gen_rtx_SUBREG (SImode, vcopy, 0));
- }
+ emit_move_insn (scopy, reg);
+
rtx_insn *seq = get_insns ();
end_sequence ();
emit_conversion_insns (seq, insn);
@@ -809,21 +897,21 @@ dimode_scalar_chain::convert_reg (unsigned regno)
registers conversion. */
void
-dimode_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
+general_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
{
*op = copy_rtx_if_shared (*op);
if (GET_CODE (*op) == NOT)
{
convert_op (&XEXP (*op, 0), insn);
- PUT_MODE (*op, V2DImode);
+ PUT_MODE (*op, vmode);
}
else if (MEM_P (*op))
{
- rtx tmp = gen_reg_rtx (DImode);
+ rtx tmp = gen_reg_rtx (GET_MODE (*op));
emit_insn_before (gen_move_insn (tmp, *op), insn);
- *op = gen_rtx_SUBREG (V2DImode, tmp, 0);
+ *op = gen_rtx_SUBREG (vmode, tmp, 0);
if (dump_file)
fprintf (dump_file, " Preloading operand for insn %d into r%d\n",
@@ -841,24 +929,30 @@ dimode_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
gcc_assert (!DF_REF_CHAIN (ref));
break;
}
- *op = gen_rtx_SUBREG (V2DImode, *op, 0);
+ *op = gen_rtx_SUBREG (vmode, *op, 0);
}
else if (CONST_INT_P (*op))
{
rtx vec_cst;
- rtx tmp = gen_rtx_SUBREG (V2DImode, gen_reg_rtx (DImode), 0);
+ rtx tmp = gen_rtx_SUBREG (vmode, gen_reg_rtx (smode), 0);
/* Prefer all ones vector in case of -1. */
if (constm1_operand (*op, GET_MODE (*op)))
- vec_cst = CONSTM1_RTX (V2DImode);
+ vec_cst = CONSTM1_RTX (vmode);
else
- vec_cst = gen_rtx_CONST_VECTOR (V2DImode,
- gen_rtvec (2, *op, const0_rtx));
+ {
+ unsigned n = GET_MODE_NUNITS (vmode);
+ rtx *v = XALLOCAVEC (rtx, n);
+ v[0] = *op;
+ for (unsigned i = 1; i < n; ++i)
+ v[i] = const0_rtx;
+ vec_cst = gen_rtx_CONST_VECTOR (vmode, gen_rtvec_v (n, v));
+ }
- if (!standard_sse_constant_p (vec_cst, V2DImode))
+ if (!standard_sse_constant_p (vec_cst, vmode))
{
start_sequence ();
- vec_cst = validize_mem (force_const_mem (V2DImode, vec_cst));
+ vec_cst = validize_mem (force_const_mem (vmode, vec_cst));
rtx_insn *seq = get_insns ();
end_sequence ();
emit_insn_before (seq, insn);
@@ -870,14 +964,14 @@ dimode_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
else
{
gcc_assert (SUBREG_P (*op));
- gcc_assert (GET_MODE (*op) == V2DImode);
+ gcc_assert (GET_MODE (*op) == vmode);
}
}
/* Convert INSN to vector mode. */
void
-dimode_scalar_chain::convert_insn (rtx_insn *insn)
+general_scalar_chain::convert_insn (rtx_insn *insn)
{
rtx def_set = single_set (insn);
rtx src = SET_SRC (def_set);
@@ -888,9 +982,9 @@ dimode_scalar_chain::convert_insn (rtx_insn *insn)
{
/* There are no scalar integer instructions and therefore
temporary register usage is required. */
- rtx tmp = gen_reg_rtx (DImode);
+ rtx tmp = gen_reg_rtx (smode);
emit_conversion_insns (gen_move_insn (dst, tmp), insn);
- dst = gen_rtx_SUBREG (V2DImode, tmp, 0);
+ dst = gen_rtx_SUBREG (vmode, tmp, 0);
}
switch (GET_CODE (src))
@@ -899,7 +993,7 @@ dimode_scalar_chain::convert_insn (rtx_insn *insn)
case ASHIFTRT:
case LSHIFTRT:
convert_op (&XEXP (src, 0), insn);
- PUT_MODE (src, V2DImode);
+ PUT_MODE (src, vmode);
break;
case PLUS:
@@ -907,25 +1001,29 @@ dimode_scalar_chain::convert_insn (rtx_insn *insn)
case IOR:
case XOR:
case AND:
+ case SMAX:
+ case SMIN:
+ case UMAX:
+ case UMIN:
convert_op (&XEXP (src, 0), insn);
convert_op (&XEXP (src, 1), insn);
- PUT_MODE (src, V2DImode);
+ PUT_MODE (src, vmode);
break;
case NEG:
src = XEXP (src, 0);
convert_op (&src, insn);
- subreg = gen_reg_rtx (V2DImode);
- emit_insn_before (gen_move_insn (subreg, CONST0_RTX (V2DImode)), insn);
- src = gen_rtx_MINUS (V2DImode, subreg, src);
+ subreg = gen_reg_rtx (vmode);
+ emit_insn_before (gen_move_insn (subreg, CONST0_RTX (vmode)), insn);
+ src = gen_rtx_MINUS (vmode, subreg, src);
break;
case NOT:
src = XEXP (src, 0);
convert_op (&src, insn);
- subreg = gen_reg_rtx (V2DImode);
- emit_insn_before (gen_move_insn (subreg, CONSTM1_RTX (V2DImode)), insn);
- src = gen_rtx_XOR (V2DImode, src, subreg);
+ subreg = gen_reg_rtx (vmode);
+ emit_insn_before (gen_move_insn (subreg, CONSTM1_RTX (vmode)), insn);
+ src = gen_rtx_XOR (vmode, src, subreg);
break;
case MEM:
@@ -939,7 +1037,7 @@ dimode_scalar_chain::convert_insn (rtx_insn *insn)
break;
case SUBREG:
- gcc_assert (GET_MODE (src) == V2DImode);
+ gcc_assert (GET_MODE (src) == vmode);
break;
case COMPARE:
@@ -977,7 +1075,9 @@ dimode_scalar_chain::convert_insn (rtx_insn *insn)
PATTERN (insn) = def_set;
INSN_CODE (insn) = -1;
- recog_memoized (insn);
+ int patt = recog_memoized (insn);
+ if (patt == -1)
+ fatal_insn_not_found (insn);
df_insn_rescan (insn);
}
@@ -1116,7 +1216,7 @@ timode_scalar_chain::convert_insn (rtx_insn *insn)
}
void
-dimode_scalar_chain::convert_registers ()
+general_scalar_chain::convert_registers ()
{
bitmap_iterator bi;
unsigned id;
@@ -1186,8 +1286,12 @@ has_non_address_hard_reg (rtx_insn *insn)
(const_int 0 [0]))) */
static bool
-convertible_comparison_p (rtx_insn *insn)
+convertible_comparison_p (rtx_insn *insn, enum machine_mode mode)
{
+ /* ??? Currently convertible for double-word DImode chain only. */
+ if (TARGET_64BIT || mode != DImode)
+ return false;
+
if (!TARGET_SSE4_1)
return false;
@@ -1238,10 +1342,10 @@ convertible_comparison_p (rtx_insn *insn)
return true;
}
-/* The DImode version of scalar_to_vector_candidate_p. */
+/* The general version of scalar_to_vector_candidate_p. */
static bool
-dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
+general_scalar_to_vector_candidate_p (rtx_insn *insn, enum machine_mode mode)
{
rtx def_set = single_set (insn);
@@ -1255,12 +1359,12 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
rtx dst = SET_DEST (def_set);
if (GET_CODE (src) == COMPARE)
- return convertible_comparison_p (insn);
+ return convertible_comparison_p (insn, mode);
- /* We are interested in DImode promotion only. */
- if ((GET_MODE (src) != DImode
+ /* We are interested in "mode" only. */
+ if ((GET_MODE (src) != mode
&& !CONST_INT_P (src))
- || GET_MODE (dst) != DImode)
+ || GET_MODE (dst) != mode)
return false;
if (!REG_P (dst) && !MEM_P (dst))
@@ -1280,6 +1384,15 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
return false;
break;
+ case SMAX:
+ case SMIN:
+ case UMAX:
+ case UMIN:
+ if ((mode == DImode && !TARGET_AVX512VL)
+ || (mode == SImode && !TARGET_SSE4_1))
+ return false;
+ /* Fallthru. */
+
case PLUS:
case MINUS:
case IOR:
@@ -1290,7 +1403,7 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
&& !CONST_INT_P (XEXP (src, 1)))
return false;
- if (GET_MODE (XEXP (src, 1)) != DImode
+ if (GET_MODE (XEXP (src, 1)) != mode
&& !CONST_INT_P (XEXP (src, 1)))
return false;
break;
@@ -1319,7 +1432,7 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
|| !REG_P (XEXP (XEXP (src, 0), 0))))
return false;
- if (GET_MODE (XEXP (src, 0)) != DImode
+ if (GET_MODE (XEXP (src, 0)) != mode
&& !CONST_INT_P (XEXP (src, 0)))
return false;
@@ -1383,22 +1496,16 @@ timode_scalar_to_vector_candidate_p (rtx_insn *insn)
return false;
}
-/* Return 1 if INSN may be converted into vector
- instruction. */
-
-static bool
-scalar_to_vector_candidate_p (rtx_insn *insn)
-{
- if (TARGET_64BIT)
- return timode_scalar_to_vector_candidate_p (insn);
- else
- return dimode_scalar_to_vector_candidate_p (insn);
-}
+/* For a given bitmap of insn UIDs scans all instruction and
+ remove insn from CANDIDATES in case it has both convertible
+ and not convertible definitions.
-/* The DImode version of remove_non_convertible_regs. */
+ All insns in a bitmap are conversion candidates according to
+ scalar_to_vector_candidate_p. Currently it implies all insns
+ are single_set. */
static void
-dimode_remove_non_convertible_regs (bitmap candidates)
+general_remove_non_convertible_regs (bitmap candidates)
{
bitmap_iterator bi;
unsigned id;
@@ -1553,23 +1660,6 @@ timode_remove_non_convertible_regs (bitmap candidates)
BITMAP_FREE (regs);
}
-/* For a given bitmap of insn UIDs scans all instruction and
- remove insn from CANDIDATES in case it has both convertible
- and not convertible definitions.
-
- All insns in a bitmap are conversion candidates according to
- scalar_to_vector_candidate_p. Currently it implies all insns
- are single_set. */
-
-static void
-remove_non_convertible_regs (bitmap candidates)
-{
- if (TARGET_64BIT)
- timode_remove_non_convertible_regs (candidates);
- else
- dimode_remove_non_convertible_regs (candidates);
-}
-
/* Main STV pass function. Find and convert scalar
instructions into vector mode when profitable. */
@@ -1577,11 +1667,14 @@ static unsigned int
convert_scalars_to_vector ()
{
basic_block bb;
- bitmap candidates;
int converted_insns = 0;
bitmap_obstack_initialize (NULL);
- candidates = BITMAP_ALLOC (NULL);
+ const machine_mode cand_mode[3] = { SImode, DImode, TImode };
+ const machine_mode cand_vmode[3] = { V4SImode, V2DImode, V1TImode };
+ bitmap_head candidates[3]; /* { SImode, DImode, TImode } */
+ for (unsigned i = 0; i < 3; ++i)
+ bitmap_initialize (&candidates[i], &bitmap_default_obstack);
calculate_dominance_info (CDI_DOMINATORS);
df_set_flags (DF_DEFER_INSN_RESCAN);
@@ -1597,51 +1690,73 @@ convert_scalars_to_vector ()
{
rtx_insn *insn;
FOR_BB_INSNS (bb, insn)
- if (scalar_to_vector_candidate_p (insn))
+ if (TARGET_64BIT
+ && timode_scalar_to_vector_candidate_p (insn))
{
if (dump_file)
- fprintf (dump_file, " insn %d is marked as a candidate\n",
+ fprintf (dump_file, " insn %d is marked as a TImode candidate\n",
INSN_UID (insn));
- bitmap_set_bit (candidates, INSN_UID (insn));
+ bitmap_set_bit (&candidates[2], INSN_UID (insn));
+ }
+ else
+ {
+ /* Check {SI,DI}mode. */
+ for (unsigned i = 0; i <= 1; ++i)
+ if (general_scalar_to_vector_candidate_p (insn, cand_mode[i]))
+ {
+ if (dump_file)
+ fprintf (dump_file, " insn %d is marked as a %s candidate\n",
+ INSN_UID (insn), i == 0 ? "SImode" : "DImode");
+
+ bitmap_set_bit (&candidates[i], INSN_UID (insn));
+ break;
+ }
}
}
- remove_non_convertible_regs (candidates);
+ if (TARGET_64BIT)
+ timode_remove_non_convertible_regs (&candidates[2]);
+ for (unsigned i = 0; i <= 1; ++i)
+ general_remove_non_convertible_regs (&candidates[i]);
- if (bitmap_empty_p (candidates))
- if (dump_file)
+ for (unsigned i = 0; i <= 2; ++i)
+ if (!bitmap_empty_p (&candidates[i]))
+ break;
+ else if (i == 2 && dump_file)
fprintf (dump_file, "There are no candidates for optimization.\n");
- while (!bitmap_empty_p (candidates))
- {
- unsigned uid = bitmap_first_set_bit (candidates);
- scalar_chain *chain;
+ for (unsigned i = 0; i <= 2; ++i)
+ while (!bitmap_empty_p (&candidates[i]))
+ {
+ unsigned uid = bitmap_first_set_bit (&candidates[i]);
+ scalar_chain *chain;
- if (TARGET_64BIT)
- chain = new timode_scalar_chain;
- else
- chain = new dimode_scalar_chain;
+ if (cand_mode[i] == TImode)
+ chain = new timode_scalar_chain;
+ else
+ chain = new general_scalar_chain (cand_mode[i], cand_vmode[i]);
- /* Find instructions chain we want to convert to vector mode.
- Check all uses and definitions to estimate all required
- conversions. */
- chain->build (candidates, uid);
+ /* Find instructions chain we want to convert to vector mode.
+ Check all uses and definitions to estimate all required
+ conversions. */
+ chain->build (&candidates[i], uid);
- if (chain->compute_convert_gain () > 0)
- converted_insns += chain->convert ();
- else
- if (dump_file)
- fprintf (dump_file, "Chain #%d conversion is not profitable\n",
- chain->chain_id);
+ if (chain->compute_convert_gain () > 0)
+ converted_insns += chain->convert ();
+ else
+ if (dump_file)
+ fprintf (dump_file, "Chain #%d conversion is not profitable\n",
+ chain->chain_id);
- delete chain;
- }
+ delete chain;
+ }
if (dump_file)
fprintf (dump_file, "Total insns converted: %d\n", converted_insns);
- BITMAP_FREE (candidates);
+ for (unsigned i = 0; i <= 2; ++i)
+ bitmap_release (&candidates[i]);
bitmap_obstack_release (NULL);
df_process_deferred_rescans ();
diff --git a/gcc/config/i386/i386-features.h b/gcc/config/i386/i386-features.h
index f2c742f..c85ac45 100644
--- a/gcc/config/i386/i386-features.h
+++ b/gcc/config/i386/i386-features.h
@@ -127,11 +127,16 @@ namespace {
class scalar_chain
{
public:
- scalar_chain ();
+ scalar_chain (enum machine_mode, enum machine_mode);
virtual ~scalar_chain ();
static unsigned max_id;
+ /* Scalar mode. */
+ enum machine_mode smode;
+ /* Vector mode. */
+ enum machine_mode vmode;
+
/* ID of a chain. */
unsigned int chain_id;
/* A queue of instructions to be included into a chain. */
@@ -159,9 +164,11 @@ class scalar_chain
virtual void convert_registers () = 0;
};
-class dimode_scalar_chain : public scalar_chain
+class general_scalar_chain : public scalar_chain
{
public:
+ general_scalar_chain (enum machine_mode smode_, enum machine_mode vmode_)
+ : scalar_chain (smode_, vmode_) {}
int compute_convert_gain ();
private:
void mark_dual_mode_def (df_ref def);
@@ -178,6 +185,8 @@ class dimode_scalar_chain : public scalar_chain
class timode_scalar_chain : public scalar_chain
{
public:
+ timode_scalar_chain () : scalar_chain (TImode, V1TImode) {}
+
/* Convert from TImode to V1TImode is always faster. */
int compute_convert_gain () { return 1; }
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index e278d9c..647bcbe 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -4126,34 +4126,6 @@ ix86_setup_incoming_varargs (cumulative_args_t cum_v, machine_mode mode,
setup_incoming_varargs_64 (&next_cum);
}
-static void
-ix86_setup_incoming_vararg_bounds (cumulative_args_t cum_v,
- machine_mode mode,
- tree type,
- int *pretend_size ATTRIBUTE_UNUSED,
- int no_rtl)
-{
- CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
- CUMULATIVE_ARGS next_cum;
- tree fntype;
-
- gcc_assert (!no_rtl);
-
- /* Do nothing if we use plain pointer to argument area. */
- if (!TARGET_64BIT || cum->call_abi == MS_ABI)
- return;
-
- fntype = TREE_TYPE (current_function_decl);
-
- /* For varargs, we do not want to skip the dummy va_dcl argument.
- For stdargs, we do want to skip the last named argument. */
- next_cum = *cum;
- if (stdarg_p (fntype))
- ix86_function_arg_advance (pack_cumulative_args (&next_cum), mode, type,
- true);
-}
-
-
/* Checks if TYPE is of kind va_list char *. */
static bool
@@ -11445,7 +11417,7 @@ output_pic_addr_const (FILE *file, rtx x, int code)
break;
case SYMBOL_REF:
- if (TARGET_64BIT || ! TARGET_MACHO_PICSYM_STUBS)
+ if (TARGET_64BIT || ! TARGET_MACHO_SYMBOL_STUBS)
output_addr_const (file, x);
else
{
@@ -16817,8 +16789,8 @@ ix86_fold_builtin (tree fndecl, int n_args,
{
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
{
- enum ix86_builtins fn_code = (enum ix86_builtins)
- DECL_FUNCTION_CODE (fndecl);
+ enum ix86_builtins fn_code
+ = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
enum rtx_code rcode;
bool is_vshift;
unsigned HOST_WIDE_INT mask;
@@ -17283,7 +17255,8 @@ ix86_gimple_fold_builtin (gimple_stmt_iterator *gsi)
tree fndecl = gimple_call_fndecl (stmt);
gcc_checking_assert (fndecl && fndecl_built_in_p (fndecl, BUILT_IN_MD));
int n_args = gimple_call_num_args (stmt);
- enum ix86_builtins fn_code = (enum ix86_builtins) DECL_FUNCTION_CODE (fndecl);
+ enum ix86_builtins fn_code
+ = (enum ix86_builtins) DECL_MD_FUNCTION_CODE (fndecl);
tree decl = NULL_TREE;
tree arg0, arg1, arg2;
enum rtx_code rcode;
@@ -18491,8 +18464,10 @@ inline_memory_move_cost (machine_mode mode, enum reg_class regclass, int in)
return 100;
}
if (in == 2)
- return MAX (ix86_cost->fp_load [index], ix86_cost->fp_store [index]);
- return in ? ix86_cost->fp_load [index] : ix86_cost->fp_store [index];
+ return MAX (ix86_cost->hard_register.fp_load [index],
+ ix86_cost->hard_register.fp_store [index]);
+ return in ? ix86_cost->hard_register.fp_load [index]
+ : ix86_cost->hard_register.fp_store [index];
}
if (SSE_CLASS_P (regclass))
{
@@ -18500,8 +18475,10 @@ inline_memory_move_cost (machine_mode mode, enum reg_class regclass, int in)
if (index == -1)
return 100;
if (in == 2)
- return MAX (ix86_cost->sse_load [index], ix86_cost->sse_store [index]);
- return in ? ix86_cost->sse_load [index] : ix86_cost->sse_store [index];
+ return MAX (ix86_cost->hard_register.sse_load [index],
+ ix86_cost->hard_register.sse_store [index]);
+ return in ? ix86_cost->hard_register.sse_load [index]
+ : ix86_cost->hard_register.sse_store [index];
}
if (MMX_CLASS_P (regclass))
{
@@ -18518,8 +18495,10 @@ inline_memory_move_cost (machine_mode mode, enum reg_class regclass, int in)
return 100;
}
if (in == 2)
- return MAX (ix86_cost->mmx_load [index], ix86_cost->mmx_store [index]);
- return in ? ix86_cost->mmx_load [index] : ix86_cost->mmx_store [index];
+ return MAX (ix86_cost->hard_register.mmx_load [index],
+ ix86_cost->hard_register.mmx_store [index]);
+ return in ? ix86_cost->hard_register.mmx_load [index]
+ : ix86_cost->hard_register.mmx_store [index];
}
switch (GET_MODE_SIZE (mode))
{
@@ -18527,37 +18506,41 @@ inline_memory_move_cost (machine_mode mode, enum reg_class regclass, int in)
if (Q_CLASS_P (regclass) || TARGET_64BIT)
{
if (!in)
- return ix86_cost->int_store[0];
+ return ix86_cost->hard_register.int_store[0];
if (TARGET_PARTIAL_REG_DEPENDENCY
&& optimize_function_for_speed_p (cfun))
- cost = ix86_cost->movzbl_load;
+ cost = ix86_cost->hard_register.movzbl_load;
else
- cost = ix86_cost->int_load[0];
+ cost = ix86_cost->hard_register.int_load[0];
if (in == 2)
- return MAX (cost, ix86_cost->int_store[0]);
+ return MAX (cost, ix86_cost->hard_register.int_store[0]);
return cost;
}
else
{
if (in == 2)
- return MAX (ix86_cost->movzbl_load, ix86_cost->int_store[0] + 4);
+ return MAX (ix86_cost->hard_register.movzbl_load,
+ ix86_cost->hard_register.int_store[0] + 4);
if (in)
- return ix86_cost->movzbl_load;
+ return ix86_cost->hard_register.movzbl_load;
else
- return ix86_cost->int_store[0] + 4;
+ return ix86_cost->hard_register.int_store[0] + 4;
}
break;
case 2:
if (in == 2)
- return MAX (ix86_cost->int_load[1], ix86_cost->int_store[1]);
- return in ? ix86_cost->int_load[1] : ix86_cost->int_store[1];
+ return MAX (ix86_cost->hard_register.int_load[1],
+ ix86_cost->hard_register.int_store[1]);
+ return in ? ix86_cost->hard_register.int_load[1]
+ : ix86_cost->hard_register.int_store[1];
default:
if (in == 2)
- cost = MAX (ix86_cost->int_load[2], ix86_cost->int_store[2]);
+ cost = MAX (ix86_cost->hard_register.int_load[2],
+ ix86_cost->hard_register.int_store[2]);
else if (in)
- cost = ix86_cost->int_load[2];
+ cost = ix86_cost->hard_register.int_load[2];
else
- cost = ix86_cost->int_store[2];
+ cost = ix86_cost->hard_register.int_store[2];
/* Multiply with the number of GPR moves needed. */
return cost * CEIL ((int) GET_MODE_SIZE (mode), UNITS_PER_WORD);
}
@@ -18627,20 +18610,21 @@ ix86_register_move_cost (machine_mode mode, reg_class_t class1_i,
because of missing QImode and HImode moves to, from or between
MMX/SSE registers. */
return MAX (8, SSE_CLASS_P (class1)
- ? ix86_cost->sse_to_integer : ix86_cost->integer_to_sse);
+ ? ix86_cost->hard_register.sse_to_integer
+ : ix86_cost->hard_register.integer_to_sse);
if (MAYBE_FLOAT_CLASS_P (class1))
- return ix86_cost->fp_move;
+ return ix86_cost->hard_register.fp_move;
if (MAYBE_SSE_CLASS_P (class1))
{
if (GET_MODE_BITSIZE (mode) <= 128)
- return ix86_cost->xmm_move;
+ return ix86_cost->hard_register.xmm_move;
if (GET_MODE_BITSIZE (mode) <= 256)
- return ix86_cost->ymm_move;
- return ix86_cost->zmm_move;
+ return ix86_cost->hard_register.ymm_move;
+ return ix86_cost->hard_register.zmm_move;
}
if (MAYBE_MMX_CLASS_P (class1))
- return ix86_cost->mmx_move;
+ return ix86_cost->hard_register.mmx_move;
return 2;
}
@@ -23048,9 +23032,6 @@ ix86_run_selftests (void)
#undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
#define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
-#undef TARGET_SETUP_INCOMING_VARARG_BOUNDS
-#define TARGET_SETUP_INCOMING_VARARG_BOUNDS ix86_setup_incoming_vararg_bounds
-
#undef TARGET_OFFLOAD_OPTIONS
#define TARGET_OFFLOAD_OPTIONS \
ix86_offload_options
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index a2fcdd4..e0a77e1 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -237,9 +237,46 @@ struct stringop_algs
} size [MAX_STRINGOP_ALGS];
};
-/* Define the specific costs for a given cpu */
+/* Define the specific costs for a given cpu. NB: hard_register is used
+ by TARGET_REGISTER_MOVE_COST and TARGET_MEMORY_MOVE_COST to compute
+ hard register move costs by register allocator. Relative costs of
+ pseudo register load and store versus pseudo register moves in RTL
+ expressions for TARGET_RTX_COSTS can be different from relative
+ costs of hard registers to get the most efficient operations with
+ pseudo registers. */
struct processor_costs {
+ /* Costs used by register allocator. integer->integer register move
+ cost is 2. */
+ struct
+ {
+ const int movzbl_load; /* cost of loading using movzbl */
+ const int int_load[3]; /* cost of loading integer registers
+ in QImode, HImode and SImode relative
+ to reg-reg move (2). */
+ const int int_store[3]; /* cost of storing integer register
+ in QImode, HImode and SImode */
+ const int fp_move; /* cost of reg,reg fld/fst */
+ const int fp_load[3]; /* cost of loading FP register
+ in SFmode, DFmode and XFmode */
+ const int fp_store[3]; /* cost of storing FP register
+ in SFmode, DFmode and XFmode */
+ const int mmx_move; /* cost of moving MMX register. */
+ const int mmx_load[2]; /* cost of loading MMX register
+ in SImode and DImode */
+ const int mmx_store[2]; /* cost of storing MMX register
+ in SImode and DImode */
+ const int xmm_move; /* cost of moving XMM register. */
+ const int ymm_move; /* cost of moving XMM register. */
+ const int zmm_move; /* cost of moving XMM register. */
+ const int sse_load[5]; /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ const int sse_store[5]; /* cost of storing SSE register
+ in SImode, DImode and TImode. */
+ const int sse_to_integer; /* cost of moving SSE register to integer. */
+ const int integer_to_sse; /* cost of moving integer register to SSE. */
+ } hard_register;
+
const int add; /* cost of an add instruction */
const int lea; /* cost of a lea instruction */
const int shift_var; /* variable shift costs */
@@ -254,32 +291,20 @@ struct processor_costs {
const int large_insn; /* insns larger than this cost more */
const int move_ratio; /* The threshold of number of scalar
memory-to-memory move insns. */
- const int movzbl_load; /* cost of loading using movzbl */
const int int_load[3]; /* cost of loading integer registers
in QImode, HImode and SImode relative
to reg-reg move (2). */
const int int_store[3]; /* cost of storing integer register
in QImode, HImode and SImode */
- const int fp_move; /* cost of reg,reg fld/fst */
- const int fp_load[3]; /* cost of loading FP register
- in SFmode, DFmode and XFmode */
- const int fp_store[3]; /* cost of storing FP register
- in SFmode, DFmode and XFmode */
- const int mmx_move; /* cost of moving MMX register. */
- const int mmx_load[2]; /* cost of loading MMX register
- in SImode and DImode */
- const int mmx_store[2]; /* cost of storing MMX register
- in SImode and DImode */
- const int xmm_move, ymm_move, /* cost of moving XMM and YMM register. */
- zmm_move;
const int sse_load[5]; /* cost of loading SSE register
in 32bit, 64bit, 128bit, 256bit and 512bit */
- const int sse_unaligned_load[5];/* cost of unaligned load. */
const int sse_store[5]; /* cost of storing SSE register
- in SImode, DImode and TImode. */
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ const int sse_unaligned_load[5];/* cost of unaligned load. */
const int sse_unaligned_store[5];/* cost of unaligned store. */
+ const int xmm_move, ymm_move, /* cost of moving XMM and YMM register. */
+ zmm_move;
const int sse_to_integer; /* cost of moving SSE register to integer. */
- const int integer_to_sse; /* cost of moving integer register to SSE. */
const int gather_static, gather_per_elt; /* Cost of gather load is computed
as static + per_item * nelts. */
const int scatter_static, scatter_per_elt; /* Cost of gather store is
@@ -647,7 +672,7 @@ extern tree x86_mfence;
/* Replace MACH-O, ifdefs by in-line tests, where possible.
(a) Macros defined in config/i386/darwin.h */
#define TARGET_MACHO 0
-#define TARGET_MACHO_PICSYM_STUBS 0
+#define TARGET_MACHO_SYMBOL_STUBS 0
#define MACHOPIC_ATT_STUB 0
/* (b) Macros defined in config/darwin.h */
#define MACHO_DYNAMIC_NO_PIC_P 0
@@ -677,6 +702,12 @@ extern tree x86_mfence;
with the rounding mode forced to 53 bits. */
#define TARGET_96_ROUND_53_LONG_DOUBLE 0
+#ifndef SUBTARGET_DRIVER_SELF_SPECS
+# define SUBTARGET_DRIVER_SELF_SPECS ""
+#endif
+
+#define DRIVER_SELF_SPECS SUBTARGET_DRIVER_SELF_SPECS
+
/* -march=native handling only makes sense with compiler running on
an x86 or x86_64 chip. If changing this condition, also change
the condition in driver-i386.c. */
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 63f18d7..9951d46 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -2786,26 +2786,20 @@
(set_attr "bdver1_decode" "double")])
(define_expand "movstrict<mode>"
- [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
+ [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
(match_operand:SWI12 1 "general_operand"))]
- ""
+ "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
{
- if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
+ gcc_assert (SUBREG_P (operands[0]));
+ if (GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
FAIL;
- if (SUBREG_P (operands[0])
- && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
- FAIL;
- /* Don't generate memory->memory moves, go through a register */
- if (MEM_P (operands[0]) && MEM_P (operands[1]))
- operands[1] = force_reg (<MODE>mode, operands[1]);
})
(define_insn "*movstrict<mode>_1"
[(set (strict_low_part
- (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
- (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
- "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+ (match_operand:SWI12 0 "register_operand" "+<r>"))
+ (match_operand:SWI12 1 "general_operand" "<r>mn"))]
+ "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
"mov{<imodesuffix>}\t{%1, %0|%0, %1}"
[(set_attr "type" "imov")
(set_attr "mode" "<MODE>")])
@@ -4011,8 +4005,10 @@
ix86_expand_clear (operands[0]);
gcc_assert (!TARGET_PARTIAL_REG_STALL);
- emit_insn (gen_movstrict<mode>
- (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
+ emit_insn (gen_rtx_SET
+ (gen_rtx_STRICT_LOW_PART
+ (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
+ operands[1]));
DONE;
}
@@ -4063,8 +4059,10 @@
ix86_expand_clear (operands[0]);
gcc_assert (!TARGET_PARTIAL_REG_STALL);
- emit_insn (gen_movstrictqi
- (gen_lowpart (QImode, operands[0]), operands[1]));
+ emit_insn (gen_rtx_SET
+ (gen_rtx_STRICT_LOW_PART
+ (VOIDmode, gen_lowpart (QImode, operands[0])),
+ operands[1]));
DONE;
}
@@ -9339,13 +9337,10 @@
[(set_attr "type" "negnot")
(set_attr "mode" "<MODE>")])
-;; Combine is quite creative about this pattern.
(define_insn "*negsi2_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
- (lshiftrt:DI
- (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
- (const_int 32)))
- (const_int 32)))
+ (zero_extend:DI
+ (neg:SI (match_operand:SI 1 "register_operand" "0"))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
"neg{l}\t%k0"
@@ -9371,16 +9366,11 @@
(define_insn "*negsi2_cmpz_zext"
[(set (reg:CCZ FLAGS_REG)
(compare:CCZ
- (lshiftrt:DI
- (neg:DI (ashift:DI
- (match_operand:DI 1 "register_operand" "0")
- (const_int 32)))
- (const_int 32))
+ (neg:SI (match_operand:SI 1 "register_operand" "0"))
(const_int 0)))
(set (match_operand:DI 0 "register_operand" "=r")
- (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
- (const_int 32)))
- (const_int 32)))]
+ (zero_extend:DI
+ (neg:SI (match_dup 1))))]
"TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
"neg{l}\t%k0"
[(set_attr "type" "negnot")
@@ -9700,7 +9690,6 @@
[(set_attr "type" "negnot")
(set_attr "mode" "<MODE>")])
-;; ??? Currently never generated - xor is used instead.
(define_insn "*one_cmplsi2_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
@@ -9751,7 +9740,6 @@
(set (match_dup 1)
(xor:SWI (match_dup 3) (const_int -1)))])])
-;; ??? Currently never generated - xor is used instead.
(define_insn "*one_cmplsi2_2_zext"
[(set (reg FLAGS_REG)
(compare (not:SI (match_operand:SI 1 "register_operand" "0"))
@@ -11835,7 +11823,7 @@
(set_attr "mode" "QI")])
(define_insn "*setcc_qi_slp"
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
+ [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
(match_operator:QI 1 "ix86_comparison_operator"
[(reg FLAGS_REG) (const_int 0)]))]
""
@@ -11864,7 +11852,7 @@
})
(define_split
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
+ [(set (strict_low_part (match_operand:QI 0 "register_operand"))
(ne:QI (match_operator 1 "ix86_comparison_operator"
[(reg FLAGS_REG) (const_int 0)])
(const_int 0)))]
@@ -11896,7 +11884,7 @@
})
(define_split
- [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
+ [(set (strict_low_part (match_operand:QI 0 "register_operand"))
(eq:QI (match_operator 1 "ix86_comparison_operator"
[(reg FLAGS_REG) (const_int 0)])
(const_int 0)))]
@@ -17731,6 +17719,110 @@
(match_operand:SWI 3 "const_int_operand")]
""
"if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
+
+;; min/max patterns
+
+(define_mode_iterator MAXMIN_IMODE
+ [(SI "TARGET_SSE4_1") (DI "TARGET_AVX512VL")])
+(define_code_attr maxmin_rel
+ [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
+
+(define_expand "<code><mode>3"
+ [(parallel
+ [(set (match_operand:MAXMIN_IMODE 0 "register_operand")
+ (maxmin:MAXMIN_IMODE
+ (match_operand:MAXMIN_IMODE 1 "register_operand")
+ (match_operand:MAXMIN_IMODE 2 "nonimmediate_operand")))
+ (clobber (reg:CC FLAGS_REG))])]
+ "TARGET_STV")
+
+(define_insn_and_split "*<code><mode>3_1"
+ [(set (match_operand:MAXMIN_IMODE 0 "register_operand")
+ (maxmin:MAXMIN_IMODE
+ (match_operand:MAXMIN_IMODE 1 "register_operand")
+ (match_operand:MAXMIN_IMODE 2 "nonimmediate_operand")))
+ (clobber (reg:CC FLAGS_REG))]
+ "(TARGET_64BIT || <MODE>mode != DImode) && TARGET_STV
+ && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (if_then_else:MAXMIN_IMODE (match_dup 3)
+ (match_dup 1)
+ (match_dup 2)))]
+{
+ machine_mode mode = <MODE>mode;
+
+ if (!register_operand (operands[2], mode))
+ operands[2] = force_reg (mode, operands[2]);
+
+ enum rtx_code code = <maxmin_rel>;
+ machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], operands[2]);
+ rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
+
+ rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], operands[2]);
+ emit_insn (gen_rtx_SET (flags, tmp));
+
+ operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
+})
+
+(define_insn_and_split "*<code>di3_doubleword"
+ [(set (match_operand:DI 0 "register_operand")
+ (maxmin:DI (match_operand:DI 1 "register_operand")
+ (match_operand:DI 2 "nonimmediate_operand")))
+ (clobber (reg:CC FLAGS_REG))]
+ "!TARGET_64BIT && TARGET_STV && TARGET_AVX512VL
+ && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (if_then_else:SI (match_dup 6)
+ (match_dup 1)
+ (match_dup 2)))
+ (set (match_dup 3)
+ (if_then_else:SI (match_dup 6)
+ (match_dup 4)
+ (match_dup 5)))]
+{
+ if (!register_operand (operands[2], DImode))
+ operands[2] = force_reg (DImode, operands[2]);
+
+ split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
+
+ rtx cmplo[2] = { operands[1], operands[2] };
+ rtx cmphi[2] = { operands[4], operands[5] };
+
+ enum rtx_code code = <maxmin_rel>;
+
+ switch (code)
+ {
+ case LE: case LEU:
+ std::swap (cmplo[0], cmplo[1]);
+ std::swap (cmphi[0], cmphi[1]);
+ code = swap_condition (code);
+ /* FALLTHRU */
+
+ case GE: case GEU:
+ {
+ bool uns = (code == GEU);
+ rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
+ = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
+
+ emit_insn (gen_cmp_1 (SImode, cmplo[0], cmplo[1]));
+
+ rtx tmp = gen_rtx_SCRATCH (SImode);
+ emit_insn (sbb_insn (SImode, tmp, cmphi[0], cmphi[1]));
+
+ rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
+ operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
+
+ break;
+ }
+
+ default:
+ gcc_unreachable ();
+ }
+})
;; Misc patterns (?)
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index c78b33b..c9cad04 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -58,6 +58,9 @@
;; Mapping from integer vector mode to mnemonic suffix
(define_mode_attr mmxvecsize [(V8QI "b") (V4HI "w") (V2SI "d") (V1DI "q")])
+(define_mode_attr mmxdoublemode
+ [(V8QI "V8HI") (V4HI "V4SI")])
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Move patterns
@@ -1394,6 +1397,36 @@
(set_attr "type" "mmxcvt,sselog,sselog")
(set_attr "mode" "DI,TI,TI")])
+(define_insn "*mmx_pinsrd"
+ [(set (match_operand:V2SI 0 "register_operand" "=x,Yv")
+ (vec_merge:V2SI
+ (vec_duplicate:V2SI
+ (match_operand:SI 2 "nonimmediate_operand" "rm,rm"))
+ (match_operand:V2SI 1 "register_operand" "0,Yv")
+ (match_operand:SI 3 "const_int_operand")))]
+ "TARGET_MMX_WITH_SSE && TARGET_SSE4_1
+ && ((unsigned) exact_log2 (INTVAL (operands[3]))
+ < GET_MODE_NUNITS (V2SImode))"
+{
+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
+ switch (which_alternative)
+ {
+ case 1:
+ return "vpinsrd\t{%3, %2, %1, %0|%0, %1, %2, %3}";
+ case 0:
+ return "pinsrd\t{%3, %2, %0|%0, %2, %3}";
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "isa" "noavx,avx")
+ (set_attr "prefix_data16" "1")
+ (set_attr "prefix_extra" "1")
+ (set_attr "type" "sselog")
+ (set_attr "length_immediate" "1")
+ (set_attr "prefix" "orig,vex")
+ (set_attr "mode" "TI")])
+
(define_expand "mmx_pinsrw"
[(set (match_operand:V4HI 0 "register_operand")
(vec_merge:V4HI
@@ -1444,23 +1477,109 @@
(set_attr "length_immediate" "1")
(set_attr "mode" "DI,TI,TI")])
-(define_insn "mmx_pextrw"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI
+(define_insn "*mmx_pinsrb"
+ [(set (match_operand:V8QI 0 "register_operand" "=x,Yv")
+ (vec_merge:V8QI
+ (vec_duplicate:V8QI
+ (match_operand:QI 2 "nonimmediate_operand" "rm,rm"))
+ (match_operand:V8QI 1 "register_operand" "0,Yv")
+ (match_operand:SI 3 "const_int_operand")))]
+ "TARGET_MMX_WITH_SSE && TARGET_SSE4_1
+ && ((unsigned) exact_log2 (INTVAL (operands[3]))
+ < GET_MODE_NUNITS (V8QImode))"
+{
+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[3])));
+ switch (which_alternative)
+ {
+ case 1:
+ if (MEM_P (operands[2]))
+ return "vpinsrb\t{%3, %2, %1, %0|%0, %1, %2, %3}";
+ else
+ return "vpinsrb\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
+ case 0:
+ if (MEM_P (operands[2]))
+ return "pinsrb\t{%3, %2, %0|%0, %2, %3}";
+ else
+ return "pinsrb\t{%3, %k2, %0|%0, %k2, %3}";
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "isa" "noavx,avx")
+ (set_attr "type" "sselog")
+ (set_attr "prefix_data16" "1")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
+ (set_attr "prefix" "orig,vex")
+ (set_attr "mode" "TI")])
+
+(define_insn "*mmx_pextrw"
+ [(set (match_operand:HI 0 "register_sse4nonimm_operand" "=r,r,m")
+ (vec_select:HI
+ (match_operand:V4HI 1 "register_operand" "y,Yv,Yv")
+ (parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n,n")])))]
+ "(TARGET_MMX || TARGET_MMX_WITH_SSE)
+ && (TARGET_SSE || TARGET_3DNOW_A)"
+ "@
+ pextrw\t{%2, %1, %k0|%k0, %1, %2}
+ %vpextrw\t{%2, %1, %k0|%k0, %1, %2}
+ %vpextrw\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "isa" "*,sse2,sse4")
+ (set_attr "mmx_isa" "native,*,*")
+ (set_attr "type" "mmxcvt,sselog1,sselog1")
+ (set_attr "length_immediate" "1")
+ (set_attr "prefix" "orig,maybe_vex,maybe_vex")
+ (set_attr "mode" "DI,TI,TI")])
+
+(define_insn "*mmx_pextrw_zext"
+ [(set (match_operand:SWI48 0 "register_operand" "=r,r")
+ (zero_extend:SWI48
(vec_select:HI
(match_operand:V4HI 1 "register_operand" "y,Yv")
(parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n")]))))]
"(TARGET_MMX || TARGET_MMX_WITH_SSE)
&& (TARGET_SSE || TARGET_3DNOW_A)"
"@
- pextrw\t{%2, %1, %0|%0, %1, %2}
- %vpextrw\t{%2, %1, %0|%0, %1, %2}"
+ pextrw\t{%2, %1, %k0|%k0, %1, %2}
+ %vpextrw\t{%2, %1, %k0|%k0, %1, %2}"
[(set_attr "isa" "*,sse2")
(set_attr "mmx_isa" "native,*")
(set_attr "type" "mmxcvt,sselog1")
(set_attr "length_immediate" "1")
+ (set_attr "prefix" "orig,maybe_vex")
(set_attr "mode" "DI,TI")])
+(define_insn "*mmx_pextrb"
+ [(set (match_operand:QI 0 "nonimmediate_operand" "=r,m")
+ (vec_select:QI
+ (match_operand:V8QI 1 "register_operand" "Yv,Yv")
+ (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n,n")])))]
+ "TARGET_MMX_WITH_SSE && TARGET_SSE4_1"
+ "@
+ %vpextrb\t{%2, %1, %k0|%k0, %1, %2}
+ %vpextrb\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "type" "sselog1")
+ (set_attr "prefix_data16" "1")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
+ (set_attr "prefix" "maybe_vex")
+ (set_attr "mode" "TI")])
+
+(define_insn "*mmx_pextrb_zext"
+ [(set (match_operand:SWI248 0 "register_operand" "=r")
+ (zero_extend:SWI248
+ (vec_select:QI
+ (match_operand:V8QI 1 "register_operand" "Yv")
+ (parallel [(match_operand:SI 2 "const_0_to_7_operand" "n")]))))]
+ "TARGET_MMX_WITH_SSE && TARGET_SSE4_1"
+ "%vpextrb\t{%2, %1, %k0|%k0, %1, %2}"
+ [(set_attr "type" "sselog1")
+ (set_attr "prefix_data16" "1")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
+ (set_attr "prefix" "maybe_vex")
+ (set_attr "mode" "TI")])
+
(define_expand "mmx_pshufw"
[(match_operand:V4HI 0 "register_operand")
(match_operand:V4HI 1 "register_mmxmem_operand")
@@ -1620,9 +1739,9 @@
;; Avoid combining registers from different units in a single alternative,
;; see comment above inline_secondary_memory_needed function in i386.c
(define_insn_and_split "*vec_extractv2si_0"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r")
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=x,m,y, m,r,r")
(vec_select:SI
- (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m")
+ (match_operand:V2SI 1 "nonimmediate_operand" "xm,x,ym,y,m,x")
(parallel [(const_int 0)])))]
"(TARGET_MMX || TARGET_MMX_WITH_SSE)
&& !(MEM_P (operands[0]) && MEM_P (operands[1]))"
@@ -1630,33 +1749,76 @@
"&& reload_completed"
[(set (match_dup 0) (match_dup 1))]
"operands[1] = gen_lowpart (SImode, operands[1]);"
- [(set_attr "mmx_isa" "*,*,native,native,*")])
+ [(set_attr "isa" "*,*,*,*,*,sse2")
+ (set_attr "mmx_isa" "*,*,native,native,*,*")
+ (set (attr "preferred_for_speed")
+ (cond [(eq_attr "alternative" "5")
+ (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
+ ]
+ (symbol_ref "true")))])
+
+(define_insn "*vec_extractv2si_0_zext_sse4"
+ [(set (match_operand:DI 0 "register_operand" "=r,x")
+ (zero_extend:DI
+ (vec_select:SI
+ (match_operand:V2SI 1 "register_operand" "x,x")
+ (parallel [(const_int 0)]))))]
+ "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_SSE4_1"
+ "#"
+ [(set_attr "isa" "x64,*")
+ (set (attr "preferred_for_speed")
+ (cond [(eq_attr "alternative" "0")
+ (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
+ ]
+ (symbol_ref "true")))])
+
+(define_insn "*vec_extractv2si_0_zext"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (vec_select:SI
+ (match_operand:V2SI 1 "register_operand" "x")
+ (parallel [(const_int 0)]))))]
+ "(TARGET_MMX || TARGET_MMX_WITH_SSE)
+ && TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_FROM_VEC"
+ "#")
+
+(define_split
+ [(set (match_operand:DI 0 "register_operand")
+ (zero_extend:DI
+ (vec_select:SI
+ (match_operand:V2SI 1 "register_operand")
+ (parallel [(const_int 0)]))))]
+ "(TARGET_MMX || TARGET_MMX_WITH_SSE)
+ && TARGET_SSE2 && reload_completed"
+ [(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
+ "operands[1] = gen_lowpart (SImode, operands[1]);")
;; Avoid combining registers from different units in a single alternative,
;; see comment above inline_secondary_memory_needed function in i386.c
(define_insn "*vec_extractv2si_1"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=y,x,x,y,x,r")
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=y,rm,x,x,y,x,r")
(vec_select:SI
- (match_operand:V2SI 1 "nonimmediate_operand" " 0,x,x,o,o,o")
+ (match_operand:V2SI 1 "nonimmediate_operand" " 0,x ,x,x,o,o,o")
(parallel [(const_int 1)])))]
"(TARGET_MMX || TARGET_MMX_WITH_SSE)
&& !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"@
punpckhdq\t%0, %0
+ %vpextrd\t{$1, %1, %0|%0, %1, 1}
%vpshufd\t{$0xe5, %1, %0|%0, %1, 0xe5}
shufps\t{$0xe5, %1, %0|%0, %1, 0xe5}
#
#
#"
- [(set_attr "isa" "*,sse2,noavx,*,*,*")
- (set_attr "mmx_isa" "native,*,*,native,*,*")
- (set_attr "type" "mmxcvt,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
+ [(set_attr "isa" "*,sse4,sse2,noavx,*,*,*")
+ (set_attr "mmx_isa" "native,*,*,*,native,*,*")
+ (set_attr "type" "mmxcvt,ssemov,sseshuf1,sseshuf1,mmxmov,ssemov,imov")
(set (attr "length_immediate")
- (if_then_else (eq_attr "alternative" "1,2")
+ (if_then_else (eq_attr "alternative" "1,2,3")
(const_string "1")
(const_string "*")))
- (set_attr "prefix" "orig,maybe_vex,orig,orig,orig,orig")
- (set_attr "mode" "DI,TI,V4SF,SI,SI,SI")])
+ (set_attr "prefix" "orig,maybe_vex,maybe_vex,orig,orig,orig,orig")
+ (set_attr "mode" "DI,TI,TI,V4SF,SI,SI,SI")])
(define_split
[(set (match_operand:SI 0 "register_operand")
@@ -1667,13 +1829,28 @@
[(set (match_dup 0) (match_dup 1))]
"operands[1] = adjust_address (operands[1], SImode, 4);")
+(define_insn "*vec_extractv2si_1_zext"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (zero_extend:DI
+ (vec_select:SI
+ (match_operand:V2SI 1 "register_operand" "x")
+ (parallel [(const_int 1)]))))]
+ "(TARGET_MMX || TARGET_MMX_WITH_SSE)
+ && TARGET_64BIT && TARGET_SSE4_1"
+ "%vpextrd\t{$1, %1, %k0|%k0, %1, 1}"
+ [(set_attr "type" "sselog1")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
+ (set_attr "prefix" "maybe_vex")
+ (set_attr "mode" "TI")])
+
(define_insn_and_split "*vec_extractv2si_zext_mem"
[(set (match_operand:DI 0 "register_operand" "=y,x,r")
(zero_extend:DI
(vec_select:SI
(match_operand:V2SI 1 "memory_operand" "o,o,o")
(parallel [(match_operand:SI 2 "const_0_to_1_operand")]))))]
- "TARGET_64BIT"
+ "(TARGET_MMX || TARGET_MMX_WITH_SSE) && TARGET_64BIT"
"#"
"&& reload_completed"
[(set (match_dup 0) (zero_extend:DI (match_dup 1)))]
@@ -1774,24 +1951,24 @@
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(define_expand "mmx_uavgv8qi3"
- [(set (match_operand:V8QI 0 "register_operand")
- (truncate:V8QI
- (lshiftrt:V8HI
- (plus:V8HI
- (plus:V8HI
- (zero_extend:V8HI
- (match_operand:V8QI 1 "register_mmxmem_operand"))
- (zero_extend:V8HI
- (match_operand:V8QI 2 "register_mmxmem_operand")))
- (const_vector:V8HI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
+(define_expand "mmx_uavg<mode>3"
+ [(set (match_operand:MMXMODE12 0 "register_operand")
+ (truncate:MMXMODE12
+ (lshiftrt:<mmxdoublemode>
+ (plus:<mmxdoublemode>
+ (plus:<mmxdoublemode>
+ (zero_extend:<mmxdoublemode>
+ (match_operand:MMXMODE12 1 "register_mmxmem_operand"))
+ (zero_extend:<mmxdoublemode>
+ (match_operand:MMXMODE12 2 "register_mmxmem_operand")))
+ (match_dup 3))
(const_int 1))))]
"(TARGET_MMX || TARGET_MMX_WITH_SSE)
&& (TARGET_SSE || TARGET_3DNOW)"
- "ix86_fixup_binary_operands_no_copy (PLUS, V8QImode, operands);")
+{
+ operands[3] = CONST1_RTX(<mmxdoublemode>mode);
+ ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
+})
(define_insn "*mmx_uavgv8qi3"
[(set (match_operand:V8QI 0 "register_operand" "=y,x,Yv")
@@ -1810,7 +1987,7 @@
(const_int 1))))]
"(TARGET_MMX || TARGET_MMX_WITH_SSE)
&& (TARGET_SSE || TARGET_3DNOW)
- && ix86_binary_operator_ok (PLUS, V8QImode, operands)"
+ && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
{
switch (which_alternative)
{
@@ -1839,23 +2016,6 @@
(const_string "*")))
(set_attr "mode" "DI,TI,TI")])
-(define_expand "mmx_uavgv4hi3"
- [(set (match_operand:V4HI 0 "register_operand")
- (truncate:V4HI
- (lshiftrt:V4SI
- (plus:V4SI
- (plus:V4SI
- (zero_extend:V4SI
- (match_operand:V4HI 1 "register_mmxmem_operand"))
- (zero_extend:V4SI
- (match_operand:V4HI 2 "register_mmxmem_operand")))
- (const_vector:V4SI [(const_int 1) (const_int 1)
- (const_int 1) (const_int 1)]))
- (const_int 1))))]
- "(TARGET_MMX || TARGET_MMX_WITH_SSE)
- && (TARGET_SSE || TARGET_3DNOW_A)"
- "ix86_fixup_binary_operands_no_copy (PLUS, V4HImode, operands);")
-
(define_insn "*mmx_uavgv4hi3"
[(set (match_operand:V4HI 0 "register_operand" "=y,x,Yv")
(truncate:V4HI
@@ -1871,7 +2031,7 @@
(const_int 1))))]
"(TARGET_MMX || TARGET_MMX_WITH_SSE)
&& (TARGET_SSE || TARGET_3DNOW_A)
- && ix86_binary_operator_ok (PLUS, V4HImode, operands)"
+ && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
"@
pavgw\t{%2, %0|%0, %2}
pavgw\t{%2, %0|%0, %2}
@@ -1881,6 +2041,24 @@
(set_attr "type" "mmxshft,sseiadd,sseiadd")
(set_attr "mode" "DI,TI,TI")])
+(define_expand "uavg<mode>3_ceil"
+ [(set (match_operand:MMXMODE12 0 "register_operand")
+ (truncate:MMXMODE12
+ (lshiftrt:<mmxdoublemode>
+ (plus:<mmxdoublemode>
+ (plus:<mmxdoublemode>
+ (zero_extend:<mmxdoublemode>
+ (match_operand:MMXMODE12 1 "register_operand"))
+ (zero_extend:<mmxdoublemode>
+ (match_operand:MMXMODE12 2 "register_operand")))
+ (match_dup 3))
+ (const_int 1))))]
+ "TARGET_MMX_WITH_SSE"
+{
+ operands[3] = CONST1_RTX(<mmxdoublemode>mode);
+ ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
+})
+
(define_insn "mmx_psadbw"
[(set (match_operand:V1DI 0 "register_operand" "=y,x,Yv")
(unspec:V1DI [(match_operand:V8QI 1 "register_operand" "0,0,Yv")
@@ -1897,6 +2075,36 @@
(set_attr "type" "mmxshft,sseiadd,sseiadd")
(set_attr "mode" "DI,TI,TI")])
+(define_expand "reduc_plus_scal_v8qi"
+ [(plus:V8QI
+ (match_operand:QI 0 "register_operand")
+ (match_operand:V8QI 1 "register_operand"))]
+ "TARGET_MMX_WITH_SSE"
+{
+ rtx tmp = gen_reg_rtx (V8QImode);
+ emit_move_insn (tmp, CONST0_RTX (V8QImode));
+ rtx tmp2 = gen_reg_rtx (V1DImode);
+ emit_insn (gen_mmx_psadbw (tmp2, operands[1], tmp));
+ tmp2 = gen_lowpart (V8QImode, tmp2);
+ emit_insn (gen_vec_extractv8qiqi (operands[0], tmp2, const0_rtx));
+ DONE;
+})
+
+(define_expand "usadv8qi"
+ [(match_operand:V2SI 0 "register_operand")
+ (match_operand:V8QI 1 "register_operand")
+ (match_operand:V8QI 2 "register_operand")
+ (match_operand:V2SI 3 "register_operand")]
+ "TARGET_MMX_WITH_SSE"
+{
+ rtx t1 = gen_reg_rtx (V1DImode);
+ rtx t2 = gen_reg_rtx (V2SImode);
+ emit_insn (gen_mmx_psadbw (t1, operands[1], operands[2]));
+ convert_move (t2, t1, 0);
+ emit_insn (gen_addv2si3 (operands[0], t2, operands[3]));
+ DONE;
+})
+
(define_insn_and_split "mmx_pmovmskb"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(unspec:SI [(match_operand:V8QI 1 "register_operand" "y,x")]
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index fa8f13f..7bef939 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -2728,9 +2728,30 @@
DONE;
})
+(define_expand "reduc_plus_scal_v16qi"
+ [(plus:V16QI
+ (match_operand:QI 0 "register_operand")
+ (match_operand:V16QI 1 "register_operand"))]
+ "TARGET_SSE2"
+{
+ rtx tmp = gen_reg_rtx (V1TImode);
+ emit_insn (gen_sse2_lshrv1ti3 (tmp, gen_lowpart (V1TImode, operands[1]),
+ GEN_INT (64)));
+ rtx tmp2 = gen_reg_rtx (V16QImode);
+ emit_insn (gen_addv16qi3 (tmp2, operands[1], gen_lowpart (V16QImode, tmp)));
+ rtx tmp3 = gen_reg_rtx (V16QImode);
+ emit_move_insn (tmp3, CONST0_RTX (V16QImode));
+ rtx tmp4 = gen_reg_rtx (V2DImode);
+ emit_insn (gen_sse2_psadbw (tmp4, tmp2, tmp3));
+ tmp4 = gen_lowpart (V16QImode, tmp4);
+ emit_insn (gen_vec_extractv16qiqi (operands[0], tmp4, const0_rtx));
+ DONE;
+})
+
(define_mode_iterator REDUC_PLUS_MODE
[(V4DF "TARGET_AVX") (V8SF "TARGET_AVX")
- (V8DF "TARGET_AVX512F") (V16SF "TARGET_AVX512F")])
+ (V8DF "TARGET_AVX512F") (V16SF "TARGET_AVX512F")
+ (V32QI "TARGET_AVX") (V64QI "TARGET_AVX512F")])
(define_expand "reduc_plus_scal_<mode>"
[(plus:REDUC_PLUS_MODE
@@ -2741,8 +2762,8 @@
rtx tmp = gen_reg_rtx (<ssehalfvecmode>mode);
emit_insn (gen_vec_extract_hi_<mode> (tmp, operands[1]));
rtx tmp2 = gen_reg_rtx (<ssehalfvecmode>mode);
- emit_insn (gen_add<ssehalfvecmodelower>3
- (tmp2, tmp, gen_lowpart (<ssehalfvecmode>mode, operands[1])));
+ rtx tmp3 = gen_lowpart (<ssehalfvecmode>mode, operands[1]);
+ emit_insn (gen_add<ssehalfvecmodelower>3 (tmp2, tmp, tmp3));
emit_insn (gen_reduc_plus_scal_<ssehalfvecmodelower> (operands[0], tmp2));
DONE;
})
@@ -11879,7 +11900,7 @@
(const_int 1))))]
"TARGET_SSE2"
{
- operands[3] = CONST1_RTX(<MODE>mode);
+ operands[3] = CONST1_RTX(<ssedoublemode>mode);
ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
})
@@ -14949,6 +14970,25 @@
(set_attr "prefix" "maybe_vex")
(set_attr "mode" "TI")])
+(define_insn "*vec_extractv16qi_zext"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (zero_extend:HI
+ (vec_select:QI
+ (match_operand:V16QI 1 "register_operand" "x,v")
+ (parallel
+ [(match_operand:SI 2 "const_0_to_15_operand")]))))]
+ "TARGET_SSE4_1"
+ "@
+ %vpextrb\t{%2, %1, %k0|%k0, %1, %2}
+ vpextrb\t{%2, %1, %k0|%k0, %1, %2}"
+ [(set_attr "isa" "*,avx512bw")
+ (set_attr "type" "sselog1")
+ (set_attr "prefix_data16" "1")
+ (set_attr "prefix_extra" "1")
+ (set_attr "length_immediate" "1")
+ (set_attr "prefix" "maybe_vex")
+ (set_attr "mode" "TI")])
+
(define_insn "*vec_extract<mode>_mem"
[(set (match_operand:<ssescalarmode> 0 "register_operand" "=r")
(vec_select:<ssescalarmode>
@@ -15601,7 +15641,7 @@
(const_int 1))))]
"TARGET_SSE2 && <mask_mode512bit_condition> && <mask_avx512bw_condition>"
{
- operands[<mask_expand_op3>] = CONST1_RTX(<MODE>mode);
+ operands[<mask_expand_op3>] = CONST1_RTX(<ssedoublemode>mode);
ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
})
@@ -15615,7 +15655,7 @@
(match_operand:VI12_AVX2 1 "vector_operand" "%0,v"))
(zero_extend:<ssedoublemode>
(match_operand:VI12_AVX2 2 "vector_operand" "xBm,vm")))
- (match_operand:VI12_AVX2 <mask_expand_op3> "const1_operand"))
+ (match_operand:<ssedoublemode> <mask_expand_op3> "const1_operand"))
(const_int 1))))]
"TARGET_SSE2 && <mask_mode512bit_condition> && <mask_avx512bw_condition>
&& !(MEM_P (operands[1]) && MEM_P (operands[2]))"
diff --git a/gcc/config/i386/t-darwin b/gcc/config/i386/t-darwin32-biarch
index bf44504..bf44504 100644
--- a/gcc/config/i386/t-darwin
+++ b/gcc/config/i386/t-darwin32-biarch
diff --git a/gcc/config/i386/t-darwin64 b/gcc/config/i386/t-darwin64-biarch
index 6a6b22f..6a6b22f 100644
--- a/gcc/config/i386/t-darwin64
+++ b/gcc/config/i386/t-darwin64-biarch
diff --git a/gcc/config/i386/x86-tune-costs.h b/gcc/config/i386/x86-tune-costs.h
index 8b963c0..ad9ea4b 100644
--- a/gcc/config/i386/x86-tune-costs.h
+++ b/gcc/config/i386/x86-tune-costs.h
@@ -36,6 +36,30 @@ static stringop_algs ix86_size_memset[2] = {
const
struct processor_costs ix86_size_cost = {/* costs for tuning for size */
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 2, /* cost for loading QImode using movzbl */
+ {2, 2, 2}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {2, 2, 2}, /* cost of storing integer registers */
+ 2, /* cost of reg,reg fld/fst */
+ {2, 2, 2}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {2, 2, 2}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 3, /* cost of moving MMX register */
+ {3, 3}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {3, 3}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 3, 3, 3, /* cost of moving XMM,YMM,ZMM register */
+ {3, 3, 3, 3, 3}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {3, 3, 3, 3, 3}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 3, 3, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_BYTES (2), /* cost of an add instruction */
COSTS_N_BYTES (3), /* cost of a lea instruction */
COSTS_N_BYTES (2), /* variable shift costs */
@@ -55,33 +79,20 @@ struct processor_costs ix86_size_cost = {/* costs for tuning for size */
COSTS_N_BYTES (3), /* cost of movzx */
0, /* "large" insn */
2, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2. */
- 2, /* cost for loading QImode using movzbl */
{2, 2, 2}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{2, 2, 2}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {2, 2, 2}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {2, 2, 2}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 3, /* cost of moving MMX register */
- {3, 3}, /* cost of loading MMX registers
- in SImode and DImode */
- {3, 3}, /* cost of storing MMX registers
- in SImode and DImode */
- 3, 3, 3, /* cost of moving XMM,YMM,ZMM register */
- {3, 3, 3, 3, 3}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {3, 3, 3, 3, 3}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {3, 3, 3, 3, 3}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{3, 3, 3, 3, 3}, /* cost of unaligned SSE load
in 128bit, 256bit and 512bit */
- {3, 3, 3, 3, 3}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
- {3, 3, 3, 3, 3}, /* cost of unaligned SSE store
+ {3, 3, 3, 3, 3}, /* cost of unaligned SSE store
in 128bit, 256bit and 512bit */
- 3, 3, /* SSE->integer and integer->SSE moves */
+ 3, 3, 3, /* cost of moving XMM,YMM,ZMM register */
+ 3, /* cost of moving SSE register to integer. */
5, 0, /* Gather load static, per_elt. */
5, 0, /* Gather store static, per_elt. */
0, /* size of l1 cache */
@@ -127,6 +138,30 @@ static stringop_algs i386_memset[2] = {
static const
struct processor_costs i386_cost = { /* 386 specific costs */
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 4, /* cost for loading QImode using movzbl */
+ {2, 4, 2}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {2, 4, 2}, /* cost of storing integer registers */
+ 2, /* cost of reg,reg fld/fst */
+ {8, 8, 8}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {8, 8, 8}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 2, /* cost of moving MMX register */
+ {4, 8}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {4, 8}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ {4, 8, 16, 32, 64}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {4, 8, 16, 32, 64}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 3, 3, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1), /* cost of a lea instruction */
COSTS_N_INSNS (3), /* variable shift costs */
@@ -146,32 +181,18 @@ struct processor_costs i386_cost = { /* 386 specific costs */
COSTS_N_INSNS (2), /* cost of movzx */
15, /* "large" insn */
3, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 4, /* cost for loading QImode using movzbl */
{2, 4, 2}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{2, 4, 2}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {8, 8, 8}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {8, 8, 8}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {4, 8}, /* cost of loading MMX registers
- in SImode and DImode */
- {4, 8}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
- {4, 8, 16, 32, 64}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {4, 8, 16, 32, 64}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {4, 8, 16, 32, 64}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{4, 8, 16, 32, 64}, /* cost of unaligned loads. */
- {4, 8, 16, 32, 64}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{4, 8, 16, 32, 64}, /* cost of unaligned stores. */
- 3, 3, /* SSE->integer and integer->SSE moves */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ 3, /* cost of moving SSE register to integer. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
0, /* size of l1 cache */
@@ -216,6 +237,30 @@ static stringop_algs i486_memset[2] = {
static const
struct processor_costs i486_cost = { /* 486 specific costs */
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 4, /* cost for loading QImode using movzbl */
+ {2, 4, 2}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {2, 4, 2}, /* cost of storing integer registers */
+ 2, /* cost of reg,reg fld/fst */
+ {8, 8, 8}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {8, 8, 8}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 2, /* cost of moving MMX register */
+ {4, 8}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {4, 8}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ {4, 8, 16, 32, 64}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {4, 8, 16, 32, 64}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 3, 3, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1), /* cost of a lea instruction */
COSTS_N_INSNS (3), /* variable shift costs */
@@ -235,32 +280,18 @@ struct processor_costs i486_cost = { /* 486 specific costs */
COSTS_N_INSNS (2), /* cost of movzx */
15, /* "large" insn */
3, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 4, /* cost for loading QImode using movzbl */
{2, 4, 2}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{2, 4, 2}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {8, 8, 8}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {8, 8, 8}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {4, 8}, /* cost of loading MMX registers
- in SImode and DImode */
- {4, 8}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
- {4, 8, 16, 32, 64}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {4, 8, 16, 32, 64}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {4, 8, 16, 32, 64}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{4, 8, 16, 32, 64}, /* cost of unaligned loads. */
- {4, 8, 16, 32, 64}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{4, 8, 16, 32, 64}, /* cost of unaligned stores. */
- 3, 3, /* SSE->integer and integer->SSE moves */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ 3, /* cost of moving SSE register to integer. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
4, /* size of l1 cache. 486 has 8kB cache
@@ -307,6 +338,30 @@ static stringop_algs pentium_memset[2] = {
static const
struct processor_costs pentium_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 6, /* cost for loading QImode using movzbl */
+ {2, 4, 2}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {2, 4, 2}, /* cost of storing integer registers */
+ 2, /* cost of reg,reg fld/fst */
+ {2, 2, 6}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {4, 4, 6}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 8, /* cost of moving MMX register */
+ {8, 8}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {8, 8}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ {4, 8, 16, 32, 64}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {4, 8, 16, 32, 64}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 3, 3, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1), /* cost of a lea instruction */
COSTS_N_INSNS (4), /* variable shift costs */
@@ -326,32 +381,18 @@ struct processor_costs pentium_cost = {
COSTS_N_INSNS (2), /* cost of movzx */
8, /* "large" insn */
6, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 6, /* cost for loading QImode using movzbl */
{2, 4, 2}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{2, 4, 2}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {2, 2, 6}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {4, 4, 6}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 8, /* cost of moving MMX register */
- {8, 8}, /* cost of loading MMX registers
- in SImode and DImode */
- {8, 8}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
- {4, 8, 16, 32, 64}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {4, 8, 16, 32, 64}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {4, 8, 16, 32, 64}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{4, 8, 16, 32, 64}, /* cost of unaligned loads. */
- {4, 8, 16, 32, 64}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{4, 8, 16, 32, 64}, /* cost of unaligned stores. */
- 3, 3, /* SSE->integer and integer->SSE moves */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ 3, /* cost of moving SSE register to integer. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
8, /* size of l1 cache. */
@@ -389,6 +430,30 @@ struct processor_costs pentium_cost = {
static const
struct processor_costs lakemont_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 6, /* cost for loading QImode using movzbl */
+ {2, 4, 2}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {2, 4, 2}, /* cost of storing integer registers */
+ 2, /* cost of reg,reg fld/fst */
+ {2, 2, 6}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {4, 4, 6}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 8, /* cost of moving MMX register */
+ {8, 8}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {8, 8}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ {4, 8, 16, 32, 64}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {4, 8, 16, 32, 64}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 3, 3, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1) + 1, /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -408,32 +473,18 @@ struct processor_costs lakemont_cost = {
COSTS_N_INSNS (2), /* cost of movzx */
8, /* "large" insn */
17, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 6, /* cost for loading QImode using movzbl */
{2, 4, 2}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{2, 4, 2}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {2, 2, 6}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {4, 4, 6}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 8, /* cost of moving MMX register */
- {8, 8}, /* cost of loading MMX registers
- in SImode and DImode */
- {8, 8}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
- {4, 8, 16, 32, 64}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {4, 8, 16, 32, 64}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {4, 8, 16, 32, 64}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{4, 8, 16, 32, 64}, /* cost of unaligned loads. */
- {4, 8, 16, 32, 64}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{4, 8, 16, 32, 64}, /* cost of unaligned stores. */
- 3, 3, /* SSE->integer and integer->SSE moves */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ 3, /* cost of moving SSE register to integer. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
8, /* size of l1 cache. */
@@ -486,6 +537,30 @@ static stringop_algs pentiumpro_memset[2] = {
DUMMY_STRINGOP_ALGS};
static const
struct processor_costs pentiumpro_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 2, /* cost for loading QImode using movzbl */
+ {4, 4, 4}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {2, 2, 2}, /* cost of storing integer registers */
+ 2, /* cost of reg,reg fld/fst */
+ {2, 2, 6}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {4, 4, 6}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 2, /* cost of moving MMX register */
+ {2, 2}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {2, 2}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ {4, 8, 16, 32, 64}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {4, 8, 16, 32, 64}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 3, 3, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1), /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -505,32 +580,18 @@ struct processor_costs pentiumpro_cost = {
COSTS_N_INSNS (1), /* cost of movzx */
8, /* "large" insn */
6, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 2, /* cost for loading QImode using movzbl */
{4, 4, 4}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{2, 2, 2}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {2, 2, 6}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {4, 4, 6}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {2, 2}, /* cost of loading MMX registers
- in SImode and DImode */
- {2, 2}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
- {4, 8, 16, 32, 64}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {4, 8, 16, 32, 64}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {4, 8, 16, 32, 64}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{4, 8, 16, 32, 64}, /* cost of unaligned loads. */
- {4, 8, 16, 32, 64}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{4, 8, 16, 32, 64}, /* cost of unaligned stores. */
- 3, 3, /* SSE->integer and integer->SSE moves */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ 3, /* cost of moving SSE register to integer. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
8, /* size of l1 cache. */
@@ -574,6 +635,30 @@ static stringop_algs geode_memset[2] = {
DUMMY_STRINGOP_ALGS};
static const
struct processor_costs geode_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 2, /* cost for loading QImode using movzbl */
+ {2, 2, 2}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {2, 2, 2}, /* cost of storing integer registers */
+ 2, /* cost of reg,reg fld/fst */
+ {2, 2, 2}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {4, 6, 6}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 2, /* cost of moving MMX register */
+ {2, 2}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {2, 2}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ {2, 2, 8, 16, 32}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {2, 2, 8, 16, 32}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 6, 6, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1), /* cost of a lea instruction */
COSTS_N_INSNS (2), /* variable shift costs */
@@ -593,33 +678,18 @@ struct processor_costs geode_cost = {
COSTS_N_INSNS (1), /* cost of movzx */
8, /* "large" insn */
4, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 2, /* cost for loading QImode using movzbl */
{2, 2, 2}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{2, 2, 2}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {2, 2, 2}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {4, 6, 6}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
-
- 2, /* cost of moving MMX register */
- {2, 2}, /* cost of loading MMX registers
- in SImode and DImode */
- {2, 2}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
- {2, 2, 8, 16, 32}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {2, 2, 8, 16, 32}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {2, 2, 8, 16, 32}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{2, 2, 8, 16, 32}, /* cost of unaligned loads. */
- {2, 2, 8, 16, 32}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{2, 2, 8, 16, 32}, /* cost of unaligned stores. */
- 6, 6, /* SSE->integer and integer->SSE moves */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ 6, /* cost of moving SSE register to integer. */
2, 2, /* Gather load static, per_elt. */
2, 2, /* Gather store static, per_elt. */
64, /* size of l1 cache. */
@@ -663,6 +733,30 @@ static stringop_algs k6_memset[2] = {
DUMMY_STRINGOP_ALGS};
static const
struct processor_costs k6_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 3, /* cost for loading QImode using movzbl */
+ {4, 5, 4}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {2, 3, 2}, /* cost of storing integer registers */
+ 4, /* cost of reg,reg fld/fst */
+ {6, 6, 6}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {4, 4, 4}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 2, /* cost of moving MMX register */
+ {2, 2}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {2, 2}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ {2, 2, 8, 16, 32}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {2, 2, 8, 16, 32}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 6, 6, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (2), /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -682,32 +776,18 @@ struct processor_costs k6_cost = {
COSTS_N_INSNS (2), /* cost of movzx */
8, /* "large" insn */
4, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 3, /* cost for loading QImode using movzbl */
{4, 5, 4}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{2, 3, 2}, /* cost of storing integer registers */
- 4, /* cost of reg,reg fld/fst */
- {6, 6, 6}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {4, 4, 4}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {2, 2}, /* cost of loading MMX registers
- in SImode and DImode */
- {2, 2}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
- {2, 2, 8, 16, 32}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {2, 2, 8, 16, 32}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {2, 2, 8, 16, 32}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{2, 2, 8, 16, 32}, /* cost of unaligned loads. */
- {2, 2, 8, 16, 32}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{2, 2, 8, 16, 32}, /* cost of unaligned stores. */
- 6, 6, /* SSE->integer and integer->SSE moves */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ 6, /* cost of moving SSE register to integer. */
2, 2, /* Gather load static, per_elt. */
2, 2, /* Gather store static, per_elt. */
32, /* size of l1 cache. */
@@ -757,6 +837,30 @@ static stringop_algs athlon_memset[2] = {
DUMMY_STRINGOP_ALGS};
static const
struct processor_costs athlon_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 4, /* cost for loading QImode using movzbl */
+ {3, 4, 3}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {3, 4, 3}, /* cost of storing integer registers */
+ 4, /* cost of reg,reg fld/fst */
+ {4, 4, 12}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {6, 6, 8}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 2, /* cost of moving MMX register */
+ {4, 4}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {4, 4}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ {4, 4, 12, 12, 24}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {4, 4, 10, 10, 20}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 5, 5, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (2), /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -776,32 +880,18 @@ struct processor_costs athlon_cost = {
COSTS_N_INSNS (1), /* cost of movzx */
8, /* "large" insn */
9, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 4, /* cost for loading QImode using movzbl */
{3, 4, 3}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{3, 4, 3}, /* cost of storing integer registers */
- 4, /* cost of reg,reg fld/fst */
- {4, 4, 12}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {6, 6, 8}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {4, 4}, /* cost of loading MMX registers
- in SImode and DImode */
- {4, 4}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
- {4, 4, 12, 12, 24}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {4, 4, 12, 12, 24}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {4, 4, 10, 10, 20}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{4, 4, 12, 12, 24}, /* cost of unaligned loads. */
- {4, 4, 10, 10, 20}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{4, 4, 10, 10, 20}, /* cost of unaligned stores. */
- 5, 5, /* SSE->integer and integer->SSE moves */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ 5, /* cost of moving SSE register to integer. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
64, /* size of l1 cache. */
@@ -853,6 +943,30 @@ static stringop_algs k8_memset[2] = {
{8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}};
static const
struct processor_costs k8_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 4, /* cost for loading QImode using movzbl */
+ {3, 4, 3}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {3, 4, 3}, /* cost of storing integer registers */
+ 4, /* cost of reg,reg fld/fst */
+ {4, 4, 12}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {6, 6, 8}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 2, /* cost of moving MMX register */
+ {3, 3}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {4, 4}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ {4, 3, 12, 12, 24}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {4, 4, 10, 10, 20}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 5, 5, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (2), /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -872,32 +986,18 @@ struct processor_costs k8_cost = {
COSTS_N_INSNS (1), /* cost of movzx */
8, /* "large" insn */
9, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 4, /* cost for loading QImode using movzbl */
{3, 4, 3}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{3, 4, 3}, /* cost of storing integer registers */
- 4, /* cost of reg,reg fld/fst */
- {4, 4, 12}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {6, 6, 8}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {3, 3}, /* cost of loading MMX registers
- in SImode and DImode */
- {4, 4}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
- {4, 3, 12, 12, 24}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {4, 3, 12, 12, 24}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {4, 4, 10, 10, 20}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{4, 3, 12, 12, 24}, /* cost of unaligned loads. */
- {4, 4, 10, 10, 20}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{4, 4, 10, 10, 20}, /* cost of unaligned stores. */
- 5, 5, /* SSE->integer and integer->SSE moves */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ 5, /* cost of moving SSE register to integer. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
64, /* size of l1 cache. */
@@ -953,28 +1053,7 @@ static stringop_algs amdfam10_memset[2] = {
{libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
{-1, libcall, false}}}};
struct processor_costs amdfam10_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction */
- COSTS_N_INSNS (2), /* cost of a lea instruction */
- COSTS_N_INSNS (1), /* variable shift costs */
- COSTS_N_INSNS (1), /* constant shift costs */
- {COSTS_N_INSNS (3), /* cost of starting multiply for QI */
- COSTS_N_INSNS (4), /* HI */
- COSTS_N_INSNS (3), /* SI */
- COSTS_N_INSNS (4), /* DI */
- COSTS_N_INSNS (5)}, /* other */
- 0, /* cost of multiply per each bit set */
- {COSTS_N_INSNS (19), /* cost of a divide/mod for QI */
- COSTS_N_INSNS (35), /* HI */
- COSTS_N_INSNS (51), /* SI */
- COSTS_N_INSNS (83), /* DI */
- COSTS_N_INSNS (83)}, /* other */
- COSTS_N_INSNS (1), /* cost of movsx */
- COSTS_N_INSNS (1), /* cost of movzx */
- 8, /* "large" insn */
- 9, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
+ /* Start of register allocator costs. integer->integer move cost is 2. */
4, /* cost for loading QImode using movzbl */
{3, 4, 3}, /* cost of loading integer registers
in QImode, HImode and SImode.
@@ -993,11 +1072,10 @@ struct processor_costs amdfam10_cost = {
2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
{4, 4, 3, 6, 12}, /* cost of loading SSE registers
in 32,64,128,256 and 512-bit */
- {4, 4, 3, 7, 12}, /* cost of unaligned loads. */
{4, 4, 5, 10, 20}, /* cost of storing SSE registers
in 32,64,128,256 and 512-bit */
- {4, 4, 5, 10, 20}, /* cost of unaligned stores. */
3, 3, /* SSE->integer and integer->SSE moves */
+
/* On K8:
MOVD reg64, xmmreg Double FSTORE 4
MOVD reg32, xmmreg Double FSTORE 4
@@ -1006,6 +1084,39 @@ struct processor_costs amdfam10_cost = {
1/1 1/1
MOVD reg32, xmmreg Double FADD 3
1/1 1/1 */
+ /* End of register allocator costs. */
+
+ COSTS_N_INSNS (1), /* cost of an add instruction */
+ COSTS_N_INSNS (2), /* cost of a lea instruction */
+ COSTS_N_INSNS (1), /* variable shift costs */
+ COSTS_N_INSNS (1), /* constant shift costs */
+ {COSTS_N_INSNS (3), /* cost of starting multiply for QI */
+ COSTS_N_INSNS (4), /* HI */
+ COSTS_N_INSNS (3), /* SI */
+ COSTS_N_INSNS (4), /* DI */
+ COSTS_N_INSNS (5)}, /* other */
+ 0, /* cost of multiply per each bit set */
+ {COSTS_N_INSNS (19), /* cost of a divide/mod for QI */
+ COSTS_N_INSNS (35), /* HI */
+ COSTS_N_INSNS (51), /* SI */
+ COSTS_N_INSNS (83), /* DI */
+ COSTS_N_INSNS (83)}, /* other */
+ COSTS_N_INSNS (1), /* cost of movsx */
+ COSTS_N_INSNS (1), /* cost of movzx */
+ 8, /* "large" insn */
+ 9, /* MOVE_RATIO */
+ {3, 4, 3}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {3, 4, 3}, /* cost of storing integer registers */
+ {4, 4, 3, 6, 12}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {4, 4, 5, 10, 20}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {4, 4, 3, 7, 12}, /* cost of unaligned loads. */
+ {4, 4, 5, 10, 20}, /* cost of unaligned stores. */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ 3, /* cost of moving SSE register to integer. */
4, 4, /* Gather load static, per_elt. */
4, 4, /* Gather store static, per_elt. */
64, /* size of l1 cache. */
@@ -1062,6 +1173,30 @@ static stringop_algs bdver_memset[2] = {
{-1, libcall, false}}}};
const struct processor_costs bdver_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 8, /* cost for loading QImode using movzbl */
+ {8, 8, 8}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {8, 8, 8}, /* cost of storing integer registers */
+ 4, /* cost of reg,reg fld/fst */
+ {12, 12, 28}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {10, 10, 18}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 4, /* cost of moving MMX register */
+ {12, 12}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {10, 10}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ {12, 12, 10, 40, 60}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {10, 10, 10, 40, 60}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 16, 20, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1), /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -1081,32 +1216,18 @@ const struct processor_costs bdver_cost = {
COSTS_N_INSNS (1), /* cost of movzx */
8, /* "large" insn */
9, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 8, /* cost for loading QImode using movzbl */
{8, 8, 8}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{8, 8, 8}, /* cost of storing integer registers */
- 4, /* cost of reg,reg fld/fst */
- {12, 12, 28}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {10, 10, 18}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 4, /* cost of moving MMX register */
- {12, 12}, /* cost of loading MMX registers
- in SImode and DImode */
- {10, 10}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
- {12, 12, 10, 40, 60}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {12, 12, 10, 40, 60}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {10, 10, 10, 40, 60}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{12, 12, 10, 40, 60}, /* cost of unaligned loads. */
- {10, 10, 10, 40, 60}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{10, 10, 10, 40, 60}, /* cost of unaligned stores. */
- 16, 20, /* SSE->integer and integer->SSE moves */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ 16, /* cost of moving SSE register to integer. */
12, 12, /* Gather load static, per_elt. */
10, 10, /* Gather store static, per_elt. */
16, /* size of l1 cache. */
@@ -1164,6 +1285,37 @@ static stringop_algs znver1_memset[2] = {
{libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
{-1, libcall, false}}}};
struct processor_costs znver1_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+
+ /* reg-reg moves are done by renaming and thus they are even cheaper than
+ 1 cycle. Becuase reg-reg move cost is 2 and the following tables correspond
+ to doubles of latencies, we do not model this correctly. It does not
+ seem to make practical difference to bump prices up even more. */
+ 6, /* cost for loading QImode using
+ movzbl. */
+ {6, 6, 6}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {8, 8, 8}, /* cost of storing integer
+ registers. */
+ 2, /* cost of reg,reg fld/fst. */
+ {6, 6, 16}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode. */
+ {8, 8, 16}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode. */
+ 2, /* cost of moving MMX register. */
+ {6, 6}, /* cost of loading MMX registers
+ in SImode and DImode. */
+ {8, 8}, /* cost of storing MMX registers
+ in SImode and DImode. */
+ 2, 3, 6, /* cost of moving XMM,YMM,ZMM register. */
+ {6, 6, 6, 12, 24}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit. */
+ {8, 8, 8, 16, 32}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit. */
+ 6, 6, /* SSE->integer and integer->SSE moves. */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction. */
COSTS_N_INSNS (1), /* cost of a lea instruction. */
COSTS_N_INSNS (1), /* variable shift costs. */
@@ -1186,39 +1338,19 @@ struct processor_costs znver1_cost = {
COSTS_N_INSNS (1), /* cost of movzx. */
8, /* "large" insn. */
9, /* MOVE_RATIO. */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
-
- /* reg-reg moves are done by renaming and thus they are even cheaper than
- 1 cycle. Becuase reg-reg move cost is 2 and the following tables correspond
- to doubles of latencies, we do not model this correctly. It does not
- seem to make practical difference to bump prices up even more. */
- 6, /* cost for loading QImode using
- movzbl. */
{6, 6, 6}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{8, 8, 8}, /* cost of storing integer
registers. */
- 2, /* cost of reg,reg fld/fst. */
- {6, 6, 16}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode. */
- {8, 8, 16}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode. */
- 2, /* cost of moving MMX register. */
- {6, 6}, /* cost of loading MMX registers
- in SImode and DImode. */
- {8, 8}, /* cost of storing MMX registers
- in SImode and DImode. */
- 2, 3, 6, /* cost of moving XMM,YMM,ZMM register. */
- {6, 6, 6, 12, 24}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit. */
+ {6, 6, 6, 12, 24}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {8, 8, 8, 16, 32}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{6, 6, 6, 12, 24}, /* cost of unaligned loads. */
- {8, 8, 8, 16, 32}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit. */
{8, 8, 8, 16, 32}, /* cost of unaligned stores. */
- 6, 6, /* SSE->integer and integer->SSE moves. */
+ 2, 3, 6, /* cost of moving XMM,YMM,ZMM register. */
+ 6, /* cost of moving SSE register to integer. */
/* VGATHERDPD is 23 uops and throughput is 9, VGATHERDPD is 35 uops,
throughput 12. Approx 9 uops do not depend on vector size and every load
is 7 uops. */
@@ -1288,31 +1420,7 @@ static stringop_algs znver2_memset[2] = {
{-1, libcall, false}}}};
struct processor_costs znver2_cost = {
- COSTS_N_INSNS (1), /* cost of an add instruction. */
- COSTS_N_INSNS (1), /* cost of a lea instruction. */
- COSTS_N_INSNS (1), /* variable shift costs. */
- COSTS_N_INSNS (1), /* constant shift costs. */
- {COSTS_N_INSNS (3), /* cost of starting multiply for QI. */
- COSTS_N_INSNS (3), /* HI. */
- COSTS_N_INSNS (3), /* SI. */
- COSTS_N_INSNS (3), /* DI. */
- COSTS_N_INSNS (3)}, /* other. */
- 0, /* cost of multiply per each bit
- set. */
- /* Depending on parameters, idiv can get faster on ryzen. This is upper
- bound. */
- {COSTS_N_INSNS (16), /* cost of a divide/mod for QI. */
- COSTS_N_INSNS (22), /* HI. */
- COSTS_N_INSNS (30), /* SI. */
- COSTS_N_INSNS (45), /* DI. */
- COSTS_N_INSNS (45)}, /* other. */
- COSTS_N_INSNS (1), /* cost of movsx. */
- COSTS_N_INSNS (1), /* cost of movzx. */
- 8, /* "large" insn. */
- 9, /* MOVE_RATIO. */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
+ /* Start of register allocator costs. integer->integer move cost is 2. */
/* reg-reg moves are done by renaming and thus they are even cheaper than
1 cycle. Because reg-reg move cost is 2 and following tables correspond
@@ -1339,12 +1447,48 @@ struct processor_costs znver2_cost = {
register. */
{6, 6, 6, 6, 12}, /* cost of loading SSE registers
in 32,64,128,256 and 512-bit. */
- {6, 6, 6, 6, 12}, /* cost of unaligned loads. */
{8, 8, 8, 8, 16}, /* cost of storing SSE registers
in 32,64,128,256 and 512-bit. */
- {8, 8, 8, 8, 16}, /* cost of unaligned stores. */
6, 6, /* SSE->integer and integer->SSE
moves. */
+ /* End of register allocator costs. */
+
+ COSTS_N_INSNS (1), /* cost of an add instruction. */
+ COSTS_N_INSNS (1), /* cost of a lea instruction. */
+ COSTS_N_INSNS (1), /* variable shift costs. */
+ COSTS_N_INSNS (1), /* constant shift costs. */
+ {COSTS_N_INSNS (3), /* cost of starting multiply for QI. */
+ COSTS_N_INSNS (3), /* HI. */
+ COSTS_N_INSNS (3), /* SI. */
+ COSTS_N_INSNS (3), /* DI. */
+ COSTS_N_INSNS (3)}, /* other. */
+ 0, /* cost of multiply per each bit
+ set. */
+ /* Depending on parameters, idiv can get faster on ryzen. This is upper
+ bound. */
+ {COSTS_N_INSNS (16), /* cost of a divide/mod for QI. */
+ COSTS_N_INSNS (22), /* HI. */
+ COSTS_N_INSNS (30), /* SI. */
+ COSTS_N_INSNS (45), /* DI. */
+ COSTS_N_INSNS (45)}, /* other. */
+ COSTS_N_INSNS (1), /* cost of movsx. */
+ COSTS_N_INSNS (1), /* cost of movzx. */
+ 8, /* "large" insn. */
+ 9, /* MOVE_RATIO. */
+ {6, 6, 6}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {8, 8, 8}, /* cost of storing integer
+ registers. */
+ {6, 6, 6, 6, 12}, /* cost of loading SSE registers
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {8, 8, 8, 8, 16}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {6, 6, 6, 6, 12}, /* cost of unaligned loads. */
+ {8, 8, 8, 8, 16}, /* cost of unaligned stores. */
+ 2, 2, 3, /* cost of moving XMM,YMM,ZMM
+ register. */
+ 6, /* cost of moving SSE register to integer. */
/* VGATHERDPD is 23 uops and throughput is 9, VGATHERDPD is 35 uops,
throughput 12. Approx 9 uops do not depend on vector size and every load
is 7 uops. */
@@ -1416,6 +1560,30 @@ static stringop_algs skylake_memset[2] = {
static const
struct processor_costs skylake_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 6, /* cost for loading QImode using movzbl */
+ {4, 4, 4}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {6, 6, 3}, /* cost of storing integer registers */
+ 2, /* cost of reg,reg fld/fst */
+ {6, 6, 8}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {6, 6, 10}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 2, /* cost of moving MMX register */
+ {6, 6}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {6, 6}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 2, 4, /* cost of moving XMM,YMM,ZMM register */
+ {6, 6, 6, 10, 20}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {8, 8, 8, 12, 24}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 2, 2, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1)+1, /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -1437,30 +1605,18 @@ struct processor_costs skylake_cost = {
COSTS_N_INSNS (0), /* cost of movzx */
8, /* "large" insn */
17, /* MOVE_RATIO */
-
- 6, /* cost for loading QImode using movzbl */
{4, 4, 4}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{6, 6, 3}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {6, 6, 8}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {6, 6, 10}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {6, 6}, /* cost of loading MMX registers
- in SImode and DImode */
- {6, 6}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 2, 4, /* cost of moving XMM,YMM,ZMM register */
- {6, 6, 6, 10, 20}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {6, 6, 6, 10, 20}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {8, 8, 8, 12, 24}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{6, 6, 6, 10, 20}, /* cost of unaligned loads. */
- {8, 8, 8, 12, 24}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{8, 8, 8, 8, 16}, /* cost of unaligned stores. */
- 2, 2, /* SSE->integer and integer->SSE moves */
+ 2, 2, 4, /* cost of moving XMM,YMM,ZMM register */
+ 2, /* cost of moving SSE register to integer. */
20, 8, /* Gather load static, per_elt. */
22, 10, /* Gather store static, per_elt. */
64, /* size of l1 cache. */
@@ -1509,6 +1665,30 @@ static stringop_algs btver1_memset[2] = {
{libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
{-1, libcall, false}}}};
const struct processor_costs btver1_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 8, /* cost for loading QImode using movzbl */
+ {6, 8, 6}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {6, 8, 6}, /* cost of storing integer registers */
+ 4, /* cost of reg,reg fld/fst */
+ {12, 12, 28}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {12, 12, 38}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 4, /* cost of moving MMX register */
+ {10, 10}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {12, 12}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ {10, 10, 12, 48, 96}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {10, 10, 12, 48, 96}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 14, 14, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (2), /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -1528,32 +1708,18 @@ const struct processor_costs btver1_cost = {
COSTS_N_INSNS (1), /* cost of movzx */
8, /* "large" insn */
9, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 8, /* cost for loading QImode using movzbl */
{6, 8, 6}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{6, 8, 6}, /* cost of storing integer registers */
- 4, /* cost of reg,reg fld/fst */
- {12, 12, 28}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {12, 12, 38}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 4, /* cost of moving MMX register */
- {10, 10}, /* cost of loading MMX registers
- in SImode and DImode */
- {12, 12}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
- {10, 10, 12, 48, 96}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {10, 10, 12, 48, 96}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {10, 10, 12, 48, 96}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{10, 10, 12, 48, 96}, /* cost of unaligned loads. */
- {10, 10, 12, 48, 96}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{10, 10, 12, 48, 96}, /* cost of unaligned stores. */
- 14, 14, /* SSE->integer and integer->SSE moves */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ 14, /* cost of moving SSE register to integer. */
10, 10, /* Gather load static, per_elt. */
10, 10, /* Gather store static, per_elt. */
32, /* size of l1 cache. */
@@ -1600,6 +1766,30 @@ static stringop_algs btver2_memset[2] = {
{libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
{-1, libcall, false}}}};
const struct processor_costs btver2_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 8, /* cost for loading QImode using movzbl */
+ {8, 8, 6}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {8, 8, 6}, /* cost of storing integer registers */
+ 4, /* cost of reg,reg fld/fst */
+ {12, 12, 28}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {12, 12, 38}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 4, /* cost of moving MMX register */
+ {10, 10}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {12, 12}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ {10, 10, 12, 48, 96}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {10, 10, 12, 48, 96}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 14, 14, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (2), /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -1619,32 +1809,18 @@ const struct processor_costs btver2_cost = {
COSTS_N_INSNS (1), /* cost of movzx */
8, /* "large" insn */
9, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 8, /* cost for loading QImode using movzbl */
{8, 8, 6}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{8, 8, 6}, /* cost of storing integer registers */
- 4, /* cost of reg,reg fld/fst */
- {12, 12, 28}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {12, 12, 38}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 4, /* cost of moving MMX register */
- {10, 10}, /* cost of loading MMX registers
- in SImode and DImode */
- {12, 12}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
- {10, 10, 12, 48, 96}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {10, 10, 12, 48, 96}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {10, 10, 12, 48, 96}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{10, 10, 12, 48, 96}, /* cost of unaligned loads. */
- {10, 10, 12, 48, 96}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{10, 10, 12, 48, 96}, /* cost of unaligned stores. */
- 14, 14, /* SSE->integer and integer->SSE moves */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ 14, /* cost of moving SSE register to integer. */
10, 10, /* Gather load static, per_elt. */
10, 10, /* Gather store static, per_elt. */
32, /* size of l1 cache. */
@@ -1690,6 +1866,30 @@ static stringop_algs pentium4_memset[2] = {
static const
struct processor_costs pentium4_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 5, /* cost for loading QImode using movzbl */
+ {4, 5, 4}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {2, 3, 2}, /* cost of storing integer registers */
+ 12, /* cost of reg,reg fld/fst */
+ {14, 14, 14}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {14, 14, 14}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 12, /* cost of moving MMX register */
+ {16, 16}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {16, 16}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 12, 24, 48, /* cost of moving XMM,YMM,ZMM register */
+ {16, 16, 16, 32, 64}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {16, 16, 16, 32, 64}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 20, 12, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (3), /* cost of a lea instruction */
COSTS_N_INSNS (4), /* variable shift costs */
@@ -1709,32 +1909,18 @@ struct processor_costs pentium4_cost = {
COSTS_N_INSNS (1), /* cost of movzx */
16, /* "large" insn */
6, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 5, /* cost for loading QImode using movzbl */
{4, 5, 4}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{2, 3, 2}, /* cost of storing integer registers */
- 12, /* cost of reg,reg fld/fst */
- {14, 14, 14}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {14, 14, 14}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 12, /* cost of moving MMX register */
- {16, 16}, /* cost of loading MMX registers
- in SImode and DImode */
- {16, 16}, /* cost of storing MMX registers
- in SImode and DImode */
- 12, 24, 48, /* cost of moving XMM,YMM,ZMM register */
- {16, 16, 16, 32, 64}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {16, 16, 16, 32, 64}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {16, 16, 16, 32, 64}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{32, 32, 32, 64, 128}, /* cost of unaligned loads. */
- {16, 16, 16, 32, 64}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{32, 32, 32, 64, 128}, /* cost of unaligned stores. */
- 20, 12, /* SSE->integer and integer->SSE moves */
+ 12, 24, 48, /* cost of moving XMM,YMM,ZMM register */
+ 20, /* cost of moving SSE register to integer. */
16, 16, /* Gather load static, per_elt. */
16, 16, /* Gather store static, per_elt. */
8, /* size of l1 cache. */
@@ -1783,6 +1969,30 @@ static stringop_algs nocona_memset[2] = {
static const
struct processor_costs nocona_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 4, /* cost for loading QImode using movzbl */
+ {4, 4, 4}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {4, 4, 4}, /* cost of storing integer registers */
+ 12, /* cost of reg,reg fld/fst */
+ {14, 14, 14}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {14, 14, 14}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 14, /* cost of moving MMX register */
+ {12, 12}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {12, 12}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 6, 12, 24, /* cost of moving XMM,YMM,ZMM register */
+ {12, 12, 12, 24, 48}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {12, 12, 12, 24, 48}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 20, 12, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1), /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -1802,32 +2012,18 @@ struct processor_costs nocona_cost = {
COSTS_N_INSNS (1), /* cost of movzx */
16, /* "large" insn */
17, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 4, /* cost for loading QImode using movzbl */
{4, 4, 4}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{4, 4, 4}, /* cost of storing integer registers */
- 12, /* cost of reg,reg fld/fst */
- {14, 14, 14}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {14, 14, 14}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 14, /* cost of moving MMX register */
- {12, 12}, /* cost of loading MMX registers
- in SImode and DImode */
- {12, 12}, /* cost of storing MMX registers
- in SImode and DImode */
- 6, 12, 24, /* cost of moving XMM,YMM,ZMM register */
- {12, 12, 12, 24, 48}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {12, 12, 12, 24, 48}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {12, 12, 12, 24, 48}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{24, 24, 24, 48, 96}, /* cost of unaligned loads. */
- {12, 12, 12, 24, 48}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{24, 24, 24, 48, 96}, /* cost of unaligned stores. */
- 20, 12, /* SSE->integer and integer->SSE moves */
+ 6, 12, 24, /* cost of moving XMM,YMM,ZMM register */
+ 20, /* cost of moving SSE register to integer. */
12, 12, /* Gather load static, per_elt. */
12, 12, /* Gather store static, per_elt. */
8, /* size of l1 cache. */
@@ -1874,6 +2070,30 @@ static stringop_algs atom_memset[2] = {
{8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}};
static const
struct processor_costs atom_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 6, /* cost for loading QImode using movzbl */
+ {6, 6, 6}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {6, 6, 6}, /* cost of storing integer registers */
+ 4, /* cost of reg,reg fld/fst */
+ {6, 6, 18}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {14, 14, 24}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 2, /* cost of moving MMX register */
+ {8, 8}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {10, 10}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ {8, 8, 8, 16, 32}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {8, 8, 8, 16, 32}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 8, 6, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1) + 1, /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -1893,32 +2113,18 @@ struct processor_costs atom_cost = {
COSTS_N_INSNS (1), /* cost of movzx */
8, /* "large" insn */
17, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 6, /* cost for loading QImode using movzbl */
{6, 6, 6}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{6, 6, 6}, /* cost of storing integer registers */
- 4, /* cost of reg,reg fld/fst */
- {6, 6, 18}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {14, 14, 24}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {8, 8}, /* cost of loading MMX registers
- in SImode and DImode */
- {10, 10}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
- {8, 8, 8, 16, 32}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {8, 8, 8, 16, 32}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {8, 8, 8, 16, 32}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{16, 16, 16, 32, 64}, /* cost of unaligned loads. */
- {8, 8, 8, 16, 32}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{16, 16, 16, 32, 64}, /* cost of unaligned stores. */
- 8, 6, /* SSE->integer and integer->SSE moves */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ 8, /* cost of moving SSE register to integer. */
8, 8, /* Gather load static, per_elt. */
8, 8, /* Gather store static, per_elt. */
32, /* size of l1 cache. */
@@ -1965,6 +2171,30 @@ static stringop_algs slm_memset[2] = {
{8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}};
static const
struct processor_costs slm_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 8, /* cost for loading QImode using movzbl */
+ {8, 8, 8}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {6, 6, 6}, /* cost of storing integer registers */
+ 2, /* cost of reg,reg fld/fst */
+ {8, 8, 18}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {6, 6, 18}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 2, /* cost of moving MMX register */
+ {8, 8}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {6, 6}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ {8, 8, 8, 16, 32}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {8, 8, 8, 16, 32}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 8, 6, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1) + 1, /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -1984,32 +2214,18 @@ struct processor_costs slm_cost = {
COSTS_N_INSNS (1), /* cost of movzx */
8, /* "large" insn */
17, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 8, /* cost for loading QImode using movzbl */
{8, 8, 8}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{6, 6, 6}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {8, 8, 18}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {6, 6, 18}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {8, 8}, /* cost of loading MMX registers
- in SImode and DImode */
- {6, 6}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
- {8, 8, 8, 16, 32}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {8, 8, 8, 16, 32}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {8, 8, 8, 16, 32}, /* cost of storing SSE register
+ in SImode, DImode and TImode. */
{16, 16, 16, 32, 64}, /* cost of unaligned loads. */
- {8, 8, 8, 16, 32}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{16, 16, 16, 32, 64}, /* cost of unaligned stores. */
- 8, 6, /* SSE->integer and integer->SSE moves */
+ 2, 4, 8, /* cost of moving XMM,YMM,ZMM register */
+ 8, /* cost of moving SSE register to integer. */
8, 8, /* Gather load static, per_elt. */
8, 8, /* Gather store static, per_elt. */
32, /* size of l1 cache. */
@@ -2056,6 +2272,30 @@ static stringop_algs intel_memset[2] = {
{8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}};
static const
struct processor_costs intel_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 6, /* cost for loading QImode using movzbl */
+ {4, 4, 4}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {6, 6, 6}, /* cost of storing integer registers */
+ 2, /* cost of reg,reg fld/fst */
+ {6, 6, 8}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {6, 6, 10}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 2, /* cost of moving MMX register */
+ {6, 6}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {6, 6}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 2, 2, /* cost of moving XMM,YMM,ZMM register */
+ {6, 6, 6, 6, 6}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {6, 6, 6, 6, 6}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 4, 4, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1) + 1, /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -2075,32 +2315,18 @@ struct processor_costs intel_cost = {
COSTS_N_INSNS (1), /* cost of movzx */
8, /* "large" insn */
17, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 6, /* cost for loading QImode using movzbl */
{4, 4, 4}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{6, 6, 6}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {6, 6, 8}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {6, 6, 10}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {6, 6}, /* cost of loading MMX registers
- in SImode and DImode */
- {6, 6}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 2, 2, /* cost of moving XMM,YMM,ZMM register */
- {6, 6, 6, 6, 6}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {6, 6, 6, 6, 6}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {6, 6, 6, 6, 6}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{10, 10, 10, 10, 10}, /* cost of unaligned loads. */
- {6, 6, 6, 6, 6}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{10, 10, 10, 10, 10}, /* cost of unaligned loads. */
- 4, 4, /* SSE->integer and integer->SSE moves */
+ 2, 2, 2, /* cost of moving XMM,YMM,ZMM register */
+ 4, /* cost of moving SSE register to integer. */
6, 6, /* Gather load static, per_elt. */
6, 6, /* Gather store static, per_elt. */
32, /* size of l1 cache. */
@@ -2151,6 +2377,30 @@ static stringop_algs generic_memset[2] = {
{-1, libcall, false}}}};
static const
struct processor_costs generic_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 6, /* cost for loading QImode using movzbl */
+ {6, 6, 6}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {6, 6, 6}, /* cost of storing integer registers */
+ 4, /* cost of reg,reg fld/fst */
+ {6, 6, 12}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {6, 6, 12}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 2, /* cost of moving MMX register */
+ {6, 6}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {6, 6}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 3, 4, /* cost of moving XMM,YMM,ZMM register */
+ {6, 6, 6, 10, 15}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {6, 6, 6, 10, 15}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 6, 6, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
/* Setting cost to 2 makes our current implementation of synth_mult result in
use of unnecessary temporary registers causing regression on several
@@ -2173,32 +2423,18 @@ struct processor_costs generic_cost = {
COSTS_N_INSNS (1), /* cost of movzx */
8, /* "large" insn */
17, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 6, /* cost for loading QImode using movzbl */
{6, 6, 6}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{6, 6, 6}, /* cost of storing integer registers */
- 4, /* cost of reg,reg fld/fst */
- {6, 6, 12}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {6, 6, 12}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {6, 6}, /* cost of loading MMX registers
- in SImode and DImode */
- {6, 6}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 3, 4, /* cost of moving XMM,YMM,ZMM register */
- {6, 6, 6, 10, 15}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {6, 6, 6, 10, 15}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {6, 6, 6, 10, 15}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{6, 6, 6, 10, 15}, /* cost of unaligned loads. */
- {6, 6, 6, 10, 15}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{6, 6, 6, 10, 15}, /* cost of unaligned storess. */
- 6, 6, /* SSE->integer and integer->SSE moves */
+ 2, 3, 4, /* cost of moving XMM,YMM,ZMM register */
+ 6, /* cost of moving SSE register to integer. */
18, 6, /* Gather load static, per_elt. */
18, 6, /* Gather store static, per_elt. */
32, /* size of l1 cache. */
@@ -2251,6 +2487,30 @@ static stringop_algs core_memset[2] = {
static const
struct processor_costs core_cost = {
+ /* Start of register allocator costs. integer->integer move cost is 2. */
+ 6, /* cost for loading QImode using movzbl */
+ {4, 4, 4}, /* cost of loading integer registers
+ in QImode, HImode and SImode.
+ Relative to reg-reg move (2). */
+ {6, 6, 6}, /* cost of storing integer registers */
+ 2, /* cost of reg,reg fld/fst */
+ {6, 6, 8}, /* cost of loading fp registers
+ in SFmode, DFmode and XFmode */
+ {6, 6, 10}, /* cost of storing fp registers
+ in SFmode, DFmode and XFmode */
+ 2, /* cost of moving MMX register */
+ {6, 6}, /* cost of loading MMX registers
+ in SImode and DImode */
+ {6, 6}, /* cost of storing MMX registers
+ in SImode and DImode */
+ 2, 2, 4, /* cost of moving XMM,YMM,ZMM register */
+ {6, 6, 6, 6, 12}, /* cost of loading SSE registers
+ in 32,64,128,256 and 512-bit */
+ {6, 6, 6, 6, 12}, /* cost of storing SSE registers
+ in 32,64,128,256 and 512-bit */
+ 2, 2, /* SSE->integer and integer->SSE moves */
+ /* End of register allocator costs. */
+
COSTS_N_INSNS (1), /* cost of an add instruction */
/* On all chips taken into consideration lea is 2 cycles and more. With
this cost however our current implementation of synth_mult results in
@@ -2277,32 +2537,18 @@ struct processor_costs core_cost = {
COSTS_N_INSNS (1), /* cost of movzx */
8, /* "large" insn */
17, /* MOVE_RATIO */
-
- /* All move costs are relative to integer->integer move times 2 and thus
- they are latency*2. */
- 6, /* cost for loading QImode using movzbl */
{4, 4, 4}, /* cost of loading integer registers
in QImode, HImode and SImode.
Relative to reg-reg move (2). */
{6, 6, 6}, /* cost of storing integer registers */
- 2, /* cost of reg,reg fld/fst */
- {6, 6, 8}, /* cost of loading fp registers
- in SFmode, DFmode and XFmode */
- {6, 6, 10}, /* cost of storing fp registers
- in SFmode, DFmode and XFmode */
- 2, /* cost of moving MMX register */
- {6, 6}, /* cost of loading MMX registers
- in SImode and DImode */
- {6, 6}, /* cost of storing MMX registers
- in SImode and DImode */
- 2, 2, 4, /* cost of moving XMM,YMM,ZMM register */
- {6, 6, 6, 6, 12}, /* cost of loading SSE registers
- in 32,64,128,256 and 512-bit */
+ {6, 6, 6, 6, 12}, /* cost of loading SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
+ {6, 6, 6, 6, 12}, /* cost of storing SSE register
+ in 32bit, 64bit, 128bit, 256bit and 512bit */
{6, 6, 6, 6, 12}, /* cost of unaligned loads. */
- {6, 6, 6, 6, 12}, /* cost of storing SSE registers
- in 32,64,128,256 and 512-bit */
{6, 6, 6, 6, 12}, /* cost of unaligned stores. */
- 2, 2, /* SSE->integer and integer->SSE moves */
+ 2, 2, 4, /* cost of moving XMM,YMM,ZMM register */
+ 2, /* cost of moving SSE register to integer. */
/* VGATHERDPD is 7 uops, rec throughput 5, while VGATHERDPD is 9 uops,
rec. throughput 6.
So 5 uops statically and one uops per load. */
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index a2a6c5c..a07244e 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -10556,8 +10556,8 @@ ia64_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED,
{
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)
{
- enum ia64_builtins fn_code = (enum ia64_builtins)
- DECL_FUNCTION_CODE (fndecl);
+ enum ia64_builtins fn_code
+ = (enum ia64_builtins) DECL_MD_FUNCTION_CODE (fndecl);
switch (fn_code)
{
case IA64_BUILTIN_NANQ:
@@ -10591,7 +10591,7 @@ ia64_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
switch (fcode)
{
diff --git a/gcc/config/iq2000/iq2000.c b/gcc/config/iq2000/iq2000.c
index c3be6fa..ad21f1c 100644
--- a/gcc/config/iq2000/iq2000.c
+++ b/gcc/config/iq2000/iq2000.c
@@ -2707,7 +2707,7 @@ iq2000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- int fcode = DECL_FUNCTION_CODE (fndecl);
+ int fcode = DECL_MD_FUNCTION_CODE (fndecl);
enum rtx_code code [5];
code[0] = REG;
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index e0535b1..45ddec1 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -17215,7 +17215,7 @@ mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
const struct mips_builtin_description *d;
fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- fcode = DECL_FUNCTION_CODE (fndecl);
+ fcode = DECL_MD_FUNCTION_CODE (fndecl);
gcc_assert (fcode < ARRAY_SIZE (mips_builtins));
d = &mips_builtins[fcode];
avail = d->avail ();
diff --git a/gcc/config/msp430/driver-msp430.c b/gcc/config/msp430/driver-msp430.c
index 5583db6e..0a3d1e1 100644
--- a/gcc/config/msp430/driver-msp430.c
+++ b/gcc/config/msp430/driver-msp430.c
@@ -25,673 +25,104 @@
#include "coretypes.h"
#include "diagnostic.h"
#include "tm.h"
+#include "msp430-devices.h"
-/* This is a copy of the same data structure found in gas/config/tc-msp430.c
- Also another (sort-of) copy can be found in gcc/config/msp430/msp430.c
- Keep these three structures in sync.
- The data in this structure has been extracted from version 1.194 of the
- devices.csv file released by TI in September 2016. */
-
-struct msp430_mcu_data
+/* This spec function is called if the user has provided an -mmcu option without
+ an -mcpu option. It will place the correct -mcpu option for the given -mmcu
+ onto the command line, to ensure the correct ISA multilib is selected. */
+const char *
+msp430_select_cpu (int argc, const char ** argv)
{
- const char * name;
- unsigned int revision; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
- unsigned int hwmpy; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */
+ if (argc == 0)
+ {
+ error ("expected an argument to %<msp430_select_cpu%>");
+ return NULL;
+ }
+ msp430_extract_mcu_data (argv[0]);
+ if (extracted_mcu_data.name != NULL)
+ {
+ switch (extracted_mcu_data.revision)
+ {
+ case 0: return "-mcpu=msp430";
+ case 1: return "-mcpu=msp430x";
+ case 2: return "-mcpu=msp430xv2";
+ default:
+ gcc_unreachable ();
+ }
+ }
+ /* MCU wasn't found, the compiler proper will warn about this. */
+ return NULL;
}
-msp430_mcu_data [] =
+
+/* Spec function to set a global variable to a specific value in the driver.
+ The first argument is the variable name, and the second is the value to set
+ it to.
+ Currently only "msp430_warn_devices_csv" and "msp430_devices_csv_loc" are
+ supported.
+ The intention is that we can take a "Target" option and set the variable
+ associated with it in the driver as well. Whilst the driver sees "Target"
+ options, it does not set the variables associated with that option. */
+const char *
+msp430_set_driver_var (int argc, const char ** argv)
{
- { "cc430f5123",2,8 },
- { "cc430f5125",2,8 },
- { "cc430f5133",2,8 },
- { "cc430f5135",2,8 },
- { "cc430f5137",2,8 },
- { "cc430f5143",2,8 },
- { "cc430f5145",2,8 },
- { "cc430f5147",2,8 },
- { "cc430f6125",2,8 },
- { "cc430f6126",2,8 },
- { "cc430f6127",2,8 },
- { "cc430f6135",2,8 },
- { "cc430f6137",2,8 },
- { "cc430f6143",2,8 },
- { "cc430f6145",2,8 },
- { "cc430f6147",2,8 },
- { "msp430afe221",0,2 },
- { "msp430afe222",0,2 },
- { "msp430afe223",0,2 },
- { "msp430afe231",0,2 },
- { "msp430afe232",0,2 },
- { "msp430afe233",0,2 },
- { "msp430afe251",0,2 },
- { "msp430afe252",0,2 },
- { "msp430afe253",0,2 },
- { "msp430bt5190",2,8 },
- { "msp430c091",0,0 },
- { "msp430c092",0,0 },
- { "msp430c111",0,0 },
- { "msp430c1111",0,0 },
- { "msp430c112",0,0 },
- { "msp430c1121",0,0 },
- { "msp430c1331",0,0 },
- { "msp430c1351",0,0 },
- { "msp430c311s",0,0 },
- { "msp430c312",0,0 },
- { "msp430c313",0,0 },
- { "msp430c314",0,0 },
- { "msp430c315",0,0 },
- { "msp430c323",0,0 },
- { "msp430c325",0,0 },
- { "msp430c336",0,1 },
- { "msp430c337",0,1 },
- { "msp430c412",0,0 },
- { "msp430c413",0,0 },
- { "msp430cg4616",1,1 },
- { "msp430cg4617",1,1 },
- { "msp430cg4618",1,1 },
- { "msp430cg4619",1,1 },
- { "msp430e112",0,0 },
- { "msp430e313",0,0 },
- { "msp430e315",0,0 },
- { "msp430e325",0,0 },
- { "msp430e337",0,1 },
- { "msp430f110",0,0 },
- { "msp430f1101",0,0 },
- { "msp430f1101a",0,0 },
- { "msp430f1111",0,0 },
- { "msp430f1111a",0,0 },
- { "msp430f112",0,0 },
- { "msp430f1121",0,0 },
- { "msp430f1121a",0,0 },
- { "msp430f1122",0,0 },
- { "msp430f1132",0,0 },
- { "msp430f122",0,0 },
- { "msp430f1222",0,0 },
- { "msp430f123",0,0 },
- { "msp430f1232",0,0 },
- { "msp430f133",0,0 },
- { "msp430f135",0,0 },
- { "msp430f147",0,1 },
- { "msp430f1471",0,1 },
- { "msp430f148",0,1 },
- { "msp430f1481",0,1 },
- { "msp430f149",0,1 },
- { "msp430f1491",0,1 },
- { "msp430f155",0,0 },
- { "msp430f156",0,0 },
- { "msp430f157",0,0 },
- { "msp430f1610",0,1 },
- { "msp430f1611",0,1 },
- { "msp430f1612",0,1 },
- { "msp430f167",0,1 },
- { "msp430f168",0,1 },
- { "msp430f169",0,1 },
- { "msp430f2001",0,0 },
- { "msp430f2002",0,0 },
- { "msp430f2003",0,0 },
- { "msp430f2011",0,0 },
- { "msp430f2012",0,0 },
- { "msp430f2013",0,0 },
- { "msp430f2101",0,0 },
- { "msp430f2111",0,0 },
- { "msp430f2112",0,0 },
- { "msp430f2121",0,0 },
- { "msp430f2122",0,0 },
- { "msp430f2131",0,0 },
- { "msp430f2132",0,0 },
- { "msp430f2232",0,0 },
- { "msp430f2234",0,0 },
- { "msp430f2252",0,0 },
- { "msp430f2254",0,0 },
- { "msp430f2272",0,0 },
- { "msp430f2274",0,0 },
- { "msp430f233",0,2 },
- { "msp430f2330",0,2 },
- { "msp430f235",0,2 },
- { "msp430f2350",0,2 },
- { "msp430f2370",0,2 },
- { "msp430f2410",0,2 },
- { "msp430f2416",1,2 },
- { "msp430f2417",1,2 },
- { "msp430f2418",1,2 },
- { "msp430f2419",1,2 },
- { "msp430f247",0,2 },
- { "msp430f2471",0,2 },
- { "msp430f248",0,2 },
- { "msp430f2481",0,2 },
- { "msp430f249",0,2 },
- { "msp430f2491",0,2 },
- { "msp430f2616",1,2 },
- { "msp430f2617",1,2 },
- { "msp430f2618",1,2 },
- { "msp430f2619",1,2 },
- { "msp430f412",0,0 },
- { "msp430f413",0,0 },
- { "msp430f4132",0,0 },
- { "msp430f415",0,0 },
- { "msp430f4152",0,0 },
- { "msp430f417",0,0 },
- { "msp430f423",0,1 },
- { "msp430f423a",0,1 },
- { "msp430f425",0,1 },
- { "msp430f4250",0,0 },
- { "msp430f425a",0,1 },
- { "msp430f4260",0,0 },
- { "msp430f427",0,1 },
- { "msp430f4270",0,0 },
- { "msp430f427a",0,1 },
- { "msp430f435",0,0 },
- { "msp430f4351",0,0 },
- { "msp430f436",0,0 },
- { "msp430f4361",0,0 },
- { "msp430f437",0,0 },
- { "msp430f4371",0,0 },
- { "msp430f438",0,0 },
- { "msp430f439",0,0 },
- { "msp430f447",0,1 },
- { "msp430f448",0,1 },
- { "msp430f4481",0,1 },
- { "msp430f449",0,1 },
- { "msp430f4491",0,1 },
- { "msp430f4616",1,1 },
- { "msp430f46161",1,1 },
- { "msp430f4617",1,1 },
- { "msp430f46171",1,1 },
- { "msp430f4618",1,1 },
- { "msp430f46181",1,1 },
- { "msp430f4619",1,1 },
- { "msp430f46191",1,1 },
- { "msp430f47126",1,4 },
- { "msp430f47127",1,4 },
- { "msp430f47163",1,4 },
- { "msp430f47166",1,4 },
- { "msp430f47167",1,4 },
- { "msp430f47173",1,4 },
- { "msp430f47176",1,4 },
- { "msp430f47177",1,4 },
- { "msp430f47183",1,4 },
- { "msp430f47186",1,4 },
- { "msp430f47187",1,4 },
- { "msp430f47193",1,4 },
- { "msp430f47196",1,4 },
- { "msp430f47197",1,4 },
- { "msp430f477",0,0 },
- { "msp430f478",0,0 },
- { "msp430f4783",0,4 },
- { "msp430f4784",0,4 },
- { "msp430f479",0,0 },
- { "msp430f4793",0,4 },
- { "msp430f4794",0,4 },
- { "msp430f5131",2,8 },
- { "msp430f5132",2,8 },
- { "msp430f5151",2,8 },
- { "msp430f5152",2,8 },
- { "msp430f5171",2,8 },
- { "msp430f5172",2,8 },
- { "msp430f5212",2,8 },
- { "msp430f5213",2,8 },
- { "msp430f5214",2,8 },
- { "msp430f5217",2,8 },
- { "msp430f5218",2,8 },
- { "msp430f5219",2,8 },
- { "msp430f5222",2,8 },
- { "msp430f5223",2,8 },
- { "msp430f5224",2,8 },
- { "msp430f5227",2,8 },
- { "msp430f5228",2,8 },
- { "msp430f5229",2,8 },
- { "msp430f5232",2,8 },
- { "msp430f5234",2,8 },
- { "msp430f5237",2,8 },
- { "msp430f5239",2,8 },
- { "msp430f5242",2,8 },
- { "msp430f5244",2,8 },
- { "msp430f5247",2,8 },
- { "msp430f5249",2,8 },
- { "msp430f5252",2,8 },
- { "msp430f5253",2,8 },
- { "msp430f5254",2,8 },
- { "msp430f5255",2,8 },
- { "msp430f5256",2,8 },
- { "msp430f5257",2,8 },
- { "msp430f5258",2,8 },
- { "msp430f5259",2,8 },
- { "msp430f5304",2,8 },
- { "msp430f5308",2,8 },
- { "msp430f5309",2,8 },
- { "msp430f5310",2,8 },
- { "msp430f5324",2,8 },
- { "msp430f5325",2,8 },
- { "msp430f5326",2,8 },
- { "msp430f5327",2,8 },
- { "msp430f5328",2,8 },
- { "msp430f5329",2,8 },
- { "msp430f5333",2,8 },
- { "msp430f5335",2,8 },
- { "msp430f5336",2,8 },
- { "msp430f5338",2,8 },
- { "msp430f5340",2,8 },
- { "msp430f5341",2,8 },
- { "msp430f5342",2,8 },
- { "msp430f5358",2,8 },
- { "msp430f5359",2,8 },
- { "msp430f5418",2,8 },
- { "msp430f5418a",2,8 },
- { "msp430f5419",2,8 },
- { "msp430f5419a",2,8 },
- { "msp430f5435",2,8 },
- { "msp430f5435a",2,8 },
- { "msp430f5436",2,8 },
- { "msp430f5436a",2,8 },
- { "msp430f5437",2,8 },
- { "msp430f5437a",2,8 },
- { "msp430f5438",2,8 },
- { "msp430f5438a",2,8 },
- { "msp430f5500",2,8 },
- { "msp430f5501",2,8 },
- { "msp430f5502",2,8 },
- { "msp430f5503",2,8 },
- { "msp430f5504",2,8 },
- { "msp430f5505",2,8 },
- { "msp430f5506",2,8 },
- { "msp430f5507",2,8 },
- { "msp430f5508",2,8 },
- { "msp430f5509",2,8 },
- { "msp430f5510",2,8 },
- { "msp430f5513",2,8 },
- { "msp430f5514",2,8 },
- { "msp430f5515",2,8 },
- { "msp430f5517",2,8 },
- { "msp430f5519",2,8 },
- { "msp430f5521",2,8 },
- { "msp430f5522",2,8 },
- { "msp430f5524",2,8 },
- { "msp430f5525",2,8 },
- { "msp430f5526",2,8 },
- { "msp430f5527",2,8 },
- { "msp430f5528",2,8 },
- { "msp430f5529",2,8 },
- { "msp430f5630",2,8 },
- { "msp430f5631",2,8 },
- { "msp430f5632",2,8 },
- { "msp430f5633",2,8 },
- { "msp430f5634",2,8 },
- { "msp430f5635",2,8 },
- { "msp430f5636",2,8 },
- { "msp430f5637",2,8 },
- { "msp430f5638",2,8 },
- { "msp430f5658",2,8 },
- { "msp430f5659",2,8 },
- { "msp430f5xx_6xxgeneric",2,8 },
- { "msp430f6433",2,8 },
- { "msp430f6435",2,8 },
- { "msp430f6436",2,8 },
- { "msp430f6438",2,8 },
- { "msp430f6458",2,8 },
- { "msp430f6459",2,8 },
- { "msp430f6630",2,8 },
- { "msp430f6631",2,8 },
- { "msp430f6632",2,8 },
- { "msp430f6633",2,8 },
- { "msp430f6634",2,8 },
- { "msp430f6635",2,8 },
- { "msp430f6636",2,8 },
- { "msp430f6637",2,8 },
- { "msp430f6638",2,8 },
- { "msp430f6658",2,8 },
- { "msp430f6659",2,8 },
- { "msp430f6720",2,8 },
- { "msp430f6720a",2,8 },
- { "msp430f6721",2,8 },
- { "msp430f6721a",2,8 },
- { "msp430f6723",2,8 },
- { "msp430f6723a",2,8 },
- { "msp430f6724",2,8 },
- { "msp430f6724a",2,8 },
- { "msp430f6725",2,8 },
- { "msp430f6725a",2,8 },
- { "msp430f6726",2,8 },
- { "msp430f6726a",2,8 },
- { "msp430f6730",2,8 },
- { "msp430f6730a",2,8 },
- { "msp430f6731",2,8 },
- { "msp430f6731a",2,8 },
- { "msp430f6733",2,8 },
- { "msp430f6733a",2,8 },
- { "msp430f6734",2,8 },
- { "msp430f6734a",2,8 },
- { "msp430f6735",2,8 },
- { "msp430f6735a",2,8 },
- { "msp430f6736",2,8 },
- { "msp430f6736a",2,8 },
- { "msp430f6745",2,8 },
- { "msp430f67451",2,8 },
- { "msp430f67451a",2,8 },
- { "msp430f6745a",2,8 },
- { "msp430f6746",2,8 },
- { "msp430f67461",2,8 },
- { "msp430f67461a",2,8 },
- { "msp430f6746a",2,8 },
- { "msp430f6747",2,8 },
- { "msp430f67471",2,8 },
- { "msp430f67471a",2,8 },
- { "msp430f6747a",2,8 },
- { "msp430f6748",2,8 },
- { "msp430f67481",2,8 },
- { "msp430f67481a",2,8 },
- { "msp430f6748a",2,8 },
- { "msp430f6749",2,8 },
- { "msp430f67491",2,8 },
- { "msp430f67491a",2,8 },
- { "msp430f6749a",2,8 },
- { "msp430f67621",2,8 },
- { "msp430f67621a",2,8 },
- { "msp430f67641",2,8 },
- { "msp430f67641a",2,8 },
- { "msp430f6765",2,8 },
- { "msp430f67651",2,8 },
- { "msp430f67651a",2,8 },
- { "msp430f6765a",2,8 },
- { "msp430f6766",2,8 },
- { "msp430f67661",2,8 },
- { "msp430f67661a",2,8 },
- { "msp430f6766a",2,8 },
- { "msp430f6767",2,8 },
- { "msp430f67671",2,8 },
- { "msp430f67671a",2,8 },
- { "msp430f6767a",2,8 },
- { "msp430f6768",2,8 },
- { "msp430f67681",2,8 },
- { "msp430f67681a",2,8 },
- { "msp430f6768a",2,8 },
- { "msp430f6769",2,8 },
- { "msp430f67691",2,8 },
- { "msp430f67691a",2,8 },
- { "msp430f6769a",2,8 },
- { "msp430f6775",2,8 },
- { "msp430f67751",2,8 },
- { "msp430f67751a",2,8 },
- { "msp430f6775a",2,8 },
- { "msp430f6776",2,8 },
- { "msp430f67761",2,8 },
- { "msp430f67761a",2,8 },
- { "msp430f6776a",2,8 },
- { "msp430f6777",2,8 },
- { "msp430f67771",2,8 },
- { "msp430f67771a",2,8 },
- { "msp430f6777a",2,8 },
- { "msp430f6778",2,8 },
- { "msp430f67781",2,8 },
- { "msp430f67781a",2,8 },
- { "msp430f6778a",2,8 },
- { "msp430f6779",2,8 },
- { "msp430f67791",2,8 },
- { "msp430f67791a",2,8 },
- { "msp430f6779a",2,8 },
- { "msp430fe423",0,0 },
- { "msp430fe4232",0,0 },
- { "msp430fe423a",0,0 },
- { "msp430fe4242",0,0 },
- { "msp430fe425",0,0 },
- { "msp430fe4252",0,0 },
- { "msp430fe425a",0,0 },
- { "msp430fe427",0,0 },
- { "msp430fe4272",0,0 },
- { "msp430fe427a",0,0 },
- { "msp430fg4250",0,0 },
- { "msp430fg4260",0,0 },
- { "msp430fg4270",0,0 },
- { "msp430fg437",0,0 },
- { "msp430fg438",0,0 },
- { "msp430fg439",0,0 },
- { "msp430fg4616",1,1 },
- { "msp430fg4617",1,1 },
- { "msp430fg4618",1,1 },
- { "msp430fg4619",1,1 },
- { "msp430fg477",0,0 },
- { "msp430fg478",0,0 },
- { "msp430fg479",0,0 },
- { "msp430fg6425",2,8 },
- { "msp430fg6426",2,8 },
- { "msp430fg6625",2,8 },
- { "msp430fg6626",2,8 },
- { "msp430fr2032",2,0 },
- { "msp430fr2033",2,0 },
- { "msp430fr2110",2,0 },
- { "msp430fr2111",2,0 },
- { "msp430fr2310",2,0 },
- { "msp430fr2311",2,0 },
- { "msp430fr2433",2,8 },
- { "msp430fr2532",2,8 },
- { "msp430fr2533",2,8 },
- { "msp430fr2632",2,8 },
- { "msp430fr2633",2,8 },
- { "msp430fr2xx_4xxgeneric",2,8 },
- { "msp430fr4131",2,0 },
- { "msp430fr4132",2,0 },
- { "msp430fr4133",2,0 },
- { "msp430fr5720",2,8 },
- { "msp430fr5721",2,8 },
- { "msp430fr5722",2,8 },
- { "msp430fr5723",2,8 },
- { "msp430fr5724",2,8 },
- { "msp430fr5725",2,8 },
- { "msp430fr5726",2,8 },
- { "msp430fr5727",2,8 },
- { "msp430fr5728",2,8 },
- { "msp430fr5729",2,8 },
- { "msp430fr5730",2,8 },
- { "msp430fr5731",2,8 },
- { "msp430fr5732",2,8 },
- { "msp430fr5733",2,8 },
- { "msp430fr5734",2,8 },
- { "msp430fr5735",2,8 },
- { "msp430fr5736",2,8 },
- { "msp430fr5737",2,8 },
- { "msp430fr5738",2,8 },
- { "msp430fr5739",2,8 },
- { "msp430fr57xxgeneric",2,8 },
- { "msp430fr5847",2,8 },
- { "msp430fr58471",2,8 },
- { "msp430fr5848",2,8 },
- { "msp430fr5849",2,8 },
- { "msp430fr5857",2,8 },
- { "msp430fr5858",2,8 },
- { "msp430fr5859",2,8 },
- { "msp430fr5867",2,8 },
- { "msp430fr58671",2,8 },
- { "msp430fr5868",2,8 },
- { "msp430fr5869",2,8 },
- { "msp430fr5870",2,8 },
- { "msp430fr5872",2,8 },
- { "msp430fr58721",2,8 },
- { "msp430fr5887",2,8 },
- { "msp430fr5888",2,8 },
- { "msp430fr5889",2,8 },
- { "msp430fr58891",2,8 },
- { "msp430fr5922",2,8 },
- { "msp430fr59221",2,8 },
- { "msp430fr5947",2,8 },
- { "msp430fr59471",2,8 },
- { "msp430fr5948",2,8 },
- { "msp430fr5949",2,8 },
- { "msp430fr5957",2,8 },
- { "msp430fr5958",2,8 },
- { "msp430fr5959",2,8 },
- { "msp430fr5962",2,8 },
- { "msp430fr5964",2,8 },
- { "msp430fr5967",2,8 },
- { "msp430fr5968",2,8 },
- { "msp430fr5969",2,8 },
- { "msp430fr59691",2,8 },
- { "msp430fr5970",2,8 },
- { "msp430fr5972",2,8 },
- { "msp430fr59721",2,8 },
- { "msp430fr5986",2,8 },
- { "msp430fr5987",2,8 },
- { "msp430fr5988",2,8 },
- { "msp430fr5989",2,8 },
- { "msp430fr59891",2,8 },
- { "msp430fr5992",2,8 },
- { "msp430fr5994",2,8 },
- { "msp430fr59941",2,8 },
- { "msp430fr5xx_6xxgeneric",2,8 },
- { "msp430fr6820",2,8 },
- { "msp430fr6822",2,8 },
- { "msp430fr68221",2,8 },
- { "msp430fr6870",2,8 },
- { "msp430fr6872",2,8 },
- { "msp430fr68721",2,8 },
- { "msp430fr6877",2,8 },
- { "msp430fr6879",2,8 },
- { "msp430fr68791",2,8 },
- { "msp430fr6887",2,8 },
- { "msp430fr6888",2,8 },
- { "msp430fr6889",2,8 },
- { "msp430fr68891",2,8 },
- { "msp430fr6920",2,8 },
- { "msp430fr6922",2,8 },
- { "msp430fr69221",2,8 },
- { "msp430fr6927",2,8 },
- { "msp430fr69271",2,8 },
- { "msp430fr6928",2,8 },
- { "msp430fr6970",2,8 },
- { "msp430fr6972",2,8 },
- { "msp430fr69721",2,8 },
- { "msp430fr6977",2,8 },
- { "msp430fr6979",2,8 },
- { "msp430fr69791",2,8 },
- { "msp430fr6987",2,8 },
- { "msp430fr6988",2,8 },
- { "msp430fr6989",2,8 },
- { "msp430fr69891",2,8 },
- { "msp430fw423",0,0 },
- { "msp430fw425",0,0 },
- { "msp430fw427",0,0 },
- { "msp430fw428",0,0 },
- { "msp430fw429",0,0 },
- { "msp430g2001",0,0 },
- { "msp430g2101",0,0 },
- { "msp430g2102",0,0 },
- { "msp430g2111",0,0 },
- { "msp430g2112",0,0 },
- { "msp430g2113",0,0 },
- { "msp430g2121",0,0 },
- { "msp430g2131",0,0 },
- { "msp430g2132",0,0 },
- { "msp430g2152",0,0 },
- { "msp430g2153",0,0 },
- { "msp430g2201",0,0 },
- { "msp430g2202",0,0 },
- { "msp430g2203",0,0 },
- { "msp430g2210",0,0 },
- { "msp430g2211",0,0 },
- { "msp430g2212",0,0 },
- { "msp430g2213",0,0 },
- { "msp430g2221",0,0 },
- { "msp430g2230",0,0 },
- { "msp430g2231",0,0 },
- { "msp430g2232",0,0 },
- { "msp430g2233",0,0 },
- { "msp430g2252",0,0 },
- { "msp430g2253",0,0 },
- { "msp430g2302",0,0 },
- { "msp430g2303",0,0 },
- { "msp430g2312",0,0 },
- { "msp430g2313",0,0 },
- { "msp430g2332",0,0 },
- { "msp430g2333",0,0 },
- { "msp430g2352",0,0 },
- { "msp430g2353",0,0 },
- { "msp430g2402",0,0 },
- { "msp430g2403",0,0 },
- { "msp430g2412",0,0 },
- { "msp430g2413",0,0 },
- { "msp430g2432",0,0 },
- { "msp430g2433",0,0 },
- { "msp430g2444",0,0 },
- { "msp430g2452",0,0 },
- { "msp430g2453",0,0 },
- { "msp430g2513",0,0 },
- { "msp430g2533",0,0 },
- { "msp430g2544",0,0 },
- { "msp430g2553",0,0 },
- { "msp430g2744",0,0 },
- { "msp430g2755",0,0 },
- { "msp430g2855",0,0 },
- { "msp430g2955",0,0 },
- { "msp430i2020",0,2 },
- { "msp430i2021",0,2 },
- { "msp430i2030",0,2 },
- { "msp430i2031",0,2 },
- { "msp430i2040",0,2 },
- { "msp430i2041",0,2 },
- { "msp430i2xxgeneric",0,2 },
- { "msp430l092",0,0 },
- { "msp430p112",0,0 },
- { "msp430p313",0,0 },
- { "msp430p315",0,0 },
- { "msp430p315s",0,0 },
- { "msp430p325",0,0 },
- { "msp430p337",0,1 },
- { "msp430sl5438a",2,8 },
- { "msp430tch5e",0,0 },
- { "msp430xgeneric",2,8 },
- { "rf430f5144",2,8 },
- { "rf430f5155",2,8 },
- { "rf430f5175",2,8 },
- { "rf430frl152h",0,0 },
- { "rf430frl152h_rom",0,0 },
- { "rf430frl153h",0,0 },
- { "rf430frl153h_rom",0,0 },
- { "rf430frl154h",0,0 },
- { "rf430frl154h_rom",0,0 }
-};
+ if (argc != 2)
+ error ("%<msp430_set_driver_var%> expects 2 arguments");
+ else if (strcmp (argv[0], "msp430_warn_devices_csv") == 0)
+ msp430_warn_devices_csv = atoi (argv[1]);
+ else if (strcmp (argv[0], "msp430_devices_csv_loc") == 0)
+ msp430_devices_csv_loc = argv[1];
+ else
+ error ("unhandled arguments %qs and %qs to %<msp430_set_driver_var%>",
+ argv[0], argv[1]);
+ return NULL;
+}
/* Implement spec function `msp430_hwmult_lib´. */
const char *
-msp430_select_hwmult_lib (int argc ATTRIBUTE_UNUSED, const char ** argv ATTRIBUTE_UNUSED)
+msp430_select_hwmult_lib (int argc ATTRIBUTE_UNUSED,
+ const char ** argv ATTRIBUTE_UNUSED)
{
int i;
switch (argc)
- {
- case 1:
- if (strcasecmp (argv[0], "default"))
- error ("unexpected argument to msp430_select_hwmult_lib: %s", argv[0]);
- break;
+ {
+ case 1:
+ if (strcasecmp (argv[0], "default"))
+ error ("unexpected argument to msp430_select_hwmult_lib: %s", argv[0]);
+ break;
- default:
- /* We can get three or more arguments passed to this function.
- This happens when the same option is repeated on the command line.
- For example:
- msp430-elf-gcc -mhwmult=none -mhwmult=16bit foo.c
- We have to use the last argument as our selector. */
- if (strcasecmp (argv[0], "hwmult") == 0)
- {
- static struct hwmult_options
+ default:
+ /* We can get three or more arguments passed to this function.
+ This happens when the same option is repeated on the command line.
+ For example:
+ msp430-elf-gcc -mhwmult=none -mhwmult=16bit foo.c
+ We have to use the last argument as our selector. */
+ if (strcasecmp (argv[0], "hwmult") == 0)
{
- const char * name;
- const char * lib;
- } hwmult_options [] =
- {
- { "none", "-lmul_none" },
- { "auto", "-lmul_AUTO" }, /* Should not see this one... */
- { "16bit", "-lmul_16" },
- { "32bit", "-lmul_32" },
- { "f5series", "-lmul_f5" }
- };
+ static struct hwmult_options
+ {
+ const char * name;
+ const char * lib;
+ } hwmult_options[] =
+ {
+ { "none", "-lmul_none" },
+ { "auto", "-lmul_AUTO" }, /* Should not see this one... */
+ { "16bit", "-lmul_16" },
+ { "32bit", "-lmul_32" },
+ { "f5series", "-lmul_f5" }
+ };
for (i = ARRAY_SIZE (hwmult_options); i--;)
if (strcasecmp (argv[argc - 1], hwmult_options[i].name) == 0)
return hwmult_options[i].lib;
- }
- else if (strcasecmp (argv[0], "mcu") == 0)
- {
- for (i = ARRAY_SIZE (msp430_mcu_data); i--;)
- if (strcasecmp (argv[argc - 1], msp430_mcu_data[i].name) == 0)
+ }
+ else if (strcasecmp (argv[0], "mcu") == 0)
+ {
+ msp430_extract_mcu_data (argv[argc - 1]);
+ if (extracted_mcu_data.name != NULL)
{
- switch (msp430_mcu_data[i].hwmpy)
+ switch (extracted_mcu_data.hwmpy)
{
case 0: return "-lmul_none";
case 2:
@@ -699,20 +130,22 @@ msp430_select_hwmult_lib (int argc ATTRIBUTE_UNUSED, const char ** argv ATTRIBUT
case 4: return "-lmul_32";
case 8: return "-lmul_f5";
default:
- error ("unrecognized hwpy field in msp430_mcu_data[%d]: %d",
- i, msp430_mcu_data[i].hwmpy);
+ /* We have already checked the hwmpy values for
+ validity in msp430_extract_mcu_data. */
+ gcc_unreachable ();
break;
}
}
- }
- else
- error ("unexpected first argument to msp430_select_hwmult_lib: %s", argv[0]);
- break;
+ }
+ else
+ error ("unexpected first argument to msp430_select_hwmult_lib: %s",
+ argv[0]);
+ break;
+
+ case 0:
+ error ("msp430_select_hwmult_lib needs one or more arguments");
+ break;
+ }
- case 0:
- error ("msp430_select_hwmult_lib needs one or more arguments");
- break;
- }
-
return "-lmul_none";
}
diff --git a/gcc/config/msp430/msp430-devices.c b/gcc/config/msp430/msp430-devices.c
new file mode 100644
index 0000000..537d438
--- /dev/null
+++ b/gcc/config/msp430/msp430-devices.c
@@ -0,0 +1,970 @@
+/* Subroutines used for reading MCU data on TI MSP430 processors.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+ Contributed by Jozef Lawrynowicz <jozef.l@mittosystems.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 "target.h"
+#include "tree.h"
+#include "memmodel.h"
+#include "diagnostic-core.h"
+#include "langhooks.h"
+#include "builtins.h"
+#include "intl.h"
+#include "msp430-devices.h"
+
+struct t_msp430_mcu_data extracted_mcu_data;
+/* Initialized at the bottom of this file. */
+extern struct t_msp430_mcu_data hard_msp430_mcu_data[605];
+
+/* Set to the full path to devices.csv if it is found by searching the -I and
+ -L paths. */
+char * derived_devices_csv_loc = NULL;
+
+/* This is to canonicalize the directory separators in the path.
+ On Windows we could have a mix of '/' and '\' in the path. */
+static void
+canonicalize_path_dirsep (char **path)
+{
+ char *t_path = *path;
+ int len = strlen (t_path);
+ int i;
+ for (i = 0; i < len; i++)
+ if (IS_DIR_SEPARATOR (t_path[i]))
+ t_path[i] = DIR_SEPARATOR;
+}
+
+/* Spec function which searches the paths passed to the -I and -L options for
+ the "devices.csv" file. If it is found then the -mdevices-csv-loc option is
+ placed on the command line so the compiler knows the location of the
+ file. */
+const char *
+msp430_check_path_for_devices (int argc, const char **argv)
+{
+ const char dirsep[2] = { DIR_SEPARATOR, 0 };
+ FILE * devices_file = NULL;
+ char * local_devices_csv_loc = NULL;
+ int i;
+ /* msp430_devices_csv_loc is set by -mdevices-csv-loc, derived_devices_csv_loc
+ is set by this function only. */
+ if (msp430_devices_csv_loc || derived_devices_csv_loc)
+ return NULL;
+ for (i = 0; i < argc; i++)
+ {
+ char *inc_path = ASTRDUP (argv[i]);
+ canonicalize_path_dirsep (&inc_path);
+ if (!IS_DIR_SEPARATOR (inc_path[strlen (inc_path) - 1]))
+ inc_path = concat (inc_path, dirsep, NULL);
+ local_devices_csv_loc = concat (inc_path, "devices.csv", NULL);
+ devices_file = fopen (local_devices_csv_loc, "r");
+ if (devices_file != NULL)
+ {
+ fclose (devices_file);
+ derived_devices_csv_loc = local_devices_csv_loc;
+ return concat ("-mdevices-csv-loc=", local_devices_csv_loc, NULL);
+ }
+ }
+ return NULL;
+}
+
+/* Search the devices.csv file for the given MCU name, and load the device
+ data into extracted_mcu_data.
+ Return 1 if MCU wasn't found in devices.csv, or the data couldn't be loaded
+ into extracted_mcu_data.
+ devices.csv has a specific format. There is a row for column headings which
+ begins with "# Device Name". The column numbers for CPU_TYPE (MSP430 ISA)
+ and MPY_TYPE (hwmult support) are extracted from this row and used later to
+ extract the ISA and hwmult supported for the given device.
+ The rows containing the MCU data are expected to begin immediately after the
+ column headings. */
+static int
+parse_devices_csv_1 (const char * real_devices_csv_loc, const char * mcu_name)
+{
+ FILE * devices_file = fopen (real_devices_csv_loc, "r");
+ /* Some devices have a large number of errata, which means that MPY_TYPE
+ isn't found until the ~100th character in the line. line_buf_size is set
+ to 200 to account for further possible additions to errata. */
+ const size_t line_buf_size = 200;
+ char line[line_buf_size];
+ char * res;
+ bool found_headings = false;
+ bool found_mcu = false;
+ int cpu_type = -1;
+ int mpy_type = -1;
+ int cpu_type_column = -1;
+ int mpy_type_column = -1;
+ const char * device_name_heading = "# Device Name";
+ const char * cpu_type_heading = "CPU_TYPE";
+ const char * mpy_type_heading = "MPY_TYPE";
+ /* devices_file should never be NULL at this stage. */
+ if (devices_file == NULL)
+ {
+ if (msp430_warn_devices_csv)
+ warning (0, "unexpected error opening %<devices.csv%>");
+ return 1;
+ }
+ while (1)
+ {
+ res = fgets (line, line_buf_size, devices_file);
+ if (res == NULL)
+ {
+ /* The device has not been found in devices.csv. Don't warn now in
+ case it is in the hard-coded data. We will warn later if the
+ device was not found in the hard-coded data either. */
+ goto end;
+ }
+ else if (!found_headings
+ && strncmp (line, device_name_heading,
+ strlen (device_name_heading)) == 0)
+ {
+ int curr_column = 0;
+ char * heading = strtok (line, ",");
+ found_headings = true;
+ /* Find which column MPY_TYPE and CPU_TYPE are in. */
+ while (heading != NULL)
+ {
+ if (strncmp (heading, cpu_type_heading,
+ strlen (cpu_type_heading)) == 0)
+ cpu_type_column = curr_column;
+ else if (strncmp (heading, mpy_type_heading,
+ strlen (mpy_type_heading)) == 0)
+ mpy_type_column = curr_column;
+ if (cpu_type_column != -1 && mpy_type_column != -1)
+ break;
+ heading = strtok (NULL, ",");
+ curr_column++;
+ }
+ if (cpu_type_column == -1 || mpy_type_column == -1)
+ {
+ if (msp430_warn_devices_csv)
+ {
+ if (cpu_type_column == -1 && mpy_type_column != -1)
+ warning (0, "%<CPU_TYPE%> column heading is missing from "
+ "%<devices.csv%>");
+ else if (mpy_type_column == -1 && cpu_type_column != -1)
+ warning (0, "%<MPY_TYPE%> column heading is missing from "
+ "%<devices.csv%>");
+ else
+ warning (0, "%<CPU_TYPE%> and %<MPY_TYPE%> column headings "
+ "are missing from %<devices.csv%>");
+ }
+ goto end;
+ }
+ }
+ else if (strncasecmp (line, mcu_name, strlen (mcu_name)) == 0
+ && *(line + strlen (mcu_name)) == ',')
+ {
+ if (!found_headings)
+ {
+ if (msp430_warn_devices_csv)
+ warning (0, "format of column headings in %<devices.csv%> "
+ "is incorrect");
+ goto end;
+ }
+ char * val = strtok (line, ",");
+ int final_col_num = ((mpy_type_column > cpu_type_column)
+ ? mpy_type_column : cpu_type_column);
+ int curr_col;
+ bool found_cpu = false;
+ bool found_mpy = false;
+ for (curr_col = 0; curr_col <= final_col_num; curr_col++)
+ {
+ /* Strip any new line characters from the last token. */
+ if (curr_col == final_col_num && strlen (val) > 1
+ /* ASCII digit 10 == LF, 13 == CR. */
+ && (val[1] == 10 || val[1] == 13))
+ {
+ /* Terminate the string after the first character. */
+ val[1] = 0;
+ }
+ if (curr_col == cpu_type_column)
+ {
+ cpu_type = atoi (val);
+ /* Only a single '0', '1' or '2' is accepted. */
+ if (strlen (val) != 1
+ /* atoi will return 0 if the string passed as an argument
+ is empty or contains only whitespace characters, so we
+ must error if 0 is returned but the first character in
+ the original string is not '0'. */
+ || (cpu_type == 0 && val[0] != '0')
+ || cpu_type > 2 || cpu_type < 0)
+ {
+ if (msp430_warn_devices_csv)
+ warning (0, "invalid %<CPU_TYPE%> value of %qs read "
+ "from %<devices.csv%> for %qs", val, mcu_name);
+ goto end;
+ }
+ extracted_mcu_data.revision = cpu_type;
+ found_cpu = true;
+ }
+ else if (curr_col == mpy_type_column)
+ {
+ mpy_type = atoi (val);
+ /* Only a single '0', '1', '2', '4' or '8' is accepted. */
+ if (strlen (val) != 1
+ || (mpy_type == 0 && val[0] != '0')
+ || !(mpy_type == 0
+ || mpy_type == 1
+ || mpy_type == 2
+ || mpy_type == 4
+ || mpy_type == 8))
+ {
+ if (msp430_warn_devices_csv)
+ warning (0, "invalid %<MPY_TYPE%> value of %qs read "
+ "from %<devices.csv%> for %qs", val, mcu_name);
+ goto end;
+ }
+ extracted_mcu_data.hwmpy = mpy_type;
+ found_mpy = true;
+ }
+ if (found_cpu && found_mpy)
+ {
+ extracted_mcu_data.name = mcu_name;
+ found_mcu = true;
+ goto end;
+ }
+ val = strtok (NULL, ",");
+ }
+ if (msp430_warn_devices_csv && (cpu_type == -1 || mpy_type == -1))
+ warning (0, "unknown error reading %s from "
+ "%<devices.csv%>",
+ (cpu_type != -1 ? "%<MPY_TYPE%>"
+ : (mpy_type != -1 ? "%<CPU_TYPE%>"
+ : "%<CPU_TYPE%> and %<MPY_TYPE%>")));
+ goto end;
+ }
+ }
+end:
+ fclose (devices_file);
+ if (!found_mcu)
+ return 1;
+ return 0;
+}
+
+/* Wrapper for the parse_devices_csv_1 work function.
+ A return code of 0 indicates that the MCU data has been successfully
+ extracted into extracted_mcu_data.
+ A return code of 1 indicates that the specified MCU wasn't found in
+ devices.csv.
+ A return code of 2 indicates that devices.csv wasn't found at all. */
+static int
+parse_devices_csv (const char * mcu_name)
+{
+ /* First check if the path to devices.csv was set by -mdevices-csv-loc. */
+ if (msp430_devices_csv_loc != NULL)
+ return parse_devices_csv_1 (msp430_devices_csv_loc, mcu_name);
+ /* Otherwise check if the path to devices.csv was found another way. */
+ else if (derived_devices_csv_loc != NULL)
+ return parse_devices_csv_1 (derived_devices_csv_loc, mcu_name);
+ /* devices.csv was not found. */
+ return 2;
+}
+
+/* Main entry point to load the MCU data for the given -mmcu into
+ extracted_mcu_data.
+ First, the "devices.csv" MCU data file is searched for, if it is found, and
+ the MCU has a record in it, then that data is used.
+ Otherwise, hard_msp430_mcu_data (initialized at the bottom of this
+ file) is searched for the MCU name.
+ This function only needs to be executed once, but it can be first called
+ from a number of different locations. */
+void
+msp430_extract_mcu_data (const char * mcu_name)
+{
+ static int executed = 0;
+ int devices_csv_not_found = 0;
+ int i;
+ if (mcu_name == NULL || executed == 1)
+ return;
+ executed = 1;
+ /* If parse_devices_csv returns non-zero we need to use the
+ hard-coded data. */
+ switch (parse_devices_csv (mcu_name))
+ {
+ case 0:
+ return;
+ case 1:
+ /* MCU not found in devices.csv. Warn later if it's not in the
+ hard-coded data either. */
+ break;
+ case 2:
+ devices_csv_not_found = 1;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ for (i = ARRAY_SIZE (hard_msp430_mcu_data); i--;)
+ if (strcasecmp (mcu_name, hard_msp430_mcu_data[i].name) == 0)
+ {
+ extracted_mcu_data = hard_msp430_mcu_data[i];
+ break;
+ }
+ /* Validation checks. */
+ if (extracted_mcu_data.name != NULL)
+ {
+ switch (extracted_mcu_data.hwmpy)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 4:
+ case 8: break;
+ default:
+ error ("unrecognized %<hwmpy%> field in "
+ "%<hard_msp430_mcu_data[%d]%>: %qd", i,
+ hard_msp430_mcu_data[i].hwmpy);
+ break;
+ }
+ switch (extracted_mcu_data.revision)
+ {
+ case 0:
+ case 1:
+ case 2: break;
+ default:
+ error ("unrecognized %<revision%> field in "
+ "%<hard_msp430_mcu_data[%d]%>: %qd", i,
+ hard_msp430_mcu_data[i].revision);
+ }
+ }
+ else if (msp430_warn_devices_csv && devices_csv_not_found)
+ warning (0, "could not locate MCU data file %<devices.csv%>");
+ else if (msp430_warn_mcu && extracted_mcu_data.name == NULL)
+ {
+ /* FIXME: We should warn here that the MCU name is unrecognized, but
+ msp430_option_override will warn about an unrecognized MCU as well.
+ The benefit of warning here is that this is code common to both the
+ driver and compiler proper, so a warning will be emitted when
+ assembling/linking via the driver, whilst msp430_option_override will
+ only be called when preprocessing or compiling. */
+ }
+}
+
+/* The data in this structure has been extracted from version 1.194 of the
+ devices.csv file released by TI in September 2016. */
+
+struct t_msp430_mcu_data hard_msp430_mcu_data[605] =
+ {
+ { "cc430f5123",2,8 },
+ { "cc430f5125",2,8 },
+ { "cc430f5133",2,8 },
+ { "cc430f5135",2,8 },
+ { "cc430f5137",2,8 },
+ { "cc430f5143",2,8 },
+ { "cc430f5145",2,8 },
+ { "cc430f5147",2,8 },
+ { "cc430f6125",2,8 },
+ { "cc430f6126",2,8 },
+ { "cc430f6127",2,8 },
+ { "cc430f6135",2,8 },
+ { "cc430f6137",2,8 },
+ { "cc430f6143",2,8 },
+ { "cc430f6145",2,8 },
+ { "cc430f6147",2,8 },
+ { "msp430afe221",0,2 },
+ { "msp430afe222",0,2 },
+ { "msp430afe223",0,2 },
+ { "msp430afe231",0,2 },
+ { "msp430afe232",0,2 },
+ { "msp430afe233",0,2 },
+ { "msp430afe251",0,2 },
+ { "msp430afe252",0,2 },
+ { "msp430afe253",0,2 },
+ { "msp430bt5190",2,8 },
+ { "msp430c091",0,0 },
+ { "msp430c092",0,0 },
+ { "msp430c111",0,0 },
+ { "msp430c1111",0,0 },
+ { "msp430c112",0,0 },
+ { "msp430c1121",0,0 },
+ { "msp430c1331",0,0 },
+ { "msp430c1351",0,0 },
+ { "msp430c311s",0,0 },
+ { "msp430c312",0,0 },
+ { "msp430c313",0,0 },
+ { "msp430c314",0,0 },
+ { "msp430c315",0,0 },
+ { "msp430c323",0,0 },
+ { "msp430c325",0,0 },
+ { "msp430c336",0,1 },
+ { "msp430c337",0,1 },
+ { "msp430c412",0,0 },
+ { "msp430c413",0,0 },
+ { "msp430cg4616",1,1 },
+ { "msp430cg4617",1,1 },
+ { "msp430cg4618",1,1 },
+ { "msp430cg4619",1,1 },
+ { "msp430e112",0,0 },
+ { "msp430e313",0,0 },
+ { "msp430e315",0,0 },
+ { "msp430e325",0,0 },
+ { "msp430e337",0,1 },
+ { "msp430f110",0,0 },
+ { "msp430f1101",0,0 },
+ { "msp430f1101a",0,0 },
+ { "msp430f1111",0,0 },
+ { "msp430f1111a",0,0 },
+ { "msp430f112",0,0 },
+ { "msp430f1121",0,0 },
+ { "msp430f1121a",0,0 },
+ { "msp430f1122",0,0 },
+ { "msp430f1132",0,0 },
+ { "msp430f122",0,0 },
+ { "msp430f1222",0,0 },
+ { "msp430f123",0,0 },
+ { "msp430f1232",0,0 },
+ { "msp430f133",0,0 },
+ { "msp430f135",0,0 },
+ { "msp430f147",0,1 },
+ { "msp430f1471",0,1 },
+ { "msp430f148",0,1 },
+ { "msp430f1481",0,1 },
+ { "msp430f149",0,1 },
+ { "msp430f1491",0,1 },
+ { "msp430f155",0,0 },
+ { "msp430f156",0,0 },
+ { "msp430f157",0,0 },
+ { "msp430f1610",0,1 },
+ { "msp430f1611",0,1 },
+ { "msp430f1612",0,1 },
+ { "msp430f167",0,1 },
+ { "msp430f168",0,1 },
+ { "msp430f169",0,1 },
+ { "msp430f2001",0,0 },
+ { "msp430f2002",0,0 },
+ { "msp430f2003",0,0 },
+ { "msp430f2011",0,0 },
+ { "msp430f2012",0,0 },
+ { "msp430f2013",0,0 },
+ { "msp430f2101",0,0 },
+ { "msp430f2111",0,0 },
+ { "msp430f2112",0,0 },
+ { "msp430f2121",0,0 },
+ { "msp430f2122",0,0 },
+ { "msp430f2131",0,0 },
+ { "msp430f2132",0,0 },
+ { "msp430f2232",0,0 },
+ { "msp430f2234",0,0 },
+ { "msp430f2252",0,0 },
+ { "msp430f2254",0,0 },
+ { "msp430f2272",0,0 },
+ { "msp430f2274",0,0 },
+ { "msp430f233",0,2 },
+ { "msp430f2330",0,2 },
+ { "msp430f235",0,2 },
+ { "msp430f2350",0,2 },
+ { "msp430f2370",0,2 },
+ { "msp430f2410",0,2 },
+ { "msp430f2416",1,2 },
+ { "msp430f2417",1,2 },
+ { "msp430f2418",1,2 },
+ { "msp430f2419",1,2 },
+ { "msp430f247",0,2 },
+ { "msp430f2471",0,2 },
+ { "msp430f248",0,2 },
+ { "msp430f2481",0,2 },
+ { "msp430f249",0,2 },
+ { "msp430f2491",0,2 },
+ { "msp430f2616",1,2 },
+ { "msp430f2617",1,2 },
+ { "msp430f2618",1,2 },
+ { "msp430f2619",1,2 },
+ { "msp430f412",0,0 },
+ { "msp430f413",0,0 },
+ { "msp430f4132",0,0 },
+ { "msp430f415",0,0 },
+ { "msp430f4152",0,0 },
+ { "msp430f417",0,0 },
+ { "msp430f423",0,1 },
+ { "msp430f423a",0,1 },
+ { "msp430f425",0,1 },
+ { "msp430f4250",0,0 },
+ { "msp430f425a",0,1 },
+ { "msp430f4260",0,0 },
+ { "msp430f427",0,1 },
+ { "msp430f4270",0,0 },
+ { "msp430f427a",0,1 },
+ { "msp430f435",0,0 },
+ { "msp430f4351",0,0 },
+ { "msp430f436",0,0 },
+ { "msp430f4361",0,0 },
+ { "msp430f437",0,0 },
+ { "msp430f4371",0,0 },
+ { "msp430f438",0,0 },
+ { "msp430f439",0,0 },
+ { "msp430f447",0,1 },
+ { "msp430f448",0,1 },
+ { "msp430f4481",0,1 },
+ { "msp430f449",0,1 },
+ { "msp430f4491",0,1 },
+ { "msp430f4616",1,1 },
+ { "msp430f46161",1,1 },
+ { "msp430f4617",1,1 },
+ { "msp430f46171",1,1 },
+ { "msp430f4618",1,1 },
+ { "msp430f46181",1,1 },
+ { "msp430f4619",1,1 },
+ { "msp430f46191",1,1 },
+ { "msp430f47126",1,4 },
+ { "msp430f47127",1,4 },
+ { "msp430f47163",1,4 },
+ { "msp430f47166",1,4 },
+ { "msp430f47167",1,4 },
+ { "msp430f47173",1,4 },
+ { "msp430f47176",1,4 },
+ { "msp430f47177",1,4 },
+ { "msp430f47183",1,4 },
+ { "msp430f47186",1,4 },
+ { "msp430f47187",1,4 },
+ { "msp430f47193",1,4 },
+ { "msp430f47196",1,4 },
+ { "msp430f47197",1,4 },
+ { "msp430f477",0,0 },
+ { "msp430f478",0,0 },
+ { "msp430f4783",0,4 },
+ { "msp430f4784",0,4 },
+ { "msp430f479",0,0 },
+ { "msp430f4793",0,4 },
+ { "msp430f4794",0,4 },
+ { "msp430f5131",2,8 },
+ { "msp430f5132",2,8 },
+ { "msp430f5151",2,8 },
+ { "msp430f5152",2,8 },
+ { "msp430f5171",2,8 },
+ { "msp430f5172",2,8 },
+ { "msp430f5212",2,8 },
+ { "msp430f5213",2,8 },
+ { "msp430f5214",2,8 },
+ { "msp430f5217",2,8 },
+ { "msp430f5218",2,8 },
+ { "msp430f5219",2,8 },
+ { "msp430f5222",2,8 },
+ { "msp430f5223",2,8 },
+ { "msp430f5224",2,8 },
+ { "msp430f5227",2,8 },
+ { "msp430f5228",2,8 },
+ { "msp430f5229",2,8 },
+ { "msp430f5232",2,8 },
+ { "msp430f5234",2,8 },
+ { "msp430f5237",2,8 },
+ { "msp430f5239",2,8 },
+ { "msp430f5242",2,8 },
+ { "msp430f5244",2,8 },
+ { "msp430f5247",2,8 },
+ { "msp430f5249",2,8 },
+ { "msp430f5252",2,8 },
+ { "msp430f5253",2,8 },
+ { "msp430f5254",2,8 },
+ { "msp430f5255",2,8 },
+ { "msp430f5256",2,8 },
+ { "msp430f5257",2,8 },
+ { "msp430f5258",2,8 },
+ { "msp430f5259",2,8 },
+ { "msp430f5304",2,8 },
+ { "msp430f5308",2,8 },
+ { "msp430f5309",2,8 },
+ { "msp430f5310",2,8 },
+ { "msp430f5324",2,8 },
+ { "msp430f5325",2,8 },
+ { "msp430f5326",2,8 },
+ { "msp430f5327",2,8 },
+ { "msp430f5328",2,8 },
+ { "msp430f5329",2,8 },
+ { "msp430f5333",2,8 },
+ { "msp430f5335",2,8 },
+ { "msp430f5336",2,8 },
+ { "msp430f5338",2,8 },
+ { "msp430f5340",2,8 },
+ { "msp430f5341",2,8 },
+ { "msp430f5342",2,8 },
+ { "msp430f5358",2,8 },
+ { "msp430f5359",2,8 },
+ { "msp430f5418",2,8 },
+ { "msp430f5418a",2,8 },
+ { "msp430f5419",2,8 },
+ { "msp430f5419a",2,8 },
+ { "msp430f5435",2,8 },
+ { "msp430f5435a",2,8 },
+ { "msp430f5436",2,8 },
+ { "msp430f5436a",2,8 },
+ { "msp430f5437",2,8 },
+ { "msp430f5437a",2,8 },
+ { "msp430f5438",2,8 },
+ { "msp430f5438a",2,8 },
+ { "msp430f5500",2,8 },
+ { "msp430f5501",2,8 },
+ { "msp430f5502",2,8 },
+ { "msp430f5503",2,8 },
+ { "msp430f5504",2,8 },
+ { "msp430f5505",2,8 },
+ { "msp430f5506",2,8 },
+ { "msp430f5507",2,8 },
+ { "msp430f5508",2,8 },
+ { "msp430f5509",2,8 },
+ { "msp430f5510",2,8 },
+ { "msp430f5513",2,8 },
+ { "msp430f5514",2,8 },
+ { "msp430f5515",2,8 },
+ { "msp430f5517",2,8 },
+ { "msp430f5519",2,8 },
+ { "msp430f5521",2,8 },
+ { "msp430f5522",2,8 },
+ { "msp430f5524",2,8 },
+ { "msp430f5525",2,8 },
+ { "msp430f5526",2,8 },
+ { "msp430f5527",2,8 },
+ { "msp430f5528",2,8 },
+ { "msp430f5529",2,8 },
+ { "msp430f5630",2,8 },
+ { "msp430f5631",2,8 },
+ { "msp430f5632",2,8 },
+ { "msp430f5633",2,8 },
+ { "msp430f5634",2,8 },
+ { "msp430f5635",2,8 },
+ { "msp430f5636",2,8 },
+ { "msp430f5637",2,8 },
+ { "msp430f5638",2,8 },
+ { "msp430f5658",2,8 },
+ { "msp430f5659",2,8 },
+ { "msp430f5xx_6xxgeneric",2,8 },
+ { "msp430f6433",2,8 },
+ { "msp430f6435",2,8 },
+ { "msp430f6436",2,8 },
+ { "msp430f6438",2,8 },
+ { "msp430f6458",2,8 },
+ { "msp430f6459",2,8 },
+ { "msp430f6630",2,8 },
+ { "msp430f6631",2,8 },
+ { "msp430f6632",2,8 },
+ { "msp430f6633",2,8 },
+ { "msp430f6634",2,8 },
+ { "msp430f6635",2,8 },
+ { "msp430f6636",2,8 },
+ { "msp430f6637",2,8 },
+ { "msp430f6638",2,8 },
+ { "msp430f6658",2,8 },
+ { "msp430f6659",2,8 },
+ { "msp430f6720",2,8 },
+ { "msp430f6720a",2,8 },
+ { "msp430f6721",2,8 },
+ { "msp430f6721a",2,8 },
+ { "msp430f6723",2,8 },
+ { "msp430f6723a",2,8 },
+ { "msp430f6724",2,8 },
+ { "msp430f6724a",2,8 },
+ { "msp430f6725",2,8 },
+ { "msp430f6725a",2,8 },
+ { "msp430f6726",2,8 },
+ { "msp430f6726a",2,8 },
+ { "msp430f6730",2,8 },
+ { "msp430f6730a",2,8 },
+ { "msp430f6731",2,8 },
+ { "msp430f6731a",2,8 },
+ { "msp430f6733",2,8 },
+ { "msp430f6733a",2,8 },
+ { "msp430f6734",2,8 },
+ { "msp430f6734a",2,8 },
+ { "msp430f6735",2,8 },
+ { "msp430f6735a",2,8 },
+ { "msp430f6736",2,8 },
+ { "msp430f6736a",2,8 },
+ { "msp430f6745",2,8 },
+ { "msp430f67451",2,8 },
+ { "msp430f67451a",2,8 },
+ { "msp430f6745a",2,8 },
+ { "msp430f6746",2,8 },
+ { "msp430f67461",2,8 },
+ { "msp430f67461a",2,8 },
+ { "msp430f6746a",2,8 },
+ { "msp430f6747",2,8 },
+ { "msp430f67471",2,8 },
+ { "msp430f67471a",2,8 },
+ { "msp430f6747a",2,8 },
+ { "msp430f6748",2,8 },
+ { "msp430f67481",2,8 },
+ { "msp430f67481a",2,8 },
+ { "msp430f6748a",2,8 },
+ { "msp430f6749",2,8 },
+ { "msp430f67491",2,8 },
+ { "msp430f67491a",2,8 },
+ { "msp430f6749a",2,8 },
+ { "msp430f67621",2,8 },
+ { "msp430f67621a",2,8 },
+ { "msp430f67641",2,8 },
+ { "msp430f67641a",2,8 },
+ { "msp430f6765",2,8 },
+ { "msp430f67651",2,8 },
+ { "msp430f67651a",2,8 },
+ { "msp430f6765a",2,8 },
+ { "msp430f6766",2,8 },
+ { "msp430f67661",2,8 },
+ { "msp430f67661a",2,8 },
+ { "msp430f6766a",2,8 },
+ { "msp430f6767",2,8 },
+ { "msp430f67671",2,8 },
+ { "msp430f67671a",2,8 },
+ { "msp430f6767a",2,8 },
+ { "msp430f6768",2,8 },
+ { "msp430f67681",2,8 },
+ { "msp430f67681a",2,8 },
+ { "msp430f6768a",2,8 },
+ { "msp430f6769",2,8 },
+ { "msp430f67691",2,8 },
+ { "msp430f67691a",2,8 },
+ { "msp430f6769a",2,8 },
+ { "msp430f6775",2,8 },
+ { "msp430f67751",2,8 },
+ { "msp430f67751a",2,8 },
+ { "msp430f6775a",2,8 },
+ { "msp430f6776",2,8 },
+ { "msp430f67761",2,8 },
+ { "msp430f67761a",2,8 },
+ { "msp430f6776a",2,8 },
+ { "msp430f6777",2,8 },
+ { "msp430f67771",2,8 },
+ { "msp430f67771a",2,8 },
+ { "msp430f6777a",2,8 },
+ { "msp430f6778",2,8 },
+ { "msp430f67781",2,8 },
+ { "msp430f67781a",2,8 },
+ { "msp430f6778a",2,8 },
+ { "msp430f6779",2,8 },
+ { "msp430f67791",2,8 },
+ { "msp430f67791a",2,8 },
+ { "msp430f6779a",2,8 },
+ { "msp430fe423",0,0 },
+ { "msp430fe4232",0,0 },
+ { "msp430fe423a",0,0 },
+ { "msp430fe4242",0,0 },
+ { "msp430fe425",0,0 },
+ { "msp430fe4252",0,0 },
+ { "msp430fe425a",0,0 },
+ { "msp430fe427",0,0 },
+ { "msp430fe4272",0,0 },
+ { "msp430fe427a",0,0 },
+ { "msp430fg4250",0,0 },
+ { "msp430fg4260",0,0 },
+ { "msp430fg4270",0,0 },
+ { "msp430fg437",0,0 },
+ { "msp430fg438",0,0 },
+ { "msp430fg439",0,0 },
+ { "msp430fg4616",1,1 },
+ { "msp430fg4617",1,1 },
+ { "msp430fg4618",1,1 },
+ { "msp430fg4619",1,1 },
+ { "msp430fg477",0,0 },
+ { "msp430fg478",0,0 },
+ { "msp430fg479",0,0 },
+ { "msp430fg6425",2,8 },
+ { "msp430fg6426",2,8 },
+ { "msp430fg6625",2,8 },
+ { "msp430fg6626",2,8 },
+ { "msp430fr2032",2,0 },
+ { "msp430fr2033",2,0 },
+ { "msp430fr2110",2,0 },
+ { "msp430fr2111",2,0 },
+ { "msp430fr2310",2,0 },
+ { "msp430fr2311",2,0 },
+ { "msp430fr2433",2,8 },
+ { "msp430fr2532",2,8 },
+ { "msp430fr2533",2,8 },
+ { "msp430fr2632",2,8 },
+ { "msp430fr2633",2,8 },
+ { "msp430fr2xx_4xxgeneric",2,8 },
+ { "msp430fr4131",2,0 },
+ { "msp430fr4132",2,0 },
+ { "msp430fr4133",2,0 },
+ { "msp430fr5720",2,8 },
+ { "msp430fr5721",2,8 },
+ { "msp430fr5722",2,8 },
+ { "msp430fr5723",2,8 },
+ { "msp430fr5724",2,8 },
+ { "msp430fr5725",2,8 },
+ { "msp430fr5726",2,8 },
+ { "msp430fr5727",2,8 },
+ { "msp430fr5728",2,8 },
+ { "msp430fr5729",2,8 },
+ { "msp430fr5730",2,8 },
+ { "msp430fr5731",2,8 },
+ { "msp430fr5732",2,8 },
+ { "msp430fr5733",2,8 },
+ { "msp430fr5734",2,8 },
+ { "msp430fr5735",2,8 },
+ { "msp430fr5736",2,8 },
+ { "msp430fr5737",2,8 },
+ { "msp430fr5738",2,8 },
+ { "msp430fr5739",2,8 },
+ { "msp430fr57xxgeneric",2,8 },
+ { "msp430fr5847",2,8 },
+ { "msp430fr58471",2,8 },
+ { "msp430fr5848",2,8 },
+ { "msp430fr5849",2,8 },
+ { "msp430fr5857",2,8 },
+ { "msp430fr5858",2,8 },
+ { "msp430fr5859",2,8 },
+ { "msp430fr5867",2,8 },
+ { "msp430fr58671",2,8 },
+ { "msp430fr5868",2,8 },
+ { "msp430fr5869",2,8 },
+ { "msp430fr5870",2,8 },
+ { "msp430fr5872",2,8 },
+ { "msp430fr58721",2,8 },
+ { "msp430fr5887",2,8 },
+ { "msp430fr5888",2,8 },
+ { "msp430fr5889",2,8 },
+ { "msp430fr58891",2,8 },
+ { "msp430fr5922",2,8 },
+ { "msp430fr59221",2,8 },
+ { "msp430fr5947",2,8 },
+ { "msp430fr59471",2,8 },
+ { "msp430fr5948",2,8 },
+ { "msp430fr5949",2,8 },
+ { "msp430fr5957",2,8 },
+ { "msp430fr5958",2,8 },
+ { "msp430fr5959",2,8 },
+ { "msp430fr5962",2,8 },
+ { "msp430fr5964",2,8 },
+ { "msp430fr5967",2,8 },
+ { "msp430fr5968",2,8 },
+ { "msp430fr5969",2,8 },
+ { "msp430fr59691",2,8 },
+ { "msp430fr5970",2,8 },
+ { "msp430fr5972",2,8 },
+ { "msp430fr59721",2,8 },
+ { "msp430fr5986",2,8 },
+ { "msp430fr5987",2,8 },
+ { "msp430fr5988",2,8 },
+ { "msp430fr5989",2,8 },
+ { "msp430fr59891",2,8 },
+ { "msp430fr5992",2,8 },
+ { "msp430fr5994",2,8 },
+ { "msp430fr59941",2,8 },
+ { "msp430fr5xx_6xxgeneric",2,8 },
+ { "msp430fr6820",2,8 },
+ { "msp430fr6822",2,8 },
+ { "msp430fr68221",2,8 },
+ { "msp430fr6870",2,8 },
+ { "msp430fr6872",2,8 },
+ { "msp430fr68721",2,8 },
+ { "msp430fr6877",2,8 },
+ { "msp430fr6879",2,8 },
+ { "msp430fr68791",2,8 },
+ { "msp430fr6887",2,8 },
+ { "msp430fr6888",2,8 },
+ { "msp430fr6889",2,8 },
+ { "msp430fr68891",2,8 },
+ { "msp430fr6920",2,8 },
+ { "msp430fr6922",2,8 },
+ { "msp430fr69221",2,8 },
+ { "msp430fr6927",2,8 },
+ { "msp430fr69271",2,8 },
+ { "msp430fr6928",2,8 },
+ { "msp430fr6970",2,8 },
+ { "msp430fr6972",2,8 },
+ { "msp430fr69721",2,8 },
+ { "msp430fr6977",2,8 },
+ { "msp430fr6979",2,8 },
+ { "msp430fr69791",2,8 },
+ { "msp430fr6987",2,8 },
+ { "msp430fr6988",2,8 },
+ { "msp430fr6989",2,8 },
+ { "msp430fr69891",2,8 },
+ { "msp430fw423",0,0 },
+ { "msp430fw425",0,0 },
+ { "msp430fw427",0,0 },
+ { "msp430fw428",0,0 },
+ { "msp430fw429",0,0 },
+ { "msp430g2001",0,0 },
+ { "msp430g2101",0,0 },
+ { "msp430g2102",0,0 },
+ { "msp430g2111",0,0 },
+ { "msp430g2112",0,0 },
+ { "msp430g2113",0,0 },
+ { "msp430g2121",0,0 },
+ { "msp430g2131",0,0 },
+ { "msp430g2132",0,0 },
+ { "msp430g2152",0,0 },
+ { "msp430g2153",0,0 },
+ { "msp430g2201",0,0 },
+ { "msp430g2202",0,0 },
+ { "msp430g2203",0,0 },
+ { "msp430g2210",0,0 },
+ { "msp430g2211",0,0 },
+ { "msp430g2212",0,0 },
+ { "msp430g2213",0,0 },
+ { "msp430g2221",0,0 },
+ { "msp430g2230",0,0 },
+ { "msp430g2231",0,0 },
+ { "msp430g2232",0,0 },
+ { "msp430g2233",0,0 },
+ { "msp430g2252",0,0 },
+ { "msp430g2253",0,0 },
+ { "msp430g2302",0,0 },
+ { "msp430g2303",0,0 },
+ { "msp430g2312",0,0 },
+ { "msp430g2313",0,0 },
+ { "msp430g2332",0,0 },
+ { "msp430g2333",0,0 },
+ { "msp430g2352",0,0 },
+ { "msp430g2353",0,0 },
+ { "msp430g2402",0,0 },
+ { "msp430g2403",0,0 },
+ { "msp430g2412",0,0 },
+ { "msp430g2413",0,0 },
+ { "msp430g2432",0,0 },
+ { "msp430g2433",0,0 },
+ { "msp430g2444",0,0 },
+ { "msp430g2452",0,0 },
+ { "msp430g2453",0,0 },
+ { "msp430g2513",0,0 },
+ { "msp430g2533",0,0 },
+ { "msp430g2544",0,0 },
+ { "msp430g2553",0,0 },
+ { "msp430g2744",0,0 },
+ { "msp430g2755",0,0 },
+ { "msp430g2855",0,0 },
+ { "msp430g2955",0,0 },
+ { "msp430i2020",0,2 },
+ { "msp430i2021",0,2 },
+ { "msp430i2030",0,2 },
+ { "msp430i2031",0,2 },
+ { "msp430i2040",0,2 },
+ { "msp430i2041",0,2 },
+ { "msp430i2xxgeneric",0,2 },
+ { "msp430l092",0,0 },
+ { "msp430p112",0,0 },
+ { "msp430p313",0,0 },
+ { "msp430p315",0,0 },
+ { "msp430p315s",0,0 },
+ { "msp430p325",0,0 },
+ { "msp430p337",0,1 },
+ { "msp430sl5438a",2,8 },
+ { "msp430tch5e",0,0 },
+ { "msp430xgeneric",2,8 },
+ { "rf430f5144",2,8 },
+ { "rf430f5155",2,8 },
+ { "rf430f5175",2,8 },
+ { "rf430frl152h",0,0 },
+ { "rf430frl152h_rom",0,0 },
+ { "rf430frl153h",0,0 },
+ { "rf430frl153h_rom",0,0 },
+ { "rf430frl154h",0,0 },
+ { "rf430frl154h_rom",0,0 }
+ };
diff --git a/gcc/config/msp430/msp430-devices.h b/gcc/config/msp430/msp430-devices.h
new file mode 100644
index 0000000..08ae1ad
--- /dev/null
+++ b/gcc/config/msp430/msp430-devices.h
@@ -0,0 +1,31 @@
+/* Definitions of subroutines used for reading MCU data on TI MSP430 processors.
+ Copyright (C) 2019 Free Software Foundation, Inc.
+ Contributed by Jozef Lawrynowicz <jozef.l@mittosystems.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/>. */
+
+struct t_msp430_mcu_data
+{
+ const char * name;
+ unsigned int revision; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
+ unsigned int hwmpy; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend. */
+ /* 4=>32-bit, 8=> 32-bit (5xx). */
+};
+
+extern struct t_msp430_mcu_data extracted_mcu_data;
+
+void msp430_extract_mcu_data (const char * mcu_name);
diff --git a/gcc/config/msp430/msp430-protos.h b/gcc/config/msp430/msp430-protos.h
index 5a4d03f..267b6f5 100644
--- a/gcc/config/msp430/msp430-protos.h
+++ b/gcc/config/msp430/msp430-protos.h
@@ -38,7 +38,8 @@ int msp430_initial_elimination_offset (int, int);
bool msp430_is_interrupt_func (void);
const char * msp430x_logical_shift_right (rtx);
const char * msp430_mcu_name (void);
-void msp430_output_aligned_decl_common (FILE *, const tree, const char *, unsigned HOST_WIDE_INT, unsigned);
+void msp430_output_aligned_decl_common (FILE *, const tree, const char *,
+ unsigned HOST_WIDE_INT, unsigned);
void msp430_output_labelref (FILE *, const char *);
void msp430_register_pragmas (void);
rtx msp430_return_addr_rtx (int);
diff --git a/gcc/config/msp430/msp430.c b/gcc/config/msp430/msp430.c
index 265c2f6..fedbdf5 100644
--- a/gcc/config/msp430/msp430.c
+++ b/gcc/config/msp430/msp430.c
@@ -45,6 +45,7 @@
#include "langhooks.h"
#include "builtins.h"
#include "intl.h"
+#include "msp430-devices.h"
/* This file should be included last. */
#include "target-def.h"
@@ -63,7 +64,7 @@ struct GTY(()) machine_function
/* If set, the rest of the fields have been computed. */
int computed;
/* Which registers need to be saved in the pro/epilogue. */
- int need_to_save [FIRST_PSEUDO_REGISTER];
+ int need_to_save[FIRST_PSEUDO_REGISTER];
/* These fields describe the frame layout... */
/* arg pointer */
@@ -95,635 +96,16 @@ msp430_init_machine_status (void)
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE msp430_option_override
-/* This is a copy of the same data structure found in gas/config/tc-msp430.c
- Also another (sort-of) copy can be found in gcc/config/msp430/t-msp430
- Keep these three structures in sync.
- The data in this structure has been extracted from version 1.194 of the
- devices.csv file released by TI in September 2016. */
-
-struct msp430_mcu_data
-{
- const char * name;
- unsigned int revision; /* 0=> MSP430, 1=>MSP430X, 2=> MSP430Xv2. */
- unsigned int hwmpy; /* 0=>none, 1=>16-bit, 2=>16-bit w/sign extend, 4=>32-bit, 8=> 32-bit (5xx). */
-}
-msp430_mcu_data [] =
-{
- { "cc430f5123",2,8 },
- { "cc430f5125",2,8 },
- { "cc430f5133",2,8 },
- { "cc430f5135",2,8 },
- { "cc430f5137",2,8 },
- { "cc430f5143",2,8 },
- { "cc430f5145",2,8 },
- { "cc430f5147",2,8 },
- { "cc430f6125",2,8 },
- { "cc430f6126",2,8 },
- { "cc430f6127",2,8 },
- { "cc430f6135",2,8 },
- { "cc430f6137",2,8 },
- { "cc430f6143",2,8 },
- { "cc430f6145",2,8 },
- { "cc430f6147",2,8 },
- { "msp430afe221",0,2 },
- { "msp430afe222",0,2 },
- { "msp430afe223",0,2 },
- { "msp430afe231",0,2 },
- { "msp430afe232",0,2 },
- { "msp430afe233",0,2 },
- { "msp430afe251",0,2 },
- { "msp430afe252",0,2 },
- { "msp430afe253",0,2 },
- { "msp430bt5190",2,8 },
- { "msp430c091",0,0 },
- { "msp430c092",0,0 },
- { "msp430c111",0,0 },
- { "msp430c1111",0,0 },
- { "msp430c112",0,0 },
- { "msp430c1121",0,0 },
- { "msp430c1331",0,0 },
- { "msp430c1351",0,0 },
- { "msp430c311s",0,0 },
- { "msp430c312",0,0 },
- { "msp430c313",0,0 },
- { "msp430c314",0,0 },
- { "msp430c315",0,0 },
- { "msp430c323",0,0 },
- { "msp430c325",0,0 },
- { "msp430c336",0,1 },
- { "msp430c337",0,1 },
- { "msp430c412",0,0 },
- { "msp430c413",0,0 },
- { "msp430cg4616",1,1 },
- { "msp430cg4617",1,1 },
- { "msp430cg4618",1,1 },
- { "msp430cg4619",1,1 },
- { "msp430e112",0,0 },
- { "msp430e313",0,0 },
- { "msp430e315",0,0 },
- { "msp430e325",0,0 },
- { "msp430e337",0,1 },
- { "msp430f110",0,0 },
- { "msp430f1101",0,0 },
- { "msp430f1101a",0,0 },
- { "msp430f1111",0,0 },
- { "msp430f1111a",0,0 },
- { "msp430f112",0,0 },
- { "msp430f1121",0,0 },
- { "msp430f1121a",0,0 },
- { "msp430f1122",0,0 },
- { "msp430f1132",0,0 },
- { "msp430f122",0,0 },
- { "msp430f1222",0,0 },
- { "msp430f123",0,0 },
- { "msp430f1232",0,0 },
- { "msp430f133",0,0 },
- { "msp430f135",0,0 },
- { "msp430f147",0,1 },
- { "msp430f1471",0,1 },
- { "msp430f148",0,1 },
- { "msp430f1481",0,1 },
- { "msp430f149",0,1 },
- { "msp430f1491",0,1 },
- { "msp430f155",0,0 },
- { "msp430f156",0,0 },
- { "msp430f157",0,0 },
- { "msp430f1610",0,1 },
- { "msp430f1611",0,1 },
- { "msp430f1612",0,1 },
- { "msp430f167",0,1 },
- { "msp430f168",0,1 },
- { "msp430f169",0,1 },
- { "msp430f2001",0,0 },
- { "msp430f2002",0,0 },
- { "msp430f2003",0,0 },
- { "msp430f2011",0,0 },
- { "msp430f2012",0,0 },
- { "msp430f2013",0,0 },
- { "msp430f2101",0,0 },
- { "msp430f2111",0,0 },
- { "msp430f2112",0,0 },
- { "msp430f2121",0,0 },
- { "msp430f2122",0,0 },
- { "msp430f2131",0,0 },
- { "msp430f2132",0,0 },
- { "msp430f2232",0,0 },
- { "msp430f2234",0,0 },
- { "msp430f2252",0,0 },
- { "msp430f2254",0,0 },
- { "msp430f2272",0,0 },
- { "msp430f2274",0,0 },
- { "msp430f233",0,2 },
- { "msp430f2330",0,2 },
- { "msp430f235",0,2 },
- { "msp430f2350",0,2 },
- { "msp430f2370",0,2 },
- { "msp430f2410",0,2 },
- { "msp430f2416",1,2 },
- { "msp430f2417",1,2 },
- { "msp430f2418",1,2 },
- { "msp430f2419",1,2 },
- { "msp430f247",0,2 },
- { "msp430f2471",0,2 },
- { "msp430f248",0,2 },
- { "msp430f2481",0,2 },
- { "msp430f249",0,2 },
- { "msp430f2491",0,2 },
- { "msp430f2616",1,2 },
- { "msp430f2617",1,2 },
- { "msp430f2618",1,2 },
- { "msp430f2619",1,2 },
- { "msp430f412",0,0 },
- { "msp430f413",0,0 },
- { "msp430f4132",0,0 },
- { "msp430f415",0,0 },
- { "msp430f4152",0,0 },
- { "msp430f417",0,0 },
- { "msp430f423",0,1 },
- { "msp430f423a",0,1 },
- { "msp430f425",0,1 },
- { "msp430f4250",0,0 },
- { "msp430f425a",0,1 },
- { "msp430f4260",0,0 },
- { "msp430f427",0,1 },
- { "msp430f4270",0,0 },
- { "msp430f427a",0,1 },
- { "msp430f435",0,0 },
- { "msp430f4351",0,0 },
- { "msp430f436",0,0 },
- { "msp430f4361",0,0 },
- { "msp430f437",0,0 },
- { "msp430f4371",0,0 },
- { "msp430f438",0,0 },
- { "msp430f439",0,0 },
- { "msp430f447",0,1 },
- { "msp430f448",0,1 },
- { "msp430f4481",0,1 },
- { "msp430f449",0,1 },
- { "msp430f4491",0,1 },
- { "msp430f4616",1,1 },
- { "msp430f46161",1,1 },
- { "msp430f4617",1,1 },
- { "msp430f46171",1,1 },
- { "msp430f4618",1,1 },
- { "msp430f46181",1,1 },
- { "msp430f4619",1,1 },
- { "msp430f46191",1,1 },
- { "msp430f47126",1,4 },
- { "msp430f47127",1,4 },
- { "msp430f47163",1,4 },
- { "msp430f47166",1,4 },
- { "msp430f47167",1,4 },
- { "msp430f47173",1,4 },
- { "msp430f47176",1,4 },
- { "msp430f47177",1,4 },
- { "msp430f47183",1,4 },
- { "msp430f47186",1,4 },
- { "msp430f47187",1,4 },
- { "msp430f47193",1,4 },
- { "msp430f47196",1,4 },
- { "msp430f47197",1,4 },
- { "msp430f477",0,0 },
- { "msp430f478",0,0 },
- { "msp430f4783",0,4 },
- { "msp430f4784",0,4 },
- { "msp430f479",0,0 },
- { "msp430f4793",0,4 },
- { "msp430f4794",0,4 },
- { "msp430f5131",2,8 },
- { "msp430f5132",2,8 },
- { "msp430f5151",2,8 },
- { "msp430f5152",2,8 },
- { "msp430f5171",2,8 },
- { "msp430f5172",2,8 },
- { "msp430f5212",2,8 },
- { "msp430f5213",2,8 },
- { "msp430f5214",2,8 },
- { "msp430f5217",2,8 },
- { "msp430f5218",2,8 },
- { "msp430f5219",2,8 },
- { "msp430f5222",2,8 },
- { "msp430f5223",2,8 },
- { "msp430f5224",2,8 },
- { "msp430f5227",2,8 },
- { "msp430f5228",2,8 },
- { "msp430f5229",2,8 },
- { "msp430f5232",2,8 },
- { "msp430f5234",2,8 },
- { "msp430f5237",2,8 },
- { "msp430f5239",2,8 },
- { "msp430f5242",2,8 },
- { "msp430f5244",2,8 },
- { "msp430f5247",2,8 },
- { "msp430f5249",2,8 },
- { "msp430f5252",2,8 },
- { "msp430f5253",2,8 },
- { "msp430f5254",2,8 },
- { "msp430f5255",2,8 },
- { "msp430f5256",2,8 },
- { "msp430f5257",2,8 },
- { "msp430f5258",2,8 },
- { "msp430f5259",2,8 },
- { "msp430f5304",2,8 },
- { "msp430f5308",2,8 },
- { "msp430f5309",2,8 },
- { "msp430f5310",2,8 },
- { "msp430f5324",2,8 },
- { "msp430f5325",2,8 },
- { "msp430f5326",2,8 },
- { "msp430f5327",2,8 },
- { "msp430f5328",2,8 },
- { "msp430f5329",2,8 },
- { "msp430f5333",2,8 },
- { "msp430f5335",2,8 },
- { "msp430f5336",2,8 },
- { "msp430f5338",2,8 },
- { "msp430f5340",2,8 },
- { "msp430f5341",2,8 },
- { "msp430f5342",2,8 },
- { "msp430f5358",2,8 },
- { "msp430f5359",2,8 },
- { "msp430f5418",2,8 },
- { "msp430f5418a",2,8 },
- { "msp430f5419",2,8 },
- { "msp430f5419a",2,8 },
- { "msp430f5435",2,8 },
- { "msp430f5435a",2,8 },
- { "msp430f5436",2,8 },
- { "msp430f5436a",2,8 },
- { "msp430f5437",2,8 },
- { "msp430f5437a",2,8 },
- { "msp430f5438",2,8 },
- { "msp430f5438a",2,8 },
- { "msp430f5500",2,8 },
- { "msp430f5501",2,8 },
- { "msp430f5502",2,8 },
- { "msp430f5503",2,8 },
- { "msp430f5504",2,8 },
- { "msp430f5505",2,8 },
- { "msp430f5506",2,8 },
- { "msp430f5507",2,8 },
- { "msp430f5508",2,8 },
- { "msp430f5509",2,8 },
- { "msp430f5510",2,8 },
- { "msp430f5513",2,8 },
- { "msp430f5514",2,8 },
- { "msp430f5515",2,8 },
- { "msp430f5517",2,8 },
- { "msp430f5519",2,8 },
- { "msp430f5521",2,8 },
- { "msp430f5522",2,8 },
- { "msp430f5524",2,8 },
- { "msp430f5525",2,8 },
- { "msp430f5526",2,8 },
- { "msp430f5527",2,8 },
- { "msp430f5528",2,8 },
- { "msp430f5529",2,8 },
- { "msp430f5630",2,8 },
- { "msp430f5631",2,8 },
- { "msp430f5632",2,8 },
- { "msp430f5633",2,8 },
- { "msp430f5634",2,8 },
- { "msp430f5635",2,8 },
- { "msp430f5636",2,8 },
- { "msp430f5637",2,8 },
- { "msp430f5638",2,8 },
- { "msp430f5658",2,8 },
- { "msp430f5659",2,8 },
- { "msp430f5xx_6xxgeneric",2,8 },
- { "msp430f6433",2,8 },
- { "msp430f6435",2,8 },
- { "msp430f6436",2,8 },
- { "msp430f6438",2,8 },
- { "msp430f6458",2,8 },
- { "msp430f6459",2,8 },
- { "msp430f6630",2,8 },
- { "msp430f6631",2,8 },
- { "msp430f6632",2,8 },
- { "msp430f6633",2,8 },
- { "msp430f6634",2,8 },
- { "msp430f6635",2,8 },
- { "msp430f6636",2,8 },
- { "msp430f6637",2,8 },
- { "msp430f6638",2,8 },
- { "msp430f6658",2,8 },
- { "msp430f6659",2,8 },
- { "msp430f6720",2,8 },
- { "msp430f6720a",2,8 },
- { "msp430f6721",2,8 },
- { "msp430f6721a",2,8 },
- { "msp430f6723",2,8 },
- { "msp430f6723a",2,8 },
- { "msp430f6724",2,8 },
- { "msp430f6724a",2,8 },
- { "msp430f6725",2,8 },
- { "msp430f6725a",2,8 },
- { "msp430f6726",2,8 },
- { "msp430f6726a",2,8 },
- { "msp430f6730",2,8 },
- { "msp430f6730a",2,8 },
- { "msp430f6731",2,8 },
- { "msp430f6731a",2,8 },
- { "msp430f6733",2,8 },
- { "msp430f6733a",2,8 },
- { "msp430f6734",2,8 },
- { "msp430f6734a",2,8 },
- { "msp430f6735",2,8 },
- { "msp430f6735a",2,8 },
- { "msp430f6736",2,8 },
- { "msp430f6736a",2,8 },
- { "msp430f6745",2,8 },
- { "msp430f67451",2,8 },
- { "msp430f67451a",2,8 },
- { "msp430f6745a",2,8 },
- { "msp430f6746",2,8 },
- { "msp430f67461",2,8 },
- { "msp430f67461a",2,8 },
- { "msp430f6746a",2,8 },
- { "msp430f6747",2,8 },
- { "msp430f67471",2,8 },
- { "msp430f67471a",2,8 },
- { "msp430f6747a",2,8 },
- { "msp430f6748",2,8 },
- { "msp430f67481",2,8 },
- { "msp430f67481a",2,8 },
- { "msp430f6748a",2,8 },
- { "msp430f6749",2,8 },
- { "msp430f67491",2,8 },
- { "msp430f67491a",2,8 },
- { "msp430f6749a",2,8 },
- { "msp430f67621",2,8 },
- { "msp430f67621a",2,8 },
- { "msp430f67641",2,8 },
- { "msp430f67641a",2,8 },
- { "msp430f6765",2,8 },
- { "msp430f67651",2,8 },
- { "msp430f67651a",2,8 },
- { "msp430f6765a",2,8 },
- { "msp430f6766",2,8 },
- { "msp430f67661",2,8 },
- { "msp430f67661a",2,8 },
- { "msp430f6766a",2,8 },
- { "msp430f6767",2,8 },
- { "msp430f67671",2,8 },
- { "msp430f67671a",2,8 },
- { "msp430f6767a",2,8 },
- { "msp430f6768",2,8 },
- { "msp430f67681",2,8 },
- { "msp430f67681a",2,8 },
- { "msp430f6768a",2,8 },
- { "msp430f6769",2,8 },
- { "msp430f67691",2,8 },
- { "msp430f67691a",2,8 },
- { "msp430f6769a",2,8 },
- { "msp430f6775",2,8 },
- { "msp430f67751",2,8 },
- { "msp430f67751a",2,8 },
- { "msp430f6775a",2,8 },
- { "msp430f6776",2,8 },
- { "msp430f67761",2,8 },
- { "msp430f67761a",2,8 },
- { "msp430f6776a",2,8 },
- { "msp430f6777",2,8 },
- { "msp430f67771",2,8 },
- { "msp430f67771a",2,8 },
- { "msp430f6777a",2,8 },
- { "msp430f6778",2,8 },
- { "msp430f67781",2,8 },
- { "msp430f67781a",2,8 },
- { "msp430f6778a",2,8 },
- { "msp430f6779",2,8 },
- { "msp430f67791",2,8 },
- { "msp430f67791a",2,8 },
- { "msp430f6779a",2,8 },
- { "msp430fe423",0,0 },
- { "msp430fe4232",0,0 },
- { "msp430fe423a",0,0 },
- { "msp430fe4242",0,0 },
- { "msp430fe425",0,0 },
- { "msp430fe4252",0,0 },
- { "msp430fe425a",0,0 },
- { "msp430fe427",0,0 },
- { "msp430fe4272",0,0 },
- { "msp430fe427a",0,0 },
- { "msp430fg4250",0,0 },
- { "msp430fg4260",0,0 },
- { "msp430fg4270",0,0 },
- { "msp430fg437",0,0 },
- { "msp430fg438",0,0 },
- { "msp430fg439",0,0 },
- { "msp430fg4616",1,1 },
- { "msp430fg4617",1,1 },
- { "msp430fg4618",1,1 },
- { "msp430fg4619",1,1 },
- { "msp430fg477",0,0 },
- { "msp430fg478",0,0 },
- { "msp430fg479",0,0 },
- { "msp430fg6425",2,8 },
- { "msp430fg6426",2,8 },
- { "msp430fg6625",2,8 },
- { "msp430fg6626",2,8 },
- { "msp430fr2032",2,0 },
- { "msp430fr2033",2,0 },
- { "msp430fr2110",2,0 },
- { "msp430fr2111",2,0 },
- { "msp430fr2310",2,0 },
- { "msp430fr2311",2,0 },
- { "msp430fr2433",2,8 },
- { "msp430fr2532",2,8 },
- { "msp430fr2533",2,8 },
- { "msp430fr2632",2,8 },
- { "msp430fr2633",2,8 },
- { "msp430fr2xx_4xxgeneric",2,8 },
- { "msp430fr4131",2,0 },
- { "msp430fr4132",2,0 },
- { "msp430fr4133",2,0 },
- { "msp430fr5720",2,8 },
- { "msp430fr5721",2,8 },
- { "msp430fr5722",2,8 },
- { "msp430fr5723",2,8 },
- { "msp430fr5724",2,8 },
- { "msp430fr5725",2,8 },
- { "msp430fr5726",2,8 },
- { "msp430fr5727",2,8 },
- { "msp430fr5728",2,8 },
- { "msp430fr5729",2,8 },
- { "msp430fr5730",2,8 },
- { "msp430fr5731",2,8 },
- { "msp430fr5732",2,8 },
- { "msp430fr5733",2,8 },
- { "msp430fr5734",2,8 },
- { "msp430fr5735",2,8 },
- { "msp430fr5736",2,8 },
- { "msp430fr5737",2,8 },
- { "msp430fr5738",2,8 },
- { "msp430fr5739",2,8 },
- { "msp430fr57xxgeneric",2,8 },
- { "msp430fr5847",2,8 },
- { "msp430fr58471",2,8 },
- { "msp430fr5848",2,8 },
- { "msp430fr5849",2,8 },
- { "msp430fr5857",2,8 },
- { "msp430fr5858",2,8 },
- { "msp430fr5859",2,8 },
- { "msp430fr5867",2,8 },
- { "msp430fr58671",2,8 },
- { "msp430fr5868",2,8 },
- { "msp430fr5869",2,8 },
- { "msp430fr5870",2,8 },
- { "msp430fr5872",2,8 },
- { "msp430fr58721",2,8 },
- { "msp430fr5887",2,8 },
- { "msp430fr5888",2,8 },
- { "msp430fr5889",2,8 },
- { "msp430fr58891",2,8 },
- { "msp430fr5922",2,8 },
- { "msp430fr59221",2,8 },
- { "msp430fr5947",2,8 },
- { "msp430fr59471",2,8 },
- { "msp430fr5948",2,8 },
- { "msp430fr5949",2,8 },
- { "msp430fr5957",2,8 },
- { "msp430fr5958",2,8 },
- { "msp430fr5959",2,8 },
- { "msp430fr5962",2,8 },
- { "msp430fr5964",2,8 },
- { "msp430fr5967",2,8 },
- { "msp430fr5968",2,8 },
- { "msp430fr5969",2,8 },
- { "msp430fr59691",2,8 },
- { "msp430fr5970",2,8 },
- { "msp430fr5972",2,8 },
- { "msp430fr59721",2,8 },
- { "msp430fr5986",2,8 },
- { "msp430fr5987",2,8 },
- { "msp430fr5988",2,8 },
- { "msp430fr5989",2,8 },
- { "msp430fr59891",2,8 },
- { "msp430fr5992",2,8 },
- { "msp430fr5994",2,8 },
- { "msp430fr59941",2,8 },
- { "msp430fr5xx_6xxgeneric",2,8 },
- { "msp430fr6820",2,8 },
- { "msp430fr6822",2,8 },
- { "msp430fr68221",2,8 },
- { "msp430fr6870",2,8 },
- { "msp430fr6872",2,8 },
- { "msp430fr68721",2,8 },
- { "msp430fr6877",2,8 },
- { "msp430fr6879",2,8 },
- { "msp430fr68791",2,8 },
- { "msp430fr6887",2,8 },
- { "msp430fr6888",2,8 },
- { "msp430fr6889",2,8 },
- { "msp430fr68891",2,8 },
- { "msp430fr6920",2,8 },
- { "msp430fr6922",2,8 },
- { "msp430fr69221",2,8 },
- { "msp430fr6927",2,8 },
- { "msp430fr69271",2,8 },
- { "msp430fr6928",2,8 },
- { "msp430fr6970",2,8 },
- { "msp430fr6972",2,8 },
- { "msp430fr69721",2,8 },
- { "msp430fr6977",2,8 },
- { "msp430fr6979",2,8 },
- { "msp430fr69791",2,8 },
- { "msp430fr6987",2,8 },
- { "msp430fr6988",2,8 },
- { "msp430fr6989",2,8 },
- { "msp430fr69891",2,8 },
- { "msp430fw423",0,0 },
- { "msp430fw425",0,0 },
- { "msp430fw427",0,0 },
- { "msp430fw428",0,0 },
- { "msp430fw429",0,0 },
- { "msp430g2001",0,0 },
- { "msp430g2101",0,0 },
- { "msp430g2102",0,0 },
- { "msp430g2111",0,0 },
- { "msp430g2112",0,0 },
- { "msp430g2113",0,0 },
- { "msp430g2121",0,0 },
- { "msp430g2131",0,0 },
- { "msp430g2132",0,0 },
- { "msp430g2152",0,0 },
- { "msp430g2153",0,0 },
- { "msp430g2201",0,0 },
- { "msp430g2202",0,0 },
- { "msp430g2203",0,0 },
- { "msp430g2210",0,0 },
- { "msp430g2211",0,0 },
- { "msp430g2212",0,0 },
- { "msp430g2213",0,0 },
- { "msp430g2221",0,0 },
- { "msp430g2230",0,0 },
- { "msp430g2231",0,0 },
- { "msp430g2232",0,0 },
- { "msp430g2233",0,0 },
- { "msp430g2252",0,0 },
- { "msp430g2253",0,0 },
- { "msp430g2302",0,0 },
- { "msp430g2303",0,0 },
- { "msp430g2312",0,0 },
- { "msp430g2313",0,0 },
- { "msp430g2332",0,0 },
- { "msp430g2333",0,0 },
- { "msp430g2352",0,0 },
- { "msp430g2353",0,0 },
- { "msp430g2402",0,0 },
- { "msp430g2403",0,0 },
- { "msp430g2412",0,0 },
- { "msp430g2413",0,0 },
- { "msp430g2432",0,0 },
- { "msp430g2433",0,0 },
- { "msp430g2444",0,0 },
- { "msp430g2452",0,0 },
- { "msp430g2453",0,0 },
- { "msp430g2513",0,0 },
- { "msp430g2533",0,0 },
- { "msp430g2544",0,0 },
- { "msp430g2553",0,0 },
- { "msp430g2744",0,0 },
- { "msp430g2755",0,0 },
- { "msp430g2855",0,0 },
- { "msp430g2955",0,0 },
- { "msp430i2020",0,2 },
- { "msp430i2021",0,2 },
- { "msp430i2030",0,2 },
- { "msp430i2031",0,2 },
- { "msp430i2040",0,2 },
- { "msp430i2041",0,2 },
- { "msp430i2xxgeneric",0,2 },
- { "msp430l092",0,0 },
- { "msp430p112",0,0 },
- { "msp430p313",0,0 },
- { "msp430p315",0,0 },
- { "msp430p315s",0,0 },
- { "msp430p325",0,0 },
- { "msp430p337",0,1 },
- { "msp430sl5438a",2,8 },
- { "msp430tch5e",0,0 },
- { "msp430xgeneric",2,8 },
- { "rf430f5144",2,8 },
- { "rf430f5155",2,8 },
- { "rf430f5175",2,8 },
- { "rf430frl152h",0,0 },
- { "rf430frl152h_rom",0,0 },
- { "rf430frl153h",0,0 },
- { "rf430frl153h_rom",0,0 },
- { "rf430frl154h",0,0 },
- { "rf430frl154h_rom",0,0 }
-};
-
/* Generate a C preprocessor symbol based upon the MCU selected by the user.
- If a specific MCU has not been selected then return a generic symbol instead. */
+ If a specific MCU has not been selected then return a generic symbol
+ instead. */
const char *
msp430_mcu_name (void)
{
if (target_mcu)
{
+ msp430_extract_mcu_data (target_mcu);
unsigned int i;
unsigned int start_upper;
unsigned int end_upper;
@@ -768,8 +150,8 @@ hwmult_name (unsigned int val)
static void
msp430_option_override (void)
{
- /* The MSP430 architecture can safely dereference a NULL pointer. In fact,
- there are memory mapped registers there. */
+ /* The MSP430 architecture can safely dereference a NULL pointer. In fact,
+ there are memory mapped registers there. */
flag_delete_null_pointer_checks = 0;
init_machine_status = msp430_init_machine_status;
@@ -786,50 +168,49 @@ msp430_option_override (void)
if (target_mcu)
{
- int i;
-
- /* FIXME: If the array were alpha sorted, we could use a binary search. */
- for (i = ARRAY_SIZE (msp430_mcu_data); i--;)
- if (strcasecmp (msp430_mcu_data[i].name, target_mcu) == 0)
- {
- bool xisa = msp430_mcu_data[i].revision >= 1;
-
- if (msp430_warn_mcu)
- {
- if (target_cpu&& msp430x != xisa)
- warning (0, "MCU %qs supports %s ISA but %<-mcpu%> option "
- "is set to %s",
- target_mcu, xisa ? "430X" : "430", msp430x ? "430X" : "430");
-
- if (msp430_mcu_data[i].hwmpy == 0
- && msp430_hwmult_type != MSP430_HWMULT_AUTO
- && msp430_hwmult_type != MSP430_HWMULT_NONE)
- warning (0, "MCU %qs does not have hardware multiply "
- "support, but %<-mhwmult%> is set to %s",
- target_mcu,
- msp430_hwmult_type == MSP430_HWMULT_SMALL ? "16-bit"
- : msp430_hwmult_type == MSP430_HWMULT_LARGE ? "32-bit" : "f5series");
- else if (msp430_hwmult_type == MSP430_HWMULT_SMALL
- && msp430_mcu_data[i].hwmpy != 1
- && msp430_mcu_data[i].hwmpy != 2 )
- warning (0, "MCU %qs supports %s hardware multiply, "
- "but %<-mhwmult%> is set to 16-bit",
- target_mcu, hwmult_name (msp430_mcu_data[i].hwmpy));
- else if (msp430_hwmult_type == MSP430_HWMULT_LARGE && msp430_mcu_data[i].hwmpy != 4)
- warning (0, "MCU %qs supports %s hardware multiply, "
- "but %<-mhwmult%> is set to 32-bit",
- target_mcu, hwmult_name (msp430_mcu_data[i].hwmpy));
- else if (msp430_hwmult_type == MSP430_HWMULT_F5SERIES && msp430_mcu_data[i].hwmpy != 8)
- warning (0, "MCU %qs supports %s hardware multiply, "
- "but %<-mhwmult%> is set to f5series",
- target_mcu, hwmult_name (msp430_mcu_data[i].hwmpy));
- }
+ msp430_extract_mcu_data (target_mcu);
- msp430x = xisa;
- break;
- }
+ if (extracted_mcu_data.name != NULL)
+ {
+ bool xisa = extracted_mcu_data.revision >= 1;
- if (i < 0)
+ if (msp430_warn_mcu)
+ {
+ if (target_cpu && msp430x != xisa)
+ warning (0, "MCU %qs supports %s ISA but %<-mcpu%> option "
+ "is set to %s",
+ target_mcu, xisa ? "430X" : "430",
+ msp430x ? "430X" : "430");
+
+ if (extracted_mcu_data.hwmpy == 0
+ && msp430_hwmult_type != MSP430_HWMULT_AUTO
+ && msp430_hwmult_type != MSP430_HWMULT_NONE)
+ warning (0, "MCU %qs does not have hardware multiply "
+ "support, but %<-mhwmult%> is set to %s",
+ target_mcu,
+ msp430_hwmult_type == MSP430_HWMULT_SMALL ? "16-bit"
+ : msp430_hwmult_type == MSP430_HWMULT_LARGE
+ ? "32-bit" : "f5series");
+ else if (msp430_hwmult_type == MSP430_HWMULT_SMALL
+ && extracted_mcu_data.hwmpy != 1
+ && extracted_mcu_data.hwmpy != 2)
+ warning (0, "MCU %qs supports %s hardware multiply, "
+ "but %<-mhwmult%> is set to 16-bit",
+ target_mcu, hwmult_name (extracted_mcu_data.hwmpy));
+ else if (msp430_hwmult_type == MSP430_HWMULT_LARGE
+ && extracted_mcu_data.hwmpy != 4)
+ warning (0, "MCU %qs supports %s hardware multiply, "
+ "but %<-mhwmult%> is set to 32-bit",
+ target_mcu, hwmult_name (extracted_mcu_data.hwmpy));
+ else if (msp430_hwmult_type == MSP430_HWMULT_F5SERIES
+ && extracted_mcu_data.hwmpy != 8)
+ warning (0, "MCU %qs supports %s hardware multiply, "
+ "but %<-mhwmult%> is set to f5series",
+ target_mcu, hwmult_name (extracted_mcu_data.hwmpy));
+ }
+ msp430x = xisa;
+ }
+ else
{
if (msp430_hwmult_type == MSP430_HWMULT_AUTO)
{
@@ -869,16 +250,33 @@ msp430_option_override (void)
}
/* The F5 series are all able to support the 430X ISA. */
- if (target_cpu == NULL && target_mcu == NULL && msp430_hwmult_type == MSP430_HWMULT_F5SERIES)
+ if (target_cpu == NULL && target_mcu == NULL
+ && msp430_hwmult_type == MSP430_HWMULT_F5SERIES)
msp430x = true;
if (TARGET_LARGE && !msp430x)
error ("%<-mlarge%> requires a 430X-compatible %<-mmcu=%>");
- if (msp430_code_region == MSP430_REGION_UPPER && ! msp430x)
- error ("%<-mcode-region=upper%> requires 430X-compatible cpu");
- if (msp430_data_region == MSP430_REGION_UPPER && ! msp430x)
- error ("%<-mdata-region=upper%> requires 430X-compatible cpu");
+ if (!TARGET_LARGE && msp430_code_region == MSP430_REGION_EITHER)
+ error ("%<-mcode-region=either%> requires the large memory model "
+ "(%<-mlarge%>)");
+ else if (!TARGET_LARGE && msp430_code_region == MSP430_REGION_UPPER)
+ error ("%<-mcode-region=upper%> requires the large memory model "
+ "(%<-mlarge%>)");
+ else if (!TARGET_LARGE && msp430_code_region == MSP430_REGION_LOWER)
+ error ("%<-mcode-region=lower%> requires the large memory model "
+ "(%<-mlarge%>)");
+
+ if (!TARGET_LARGE && msp430_data_region == MSP430_REGION_EITHER)
+ error ("%<-mdata-region=either%> requires the large memory model "
+ "(%<-mlarge%>)");
+ else if (!TARGET_LARGE && msp430_data_region == MSP430_REGION_UPPER)
+ error ("%<-mdata-region=upper%> requires the large memory model "
+ "(%<-mlarge%>)");
+ else if (!TARGET_LARGE && msp430_data_region == MSP430_REGION_LOWER)
+ error ("%<-mdata-region=lower%> requires the large memory model "
+ "(%<-mlarge%>)");
+
if (flag_exceptions || flag_non_call_exceptions
|| flag_unwind_tables || flag_asynchronous_unwind_tables)
@@ -954,7 +352,7 @@ msp430_hard_regno_nregs_has_padding (int regno ATTRIBUTE_UNUSED,
/* Implements HARD_REGNO_NREGS_WITH_PADDING. */
int
msp430_hard_regno_nregs_with_padding (int regno ATTRIBUTE_UNUSED,
- machine_mode mode)
+ machine_mode mode)
{
if (mode == PSImode)
return 2;
@@ -1027,7 +425,7 @@ msp430_initial_elimination_offset (int from, int to)
/* Allow for the saved return address. */
rv += (TARGET_LARGE ? 4 : 2);
/* NB/ No need to allow for crtl->args.pretend_args_size.
- GCC does that for us. */
+ GCC does that for us. */
break;
default:
gcc_unreachable ();
@@ -1137,7 +535,7 @@ msp430_addr_space_convert (rtx op, tree from_type, tree to_type)
/* For each function, we list the gcc version and the TI version on
each line, where we're converting the function names. */
-static char const * const special_convention_function_names [] =
+static char const * const special_convention_function_names[] =
{
"__muldi3", "__mspabi_mpyll",
"__udivdi3", "__mspabi_divull",
@@ -1162,8 +560,8 @@ msp430_special_register_convention_p (const char *name)
{
int i;
- for (i = 0; special_convention_function_names [i]; i++)
- if (! strcmp (name, special_convention_function_names [i]))
+ for (i = 0; special_convention_function_names[i]; i++)
+ if (!strcmp (name, special_convention_function_names[i]))
return true;
return false;
@@ -1259,7 +657,7 @@ msp430_evaluate_arg (cumulative_args_t cap,
{
case 1:
for (i = 0; i < 4; i++)
- if (! ca->reg_used [i])
+ if (!ca->reg_used[i])
{
ca->reg_count = 1;
ca->start_reg = CA_FIRST_REG + i;
@@ -1268,13 +666,13 @@ msp430_evaluate_arg (cumulative_args_t cap,
break;
case 2:
for (i = 0; i < 3; i++)
- if (! ca->reg_used [i] && ! ca->reg_used [i + 1])
+ if (!ca->reg_used[i] && !ca->reg_used[i + 1])
{
ca->reg_count = 2;
ca->start_reg = CA_FIRST_REG + i;
return;
}
- if (! ca->reg_used [3] && ca->can_split)
+ if (!ca->reg_used[3] && ca->can_split)
{
ca->reg_count = 1;
ca->mem_count = 2;
@@ -1285,10 +683,10 @@ msp430_evaluate_arg (cumulative_args_t cap,
case 3:
case 4:
ca->can_split = 0;
- if (! ca->reg_used [0]
- && ! ca->reg_used [1]
- && ! ca->reg_used [2]
- && ! ca->reg_used [3])
+ if (!ca->reg_used[0]
+ && !ca->reg_used[1]
+ && !ca->reg_used[2]
+ && !ca->reg_used[3])
{
ca->reg_count = 4;
ca->start_reg = CA_FIRST_REG;
@@ -1364,9 +762,9 @@ msp430_pass_by_reference (cumulative_args_t cap ATTRIBUTE_UNUSED,
static bool
msp430_callee_copies (cumulative_args_t cap ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED,
- const_tree type ATTRIBUTE_UNUSED,
- bool named ATTRIBUTE_UNUSED)
+ machine_mode mode ATTRIBUTE_UNUSED,
+ const_tree type ATTRIBUTE_UNUSED,
+ bool named ATTRIBUTE_UNUSED)
{
return true;
}
@@ -1387,7 +785,7 @@ msp430_function_arg_advance (cumulative_args_t cap,
if (ca->start_reg >= CA_FIRST_REG)
for (i = 0; i < ca->reg_count; i ++)
- ca->reg_used [i + ca->start_reg - CA_FIRST_REG] = 1;
+ ca->reg_used[i + ca->start_reg - CA_FIRST_REG] = 1;
ca->special_p = 0;
}
@@ -1410,7 +808,8 @@ msp430_function_arg_boundary (machine_mode mode, const_tree type)
#define TARGET_RETURN_IN_MEMORY msp430_return_in_memory
static bool
-msp430_return_in_memory (const_tree ret_type, const_tree fntype ATTRIBUTE_UNUSED)
+msp430_return_in_memory (const_tree ret_type,
+ const_tree fntype ATTRIBUTE_UNUSED)
{
machine_mode mode = TYPE_MODE (ret_type);
@@ -1451,7 +850,7 @@ msp430_get_raw_result_mode (int regno ATTRIBUTE_UNUSED)
static tree
msp430_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
- gimple_seq *post_p)
+ gimple_seq *post_p)
{
tree addr, t, type_size, rounded_size, valist_tmp;
unsigned HOST_WIDE_INT align, boundary;
@@ -1492,7 +891,8 @@ msp430_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
t = build2 (MODIFY_EXPR, TREE_TYPE (valist), valist_tmp,
fold_build2 (BIT_AND_EXPR, TREE_TYPE (valist),
valist_tmp,
- build_int_cst (TREE_TYPE (valist), -boundary)));
+ build_int_cst (TREE_TYPE (valist),
+ -boundary)));
gimplify_and_add (t, pre_p);
}
}
@@ -1548,7 +948,7 @@ reg_ok_for_addr (rtx r, bool strict)
int rn = REGNO (r);
if (strict && rn >= FIRST_PSEUDO_REGISTER)
- rn = reg_renumber [rn];
+ rn = reg_renumber[rn];
if (strict && 0 <= rn && rn < FIRST_PSEUDO_REGISTER)
return true;
if (!strict)
@@ -1600,7 +1000,8 @@ msp430_legitimate_address_p (machine_mode mode ATTRIBUTE_UNUSED,
}
#undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
-#define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P msp430_addr_space_legitimate_address_p
+#define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
+ msp430_addr_space_legitimate_address_p
bool
msp430_addr_space_legitimate_address_p (machine_mode mode,
@@ -1642,7 +1043,7 @@ msp430_asm_integer (rtx x, unsigned int size, int aligned_p)
static bool
msp430_asm_output_addr_const_extra (FILE *file ATTRIBUTE_UNUSED, rtx x)
{
- debug_rtx(x);
+ debug_rtx (x);
return false;
}
@@ -1657,7 +1058,8 @@ msp430_legitimate_constant (machine_mode mode, rtx x)
/* GCC does not know the width of the PSImode, so make
sure that it does not try to use a constant value that
is out of range. */
- || (INTVAL (x) < (1 << 20) && INTVAL (x) >= (HOST_WIDE_INT)(HOST_WIDE_INT_M1U << 20));
+ || (INTVAL (x) < (1 << 20)
+ && INTVAL (x) >= (HOST_WIDE_INT)(HOST_WIDE_INT_M1U << 20));
}
@@ -1752,7 +1154,7 @@ msp430_preserve_reg_p (int regno)
return true;
/* Shouldn't be more than the above, but just in case... */
- if (fixed_regs [regno])
+ if (fixed_regs[regno])
return false;
/* For interrupt functions we must save and restore the used regs that
@@ -1769,7 +1171,7 @@ msp430_preserve_reg_p (int regno)
return true;
}
- if (!call_used_regs [regno]
+ if (!call_used_regs[regno]
&& df_regs_ever_live_p (regno))
return true;
@@ -1791,11 +1193,11 @@ msp430_compute_frame_info (void)
for (i = 0; i < ARG_POINTER_REGNUM; i ++)
if (msp430_preserve_reg_p (i))
{
- cfun->machine->need_to_save [i] = 1;
+ cfun->machine->need_to_save[i] = 1;
cfun->machine->framesize_regs += (TARGET_LARGE ? 4 : 2);
}
else
- cfun->machine->need_to_save [i] = 0;
+ cfun->machine->need_to_save[i] = 0;
if ((cfun->machine->framesize_locals + cfun->machine->framesize_outgoing) & 1)
cfun->machine->framesize_locals ++;
@@ -1870,11 +1272,12 @@ has_section_name (const char * name, tree decl = current_function_decl)
if (decl == NULL_TREE)
return false;
return (DECL_SECTION_NAME (decl)
- && (strcmp (name, DECL_SECTION_NAME (decl)) == 0));
+ && (strcmp (name, DECL_SECTION_NAME (decl)) == 0));
}
#undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
-#define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS msp430_allocate_stack_slots_for_args
+#define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS \
+ msp430_allocate_stack_slots_for_args
static bool
msp430_allocate_stack_slots_for_args (void)
@@ -1935,8 +1338,8 @@ msp430_attr (tree * node,
default:
warning (OPT_Wattributes,
- "argument of %qE attribute is not a string constant or number",
- name);
+ "argument of %qE attribute is not a string constant "
+ "or number", name);
*no_add_attrs = true;
break;
}
@@ -1996,7 +1399,7 @@ msp430_attr (tree * node,
warning (OPT_Wattributes, message, name);
* no_add_attrs = true;
}
-
+
return NULL_TREE;
}
@@ -2038,12 +1441,23 @@ msp430_section_attr (tree * node,
message = "already marked with 'upper' attribute";
}
+ /* It does not make sense to use upper/lower/either attributes without
+ -mlarge.
+ Without -mlarge, "lower" is the default and only region, so is redundant.
+ Without -mlarge, "upper" will (and "either" might) place code/data in the
+ upper region, which for data could result in relocation overflows, and for
+ code could result in stack mismanagement and incorrect call/return
+ instructions. */
+ if (!TARGET_LARGE)
+ message = G_("%qE attribute ignored. large memory model (%<-mlarge%>) "
+ "is required");
+
if (message)
{
warning (OPT_Wattributes, message, name);
* no_add_attrs = true;
}
-
+
return NULL_TREE;
}
@@ -2065,7 +1479,8 @@ msp430_data_attr (tree * node,
/* Check that it's possible for the variable to have a section. */
if ((TREE_STATIC (* node) || DECL_EXTERNAL (* node) || in_lto_p)
&& DECL_SECTION_NAME (* node))
- message = G_("%qE attribute cannot be applied to variables with specific sections");
+ message = G_("%qE attribute cannot be applied to variables with specific "
+ "sections");
if (!message && TREE_NAME_EQ (name, ATTR_PERSIST) && !TREE_STATIC (* node)
&& !TREE_PUBLIC (* node) && !DECL_EXTERNAL (* node))
@@ -2080,7 +1495,8 @@ msp430_data_attr (tree * node,
set_decl_section_name (* node, ".persistent");
/* If this var is thought to be common, then change this. Common variables
- are assigned to sections before the backend has a chance to process them. */
+ are assigned to sections before the backend has a chance to process
+ them. */
if (DECL_COMMON (* node))
DECL_COMMON (* node) = 0;
@@ -2089,7 +1505,7 @@ msp430_data_attr (tree * node,
warning (OPT_Wattributes, message, name);
* no_add_attrs = true;
}
-
+
return NULL_TREE;
}
@@ -2099,30 +1515,27 @@ msp430_data_attr (tree * node,
/* Table of MSP430-specific attributes. */
const struct attribute_spec msp430_attribute_table[] =
-{
- /* Name min_num_args type_req, handler
- max_num_args, fn_type_req exclude
- decl_req affects_type_identity. */
- { ATTR_INTR, 0, 1, true, false, false, false, msp430_attr, NULL },
- { ATTR_NAKED, 0, 0, true, false, false, false, msp430_attr, NULL },
- { ATTR_REENT, 0, 0, true, false, false, false, msp430_attr, NULL },
- { ATTR_CRIT, 0, 0, true, false, false, false, msp430_attr, NULL },
- { ATTR_WAKEUP, 0, 0, true, false, false, false, msp430_attr, NULL },
-
- { ATTR_LOWER, 0, 0, true, false, false, false, msp430_section_attr,
- NULL },
- { ATTR_UPPER, 0, 0, true, false, false, false, msp430_section_attr,
- NULL },
- { ATTR_EITHER, 0, 0, true, false, false, false, msp430_section_attr,
- NULL },
-
- { ATTR_NOINIT, 0, 0, true, false, false, false, msp430_data_attr,
- NULL },
- { ATTR_PERSIST, 0, 0, true, false, false, false, msp430_data_attr,
- NULL },
-
- { NULL, 0, 0, false, false, false, false, NULL, NULL }
-};
+ {
+ /* { name, min_num_args, max_num_args, decl_req, type_req, fn_type_req,
+ affects_type_identity, handler, exclude } */
+ { ATTR_INTR, 0, 1, true, false, false, false, msp430_attr, NULL },
+ { ATTR_NAKED, 0, 0, true, false, false, false, msp430_attr, NULL },
+ { ATTR_REENT, 0, 0, true, false, false, false, msp430_attr, NULL },
+ { ATTR_CRIT, 0, 0, true, false, false, false, msp430_attr, NULL },
+ { ATTR_WAKEUP, 0, 0, true, false, false, false, msp430_attr, NULL },
+
+ { ATTR_LOWER, 0, 0, true, false, false, false, msp430_section_attr,
+ NULL },
+ { ATTR_UPPER, 0, 0, true, false, false, false, msp430_section_attr,
+ NULL },
+ { ATTR_EITHER, 0, 0, true, false, false, false, msp430_section_attr,
+ NULL },
+
+ { ATTR_PERSIST, 0, 0, true, false, false, false, msp430_data_attr,
+ NULL },
+
+ { NULL, 0, 0, false, false, false, false, NULL, NULL }
+ };
#undef TARGET_ASM_FUNCTION_PROLOGUE
#define TARGET_ASM_FUNCTION_PROLOGUE msp430_start_function
@@ -2150,19 +1563,26 @@ msp430_start_function (FILE *outfile)
fprintf (outfile, "\n");
}
- fprintf (outfile, "; framesize_regs: %d\n", cfun->machine->framesize_regs);
- fprintf (outfile, "; framesize_locals: %d\n", cfun->machine->framesize_locals);
- fprintf (outfile, "; framesize_outgoing: %d\n", cfun->machine->framesize_outgoing);
+ fprintf (outfile, "; framesize_regs: %d\n",
+ cfun->machine->framesize_regs);
+ fprintf (outfile, "; framesize_locals: %d\n",
+ cfun->machine->framesize_locals);
+ fprintf (outfile, "; framesize_outgoing: %d\n",
+ cfun->machine->framesize_outgoing);
fprintf (outfile, "; framesize: %d\n", cfun->machine->framesize);
- fprintf (outfile, "; elim ap -> fp %d\n", msp430_initial_elimination_offset (ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM));
- fprintf (outfile, "; elim fp -> sp %d\n", msp430_initial_elimination_offset (FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM));
+ fprintf (outfile, "; elim ap -> fp %d\n",
+ msp430_initial_elimination_offset (ARG_POINTER_REGNUM,
+ FRAME_POINTER_REGNUM));
+ fprintf (outfile, "; elim fp -> sp %d\n",
+ msp430_initial_elimination_offset (FRAME_POINTER_REGNUM,
+ STACK_POINTER_REGNUM));
n = 0;
fprintf (outfile, "; saved regs:");
for (r = 0; r < ARG_POINTER_REGNUM; r++)
- if (cfun->machine->need_to_save [r])
+ if (cfun->machine->need_to_save[r])
{
- fprintf (outfile, " %s", reg_names [r]);
+ fprintf (outfile, " %s", reg_names[r]);
n = 1;
}
if (n == 0)
@@ -2216,7 +1636,8 @@ msp430_start_function (FILE *file, const char *name, tree decl)
functions implies multiple definitions. */
if (DECL_WEAK (decl))
{
- error ("argument to interrupt attribute is unsupported for weak functions");
+ error ("argument to interrupt attribute is unsupported for weak "
+ "functions");
}
intr_vector = TREE_VALUE (intr_vector);
@@ -2241,7 +1662,7 @@ msp430_start_function (FILE *file, const char *name, tree decl)
}
switch_to_section (function_section (decl));
- ASM_OUTPUT_TYPE_DIRECTIVE(file, name, "function");
+ ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
ASM_OUTPUT_FUNCTION_LABEL (file, name, decl);
}
@@ -2258,7 +1679,8 @@ gen_prefix (tree decl)
if (DECL_ONE_ONLY (decl))
return NULL;
- /* If the user has specified a particular section then do not use any prefix. */
+ /* If the user has specified a particular section then do not use any
+ prefix. */
if (has_attr ("section", decl))
return NULL;
@@ -2272,7 +1694,8 @@ gen_prefix (tree decl)
if (has_attr (ATTR_LOWER, decl))
return lower_prefix;
- /* If we are compiling for the MSP430 then we do not support the upper region. */
+ /* If we are compiling for the MSP430 then we do not support the upper
+ region. */
if (! msp430x)
return NULL;
@@ -2317,8 +1740,10 @@ static section * persist_section;
static void
msp430_init_sections (void)
{
- noinit_section = get_unnamed_section (0, output_section_asm_op, ".section .noinit,\"aw\"");
- persist_section = get_unnamed_section (0, output_section_asm_op, ".section .persistent,\"aw\"");
+ noinit_section = get_unnamed_section (0, output_section_asm_op,
+ ".section .noinit,\"aw\"");
+ persist_section = get_unnamed_section (0, output_section_asm_op,
+ ".section .persistent,\"aw\"");
}
#undef TARGET_ASM_SELECT_SECTION
@@ -2335,10 +1760,11 @@ msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
|| TREE_CODE (decl) == VECTOR_CST
|| TREE_CODE (decl) == COMPLEX_CST)
return default_select_section (decl, reloc, align);
-
+
/* In large mode we must make sure that interrupt handlers are put into
low memory as the vector table only accepts 16-bit addresses. */
- if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL && is_interrupt_func (decl))
+ if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL
+ && is_interrupt_func (decl))
return get_section (".lowtext", SECTION_CODE | SECTION_WRITE , decl);
const char * prefix = gen_prefix (decl);
@@ -2346,6 +1772,8 @@ msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
{
if (TREE_CODE (decl) == FUNCTION_DECL)
return text_section;
+ /* FIXME: ATTR_NOINIT is handled generically in
+ default_elf_select_section. */
else if (has_attr (ATTR_NOINIT, decl))
return noinit_section;
else if (has_attr (ATTR_PERSIST, decl))
@@ -2353,7 +1781,7 @@ msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
else
return default_select_section (decl, reloc, align);
}
-
+
const char * sec;
switch (categorize_decl_for_section (decl, reloc))
{
@@ -2379,7 +1807,7 @@ msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
default:
gcc_unreachable ();
}
-
+
const char * dec_name = DECL_SECTION_NAME (decl);
char * name = ACONCAT ((prefix, sec, dec_name, NULL));
@@ -2390,7 +1818,8 @@ msp430_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
#define TARGET_ASM_FUNCTION_SECTION msp430_function_section
static section *
-msp430_function_section (tree decl, enum node_frequency freq, bool startup, bool exit)
+msp430_function_section (tree decl, enum node_frequency freq, bool startup,
+ bool exit)
{
const char * name;
@@ -2422,7 +1851,7 @@ msp430_section_type_flags (tree decl, const char * name, int reloc)
return SECTION_WRITE | SECTION_BSS | SECTION_NOTYPE;
else if (strcmp (name, ".persistent") == 0)
return SECTION_WRITE | SECTION_NOTYPE;
-
+
return default_section_type_flags (decl, name, reloc);
}
@@ -2436,7 +1865,8 @@ msp430_unique_section (tree decl, int reloc)
/* In large mode we must make sure that interrupt handlers are put into
low memory as the vector table only accepts 16-bit addresses. */
- if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL && is_interrupt_func (decl))
+ if (TARGET_LARGE && TREE_CODE (decl) == FUNCTION_DECL
+ && is_interrupt_func (decl))
{
set_decl_section_name (decl, ".lowtext");
return;
@@ -2451,8 +1881,7 @@ msp430_unique_section (tree decl, int reloc)
|| TREE_CODE (decl) == INTEGER_CST
|| TREE_CODE (decl) == VECTOR_CST
|| TREE_CODE (decl) == COMPLEX_CST
- || (prefix = gen_prefix (decl)) == NULL
- )
+ || (prefix = gen_prefix (decl)) == NULL)
return;
const char * dec_name = DECL_SECTION_NAME (decl);
@@ -2466,11 +1895,11 @@ msp430_unique_section (tree decl, int reloc)
equivalent .bss section instead. */
void
-msp430_output_aligned_decl_common (FILE * stream,
- const tree decl,
- const char * name,
+msp430_output_aligned_decl_common (FILE * stream,
+ const tree decl,
+ const char * name,
unsigned HOST_WIDE_INT size,
- unsigned int align)
+ unsigned int align)
{
if (msp430_data_region == MSP430_REGION_ANY)
{
@@ -2488,9 +1917,15 @@ msp430_output_aligned_decl_common (FILE * stream,
else
switch (msp430_data_region)
{
- case MSP430_REGION_UPPER: sec = get_named_section (NULL, ".upper.bss", 0); break;
- case MSP430_REGION_LOWER: sec = get_named_section (NULL, ".lower.bss", 0); break;
- case MSP430_REGION_EITHER: sec = get_named_section (NULL, ".either.bss", 0); break;
+ case MSP430_REGION_UPPER:
+ sec = get_named_section (NULL, ".upper.bss", 0);
+ break;
+ case MSP430_REGION_LOWER:
+ sec = get_named_section (NULL, ".lower.bss", 0);
+ break;
+ case MSP430_REGION_EITHER:
+ sec = get_named_section (NULL, ".either.bss", 0);
+ break;
default:
gcc_unreachable ();
}
@@ -2508,11 +1943,11 @@ msp430_output_aligned_decl_common (FILE * stream,
bool
msp430_do_not_relax_short_jumps (void)
{
- /* When placing code into "either" low or high memory we do not want the linker
- to grow the size of sections, which it can do if it is encounters a branch to
- a label that is too far away. So we tell the cbranch patterns to avoid using
- short jumps when there is a chance that the instructions will end up in a low
- section. */
+ /* When placing code into "either" low or high memory we do not want the
+ linker to grow the size of sections, which it can do if it is encounters a
+ branch to a label that is too far away. So we tell the cbranch patterns to
+ avoid using short jumps when there is a chance that the instructions will
+ end up in a low section. */
return
msp430_code_region == MSP430_REGION_EITHER
|| msp430_code_region == MSP430_REGION_LOWER
@@ -2528,25 +1963,29 @@ enum msp430_builtin
MSP430_BUILTIN_max
};
-static GTY(()) tree msp430_builtins [(int) MSP430_BUILTIN_max];
+static GTY(()) tree msp430_builtins[(int) MSP430_BUILTIN_max];
static void
msp430_init_builtins (void)
{
- tree void_ftype_int = build_function_type_list (void_type_node, integer_type_node, NULL);
- tree void_ftype_longlong = build_function_type_list (void_type_node, long_long_integer_type_node, NULL);
+ tree void_ftype_int = build_function_type_list (void_type_node,
+ integer_type_node, NULL);
+ tree void_ftype_longlong
+ = build_function_type_list (void_type_node, long_long_integer_type_node,
+ NULL);
msp430_builtins[MSP430_BUILTIN_BIC_SR] =
add_builtin_function ( "__bic_SR_register_on_exit", void_ftype_int,
- MSP430_BUILTIN_BIC_SR, BUILT_IN_MD, NULL, NULL_TREE);
+ MSP430_BUILTIN_BIC_SR, BUILT_IN_MD, NULL, NULL_TREE);
msp430_builtins[MSP430_BUILTIN_BIS_SR] =
add_builtin_function ( "__bis_SR_register_on_exit", void_ftype_int,
- MSP430_BUILTIN_BIS_SR, BUILT_IN_MD, NULL, NULL_TREE);
+ MSP430_BUILTIN_BIS_SR, BUILT_IN_MD, NULL, NULL_TREE);
msp430_builtins[MSP430_BUILTIN_DELAY_CYCLES] =
add_builtin_function ( "__delay_cycles", void_ftype_longlong,
- MSP430_BUILTIN_DELAY_CYCLES, BUILT_IN_MD, NULL, NULL_TREE);
+ MSP430_BUILTIN_DELAY_CYCLES, BUILT_IN_MD, NULL,
+ NULL_TREE);
}
static tree
@@ -2613,7 +2052,8 @@ msp430_expand_delay_cycles (rtx arg)
if (c > 3 * 0xffff + CYCX (7, 10))
{
n = c;
- /* There's 4 cycles in the short (i>0xffff) loop and 7 in the long (x<=0xffff) loop */
+ /* There's 4 cycles in the short (i>0xffff) loop and 7 in the long
+ (x<=0xffff) loop. */
if (c >= 0x10000 * 7 + CYCX (14, 16))
{
i = 0x10000;
@@ -2643,7 +2083,8 @@ msp430_expand_delay_cycles (rtx arg)
emit_insn (gen_delay_cycles_32 (GEN_INT (i), GEN_INT (n - c)));
}
- /* For 16-bit loops, there's 7(10) + 3x cycles - so the max cycles is 0x30004(7). */
+ /* For 16-bit loops, there's 7(10) + 3x cycles - so the max cycles is
+ 0x30004(7). */
if (c > 12)
{
n = c;
@@ -2684,7 +2125,7 @@ msp430_expand_builtin (tree exp,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
if (fcode == MSP430_BUILTIN_DELAY_CYCLES)
@@ -2765,7 +2206,8 @@ msp430_expand_prologue (void)
/* Document the stack decrement... */
note = F (gen_rtx_SET (stack_pointer_rtx,
- gen_rtx_MINUS (Pmode, stack_pointer_rtx, GEN_INT (2))));
+ gen_rtx_MINUS (Pmode,
+ stack_pointer_rtx, GEN_INT (2))));
add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
/* ...and the establishment of a new location for the return address. */
@@ -2779,7 +2221,7 @@ msp430_expand_prologue (void)
}
for (i = 15; i >= 4; i--)
- if (cfun->machine->need_to_save [i])
+ if (cfun->machine->need_to_save[i])
{
int seq, count;
rtx note;
@@ -2790,7 +2232,8 @@ msp430_expand_prologue (void)
if (msp430x)
{
- /* Note: with TARGET_LARGE we still use PUSHM as PUSHX.A is two bytes bigger. */
+ /* Note: with TARGET_LARGE we still use PUSHM as PUSHX.A is two
+ bytes bigger. */
p = F (emit_insn (gen_pushm (gen_rtx_REG (Pmode, i),
GEN_INT (count))));
@@ -2800,7 +2243,8 @@ msp430_expand_prologue (void)
= F (gen_rtx_SET (stack_pointer_rtx,
gen_rtx_PLUS (Pmode,
stack_pointer_rtx,
- GEN_INT (count * (TARGET_LARGE ? -4 : -2)))));
+ GEN_INT (count * (TARGET_LARGE
+ ? -4 : -2)))));
/* *sp-- = R[i-j] */
/* sp+N R10
@@ -2818,7 +2262,7 @@ msp430_expand_prologue (void)
XVECEXP (note, 0, j + 1) =
F (gen_rtx_SET (gen_rtx_MEM (Pmode, addr),
- gen_rtx_REG (Pmode, i - j)) );
+ gen_rtx_REG (Pmode, i - j)));
}
add_reg_note (p, REG_FRAME_RELATED_EXPR, note);
@@ -2853,16 +2297,16 @@ msp430_expand_epilogue (int is_eh)
return;
}
- if (cfun->machine->need_to_save [10])
+ if (cfun->machine->need_to_save[10])
{
/* Check for a helper function. */
helper_n = 7; /* For when the loop below never sees a match. */
for (i = 9; i >= 4; i--)
- if (!cfun->machine->need_to_save [i])
+ if (!cfun->machine->need_to_save[i])
{
helper_n = 10 - i;
for (; i >= 4; i--)
- if (cfun->machine->need_to_save [i])
+ if (cfun->machine->need_to_save[i])
{
helper_n = 0;
break;
@@ -2873,7 +2317,8 @@ msp430_expand_epilogue (int is_eh)
emit_insn (gen_epilogue_start_marker ());
- if (cfun->decl && strcmp (IDENTIFIER_POINTER (DECL_NAME (cfun->decl)), "main") == 0)
+ if (cfun->decl && strcmp (IDENTIFIER_POINTER (DECL_NAME (cfun->decl)),
+ "main") == 0)
emit_insn (gen_msp430_refsym_need_exit ());
if (is_wakeup_func ())
@@ -2902,11 +2347,13 @@ msp430_expand_epilogue (int is_eh)
emit_move_insn (r12, stack_pointer_rtx);
emit_insn (addPmode (r12, r12, EH_RETURN_STACKADJ_RTX));
emit_insn (addPmode (r12, r12, GEN_INT (i)));
- emit_move_insn (gen_rtx_MEM (Pmode, plus_constant (Pmode, stack_pointer_rtx, i)), r12);
+ emit_move_insn (gen_rtx_MEM (Pmode, plus_constant (Pmode,
+ stack_pointer_rtx,
+ i)), r12);
}
for (i = 4; i <= 15; i++)
- if (cfun->machine->need_to_save [i])
+ if (cfun->machine->need_to_save[i])
{
int seq, count;
@@ -2927,7 +2374,8 @@ msp430_expand_epilogue (int is_eh)
&& ! is_reentrant_func ()
&& ! is_critical_func ()
&& crtl->args.pretend_args_size == 0
- /* Calling the helper takes as many bytes as the POP;RET sequence. */
+ /* Calling the helper takes as many bytes as the POP;RET
+ sequence. */
&& helper_n > 1
&& !is_eh)
{
@@ -2943,7 +2391,8 @@ msp430_expand_epilogue (int is_eh)
/* Also pop SP, which puts us into the EH return frame. Except
that you can't "pop" sp, you have to just load it off the
stack. */
- emit_move_insn (stack_pointer_rtx, gen_rtx_MEM (Pmode, stack_pointer_rtx));
+ emit_move_insn (stack_pointer_rtx, gen_rtx_MEM (Pmode,
+ stack_pointer_rtx));
}
if (crtl->args.pretend_args_size)
@@ -3027,7 +2476,7 @@ static struct
int need_430x;
rtx (*genfunc)(rtx,rtx);
}
- const_shift_helpers[] =
+const_shift_helpers[] =
{
#define CSH(N,C,X,G) { "__mspabi_" N, C, X, gen_##G }
@@ -3050,7 +2499,8 @@ static struct
emit such a function, using the table above to optimize some
cases. */
void
-msp430_expand_helper (rtx *operands, const char *helper_name, bool const_variants)
+msp430_expand_helper (rtx *operands, const char *helper_name,
+ bool const_variants)
{
rtx c, f;
char *helper_const = NULL;
@@ -3072,7 +2522,8 @@ msp430_expand_helper (rtx *operands, const char *helper_name, bool const_variant
&& strcmp (helper_name, const_shift_helpers[i].name) == 0
&& INTVAL (operands[2]) == const_shift_helpers[i].count)
{
- emit_insn (const_shift_helpers[i].genfunc (operands[0], operands[1]));
+ emit_insn (const_shift_helpers[i].genfunc (operands[0],
+ operands[1]));
return;
}
}
@@ -3101,10 +2552,12 @@ msp430_expand_helper (rtx *operands, const char *helper_name, bool const_variant
&& INTVAL (operands[2]) >= 1
&& INTVAL (operands[2]) <= 15)
{
- /* Note that the INTVAL is limited in value and length by the conditional above. */
+ /* Note that the INTVAL is limited in value and length by the conditional
+ above. */
int len = strlen (helper_name) + 4;
helper_const = (char *) xmalloc (len);
- snprintf (helper_const, len, "%s_%d", helper_name, (int) INTVAL (operands[2]));
+ snprintf (helper_const, len, "%s_%d", helper_name,
+ (int) INTVAL (operands[2]));
}
emit_move_insn (gen_rtx_REG (arg1mode, arg1),
@@ -3114,7 +2567,9 @@ msp430_expand_helper (rtx *operands, const char *helper_name, bool const_variant
operands[2]);
c = gen_call_value_internal (gen_rtx_REG (arg0mode, 12),
- gen_rtx_SYMBOL_REF (VOIDmode, helper_const ? helper_const : helper_name),
+ gen_rtx_SYMBOL_REF (VOIDmode, helper_const
+ ? helper_const
+ : helper_name),
GEN_INT (0));
c = emit_call_insn (c);
RTL_CONST_CALL_P (c) = 1;
@@ -3197,9 +2652,11 @@ msp430_split_movsi (rtx *operands)
if (GET_CODE (operands[1]) == CONST
|| GET_CODE (operands[1]) == SYMBOL_REF)
{
- op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (0));
+ op10 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16),
+ GEN_INT (0));
op10 = gen_rtx_CONST (HImode, op10);
- op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16), GEN_INT (16));
+ op12 = gen_rtx_ZERO_EXTRACT (HImode, operands[1], GEN_INT (16),
+ GEN_INT (16));
op12 = gen_rtx_CONST (HImode, op12);
}
else
@@ -3219,8 +2676,7 @@ msp430_split_movsi (rtx *operands)
/* Catch the case where we are loading (rN, rN+1) from mem (rN). */
|| (REG_P (op00) && reg_mentioned_p (op00, op10))
/* Or storing (rN) into mem (rN). */
- || (REG_P (op10) && reg_mentioned_p (op10, op00))
- )
+ || (REG_P (op10) && reg_mentioned_p (op10, op00)))
{
operands[2] = op02;
operands[4] = op12;
@@ -3245,82 +2701,84 @@ static const struct
char const * const gcc_name;
char const * const ti_name;
}
- helper_function_name_mappings [] =
-{
- /* Floating point to/from integer conversions. */
- { "__truncdfsf2", "__mspabi_cvtdf" },
- { "__extendsfdf2", "__mspabi_cvtfd" },
- { "__fixdfhi", "__mspabi_fixdi" },
- { "__fixdfsi", "__mspabi_fixdli" },
- { "__fixdfdi", "__mspabi_fixdlli" },
- { "__fixunsdfhi", "__mspabi_fixdu" },
- { "__fixunsdfsi", "__mspabi_fixdul" },
- { "__fixunsdfdi", "__mspabi_fixdull" },
- { "__fixsfhi", "__mspabi_fixfi" },
- { "__fixsfsi", "__mspabi_fixfli" },
- { "__fixsfdi", "__mspabi_fixflli" },
- { "__fixunsfhi", "__mspabi_fixfu" },
- { "__fixunsfsi", "__mspabi_fixful" },
- { "__fixunsfdi", "__mspabi_fixfull" },
- { "__floathisf", "__mspabi_fltif" },
- { "__floatsisf", "__mspabi_fltlif" },
- { "__floatdisf", "__mspabi_fltllif" },
- { "__floathidf", "__mspabi_fltid" },
- { "__floatsidf", "__mspabi_fltlid" },
- { "__floatdidf", "__mspabi_fltllid" },
- { "__floatunhisf", "__mspabi_fltuf" },
- { "__floatunsisf", "__mspabi_fltulf" },
- { "__floatundisf", "__mspabi_fltullf" },
- { "__floatunhidf", "__mspabi_fltud" },
- { "__floatunsidf", "__mspabi_fltuld" },
- { "__floatundidf", "__mspabi_fltulld" },
-
- /* Floating point comparisons. */
- /* GCC uses individual functions for each comparison, TI uses one
- compare <=> function. */
-
- /* Floating point arithmatic */
- { "__adddf3", "__mspabi_addd" },
- { "__addsf3", "__mspabi_addf" },
- { "__divdf3", "__mspabi_divd" },
- { "__divsf3", "__mspabi_divf" },
- { "__muldf3", "__mspabi_mpyd" },
- { "__mulsf3", "__mspabi_mpyf" },
- { "__subdf3", "__mspabi_subd" },
- { "__subsf3", "__mspabi_subf" },
- /* GCC does not use helper functions for negation */
-
- /* Integer multiply, divide, remainder. */
- { "__mulhi3", "__mspabi_mpyi" },
- { "__mulsi3", "__mspabi_mpyl" },
- { "__muldi3", "__mspabi_mpyll" },
+helper_function_name_mappings[] =
+ {
+ /* Floating point to/from integer conversions. */
+ { "__truncdfsf2", "__mspabi_cvtdf" },
+ { "__extendsfdf2", "__mspabi_cvtfd" },
+ { "__fixdfhi", "__mspabi_fixdi" },
+ { "__fixdfsi", "__mspabi_fixdli" },
+ { "__fixdfdi", "__mspabi_fixdlli" },
+ { "__fixunsdfhi", "__mspabi_fixdu" },
+ { "__fixunsdfsi", "__mspabi_fixdul" },
+ { "__fixunsdfdi", "__mspabi_fixdull" },
+ { "__fixsfhi", "__mspabi_fixfi" },
+ { "__fixsfsi", "__mspabi_fixfli" },
+ { "__fixsfdi", "__mspabi_fixflli" },
+ { "__fixunsfhi", "__mspabi_fixfu" },
+ { "__fixunsfsi", "__mspabi_fixful" },
+ { "__fixunsfdi", "__mspabi_fixfull" },
+ { "__floathisf", "__mspabi_fltif" },
+ { "__floatsisf", "__mspabi_fltlif" },
+ { "__floatdisf", "__mspabi_fltllif" },
+ { "__floathidf", "__mspabi_fltid" },
+ { "__floatsidf", "__mspabi_fltlid" },
+ { "__floatdidf", "__mspabi_fltllid" },
+ { "__floatunhisf", "__mspabi_fltuf" },
+ { "__floatunsisf", "__mspabi_fltulf" },
+ { "__floatundisf", "__mspabi_fltullf" },
+ { "__floatunhidf", "__mspabi_fltud" },
+ { "__floatunsidf", "__mspabi_fltuld" },
+ { "__floatundidf", "__mspabi_fltulld" },
+
+ /* Floating point comparisons. */
+ /* GCC uses individual functions for each comparison, TI uses one
+ compare <=> function. */
+
+ /* Floating point arithmetic. */
+ { "__adddf3", "__mspabi_addd" },
+ { "__addsf3", "__mspabi_addf" },
+ { "__divdf3", "__mspabi_divd" },
+ { "__divsf3", "__mspabi_divf" },
+ { "__muldf3", "__mspabi_mpyd" },
+ { "__mulsf3", "__mspabi_mpyf" },
+ { "__subdf3", "__mspabi_subd" },
+ { "__subsf3", "__mspabi_subf" },
+ /* GCC does not use helper functions for negation. */
+
+ /* Integer multiply, divide, remainder. */
+ { "__mulhi3", "__mspabi_mpyi" },
+ { "__mulsi3", "__mspabi_mpyl" },
+ { "__muldi3", "__mspabi_mpyll" },
#if 0
- /* Clarify signed vs unsigned first. */
- { "__mulhisi3", "__mspabi_mpysl" }, /* gcc doesn't use widening multiply (yet?) */
- { "__mulsidi3", "__mspabi_mpysll" }, /* gcc doesn't use widening multiply (yet?) */
+ /* Clarify signed vs unsigned first. */
+ { "__mulhisi3", "__mspabi_mpysl" }, /* gcc doesn't use widening multiply
+ (yet?) */
+ { "__mulsidi3", "__mspabi_mpysll" }, /* gcc doesn't use widening multiply
+ (yet?) */
#endif
- { "__divhi3", "__mspabi_divi" },
- { "__divsi3", "__mspabi_divli" },
- { "__divdi3", "__mspabi_divlli" },
- { "__udivhi3", "__mspabi_divu" },
- { "__udivsi3", "__mspabi_divul" },
- { "__udivdi3", "__mspabi_divull" },
- { "__modhi3", "__mspabi_remi" },
- { "__modsi3", "__mspabi_remli" },
- { "__moddi3", "__mspabi_remlli" },
- { "__umodhi3", "__mspabi_remu" },
- { "__umodsi3", "__mspabi_remul" },
- { "__umoddi3", "__mspabi_remull" },
-
- /* Bitwise operations. */
- /* Rotation - no rotation support yet. */
- /* Logical left shift - gcc already does these itself. */
- /* Arithmetic left shift - gcc already does these itself. */
- /* Arithmetic right shift - gcc already does these itself. */
-
- { NULL, NULL }
-};
+ { "__divhi3", "__mspabi_divi" },
+ { "__divsi3", "__mspabi_divli" },
+ { "__divdi3", "__mspabi_divlli" },
+ { "__udivhi3", "__mspabi_divu" },
+ { "__udivsi3", "__mspabi_divul" },
+ { "__udivdi3", "__mspabi_divull" },
+ { "__modhi3", "__mspabi_remi" },
+ { "__modsi3", "__mspabi_remli" },
+ { "__moddi3", "__mspabi_remlli" },
+ { "__umodhi3", "__mspabi_remu" },
+ { "__umodsi3", "__mspabi_remul" },
+ { "__umoddi3", "__mspabi_remull" },
+
+ /* Bitwise operations. */
+ /* Rotation - no rotation support yet. */
+ /* Logical left shift - gcc already does these itself. */
+ /* Arithmetic left shift - gcc already does these itself. */
+ /* Arithmetic right shift - gcc already does these itself. */
+
+ { NULL, NULL }
+ };
/* Returns true if the current MCU supports an F5xxx series
hardware multiper. */
@@ -3329,7 +2787,7 @@ bool
msp430_use_f5_series_hwmult (void)
{
static const char * cached_match = NULL;
- static bool cached_result;
+ static bool cached_result;
if (msp430_hwmult_type == MSP430_HWMULT_F5SERIES)
return true;
@@ -3349,12 +2807,10 @@ msp430_use_f5_series_hwmult (void)
if (strncasecmp (target_mcu, "msp430f6", 8) == 0)
return cached_result = true;
- int i;
+ msp430_extract_mcu_data (target_mcu);
- /* FIXME: This array is alpha sorted - we could use a binary search. */
- for (i = ARRAY_SIZE (msp430_mcu_data); i--;)
- if (strcasecmp (target_mcu, msp430_mcu_data[i].name) == 0)
- return cached_result = msp430_mcu_data[i].hwmpy == 8;
+ if (extracted_mcu_data.name != NULL)
+ return cached_result = extracted_mcu_data.hwmpy == 8;
return cached_result = false;
}
@@ -3366,8 +2822,7 @@ static bool
use_32bit_hwmult (void)
{
static const char * cached_match = NULL;
- static bool cached_result;
- int i;
+ static bool cached_result;
if (msp430_hwmult_type == MSP430_HWMULT_LARGE)
return true;
@@ -3380,10 +2835,9 @@ use_32bit_hwmult (void)
cached_match = target_mcu;
- /* FIXME: This array is alpha sorted - we could use a binary search. */
- for (i = ARRAY_SIZE (msp430_mcu_data); i--;)
- if (strcasecmp (target_mcu, msp430_mcu_data[i].name) == 0)
- return cached_result = msp430_mcu_data[i].hwmpy == 4;
+ msp430_extract_mcu_data (target_mcu);
+ if (extracted_mcu_data.name != NULL)
+ return cached_result = extracted_mcu_data.hwmpy == 4;
return cached_result = false;
}
@@ -3395,8 +2849,7 @@ static bool
msp430_no_hwmult (void)
{
static const char * cached_match = NULL;
- static bool cached_result;
- int i;
+ static bool cached_result;
if (msp430_hwmult_type == MSP430_HWMULT_NONE)
return true;
@@ -3412,10 +2865,9 @@ msp430_no_hwmult (void)
cached_match = target_mcu;
- /* FIXME: This array is alpha sorted - we could use a binary search. */
- for (i = ARRAY_SIZE (msp430_mcu_data); i--;)
- if (strcasecmp (target_mcu, msp430_mcu_data[i].name) == 0)
- return cached_result = msp430_mcu_data[i].hwmpy == 0;
+ msp430_extract_mcu_data (target_mcu);
+ if (extracted_mcu_data.name != NULL)
+ return cached_result = extracted_mcu_data.hwmpy == 0;
/* If we do not recognise the MCU name, we assume that it does not support
any kind of hardware multiply - this is the safest assumption to make. */
@@ -3430,10 +2882,10 @@ msp430_output_labelref (FILE *file, const char *name)
{
int i;
- for (i = 0; helper_function_name_mappings [i].gcc_name; i++)
- if (strcmp (helper_function_name_mappings [i].gcc_name, name) == 0)
+ for (i = 0; helper_function_name_mappings[i].gcc_name; i++)
+ if (strcmp (helper_function_name_mappings[i].gcc_name, name) == 0)
{
- name = helper_function_name_mappings [i].ti_name;
+ name = helper_function_name_mappings[i].ti_name;
break;
}
@@ -3475,7 +2927,7 @@ msp430_print_operand_raw (FILE * file, rtx op)
switch (GET_CODE (op))
{
case REG:
- fprintf (file, "%s", reg_names [REGNO (op)]);
+ fprintf (file, "%s", reg_names[REGNO (op)]);
break;
case CONST_INT:
@@ -3520,7 +2972,7 @@ msp430_print_operand_addr (FILE * file, machine_mode /*mode*/, rtx addr)
case PLUS:
msp430_print_operand_raw (file, XEXP (addr, 1));
gcc_assert (REG_P (XEXP (addr, 0)));
- fprintf (file, "(%s)", reg_names [REGNO (XEXP (addr, 0))]);
+ fprintf (file, "(%s)", reg_names[REGNO (XEXP (addr, 0))]);
return;
case REG:
@@ -3622,7 +3074,7 @@ msp430_print_operand (FILE * file, rtx op, int letter)
break;
}
return;
- case 'p': /* Bit position. 0 == 0x01, 3 = 0x08 etc. */
+ case 'p': /* Bit position. 0 == 0x01, 3 = 0x08 etc. */
gcc_assert (CONST_INT_P (op));
fprintf (file, "#%d", 1 << INTVAL (op));
return;
@@ -3734,9 +3186,11 @@ msp430_print_operand (FILE * file, rtx op, int letter)
case 'O':
/* Computes the offset to the top of the stack for the current frame.
This has to be done here rather than in, say, msp430_expand_builtin()
- because builtins are expanded before the frame layout is determined. */
+ because builtins are expanded before the frame layout is
+ determined. */
fprintf (file, "%d",
- msp430_initial_elimination_offset (ARG_POINTER_REGNUM, STACK_POINTER_REGNUM)
+ msp430_initial_elimination_offset (ARG_POINTER_REGNUM,
+ STACK_POINTER_REGNUM)
- (TARGET_LARGE ? 4 : 2));
return;
@@ -3771,7 +3225,7 @@ msp430_print_operand (FILE * file, rtx op, int letter)
msp430_print_operand_raw (file, XEXP (op, 0));
fprintf (file, ")");
break;
-
+
case 16:
fprintf (file, "#hi (");
msp430_print_operand_raw (file, XEXP (op, 0));
@@ -3820,7 +3274,8 @@ msp430_return_addr_rtx (int count)
if (crtl->args.pretend_args_size)
ra_size += 2;
- return gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, arg_pointer_rtx, GEN_INT (- ra_size)));
+ return gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, arg_pointer_rtx,
+ GEN_INT (- ra_size)));
}
rtx
@@ -3839,28 +3294,29 @@ const char *
msp430x_extendhisi (rtx * operands)
{
if (REGNO (operands[0]) == REGNO (operands[1]))
- /* Low word of dest == source word. */
- return "BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0"; /* 8-bytes. */
+ /* Low word of dest == source word. 8-byte sequence. */
+ return "BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0";
if (! msp430x)
/* Note: This sequence is approximately the same length as invoking a helper
function to perform the sign-extension, as in:
- MOV.W %1, %L0
- MOV.W %1, r12
- CALL __mspabi_srai_15
- MOV.W r12, %H0
+ MOV.W %1, %L0
+ MOV.W %1, r12
+ CALL __mspabi_srai_15
+ MOV.W r12, %H0
but this version does not involve any function calls or using argument
- registers, so it reduces register pressure. */
- return "MOV.W\t%1, %L0 { BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 { INV.W\t%H0, %H0"; /* 10-bytes. */
+ registers, so it reduces register pressure. 10-byte sequence. */
+ return "MOV.W\t%1, %L0 { BIT.W\t#0x8000, %L0 { SUBC.W\t%H0, %H0 "
+ "{ INV.W\t%H0, %H0";
if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
- /* High word of dest == source word. */
- return "MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0"; /* 6-bytes. */
+ /* High word of dest == source word. 6-byte sequence. */
+ return "MOV.W\t%1, %L0 { RPT\t#15 { RRAX.W\t%H0";
- /* No overlap between dest and source. */
- return "MOV.W\t%1, %L0 { MOV.W\t%1, %H0 { RPT\t#15 { RRAX.W\t%H0"; /* 8-bytes. */
+ /* No overlap between dest and source. 8-byte sequence. */
+ return "MOV.W\t%1, %L0 { MOV.W\t%1, %H0 { RPT\t#15 { RRAX.W\t%H0";
}
/* Likewise for logical right shifts. */
diff --git a/gcc/config/msp430/msp430.h b/gcc/config/msp430/msp430.h
index 1288b1a..36b715d 100644
--- a/gcc/config/msp430/msp430.h
+++ b/gcc/config/msp430/msp430.h
@@ -26,10 +26,10 @@
extern bool msp430x;
#endif
-#define TARGET_CPU_CPP_BUILTINS() \
- do \
- { \
- builtin_define ("NO_TRAMPOLINES"); \
+#define TARGET_CPU_CPP_BUILTINS() \
+ do \
+ { \
+ builtin_define ("NO_TRAMPOLINES"); \
builtin_define ("__MSP430__"); \
builtin_define (msp430_mcu_name ()); \
if (msp430x) \
@@ -41,35 +41,61 @@ extern bool msp430x;
} \
else \
builtin_assert ("cpu=MSP430"); \
- } \
+ } \
while (0)
#undef STARTFILE_SPEC
-#define STARTFILE_SPEC "%{pg:gcrt0.o%s}%{!pg:%{minrt:crt0-minrt.o%s}%{!minrt:crt0.o%s}} %{!minrt:crtbegin.o%s}"
+#define STARTFILE_SPEC "%{pg:gcrt0.o%s}" \
+ "%{!pg:%{minrt:crt0-minrt.o%s}%{!minrt:crt0.o%s}} %{!minrt:crtbegin.o%s}"
/* -lgcc is included because crtend.o needs __mspabi_func_epilog_1. */
#undef ENDFILE_SPEC
-#define ENDFILE_SPEC "%{!minrt:crtend.o%s} %{minrt:crtn-minrt.o%s}%{!minrt:crtn.o%s} -lgcc"
+#define ENDFILE_SPEC "%{!minrt:crtend.o%s} " \
+ "%{minrt:%:if-exists(crtn-minrt.o%s)}%{!minrt:%:if-exists(crtn.o%s)} -lgcc"
#define ASM_SPEC "-mP " /* Enable polymorphic instructions. */ \
- "%{mcpu=*:-mcpu=%*}%{!mcpu=*:%{mmcu=*:-mmcu=%*}} " /* Pass the CPU type on to the assembler. */ \
+ "%{mcpu=*:-mcpu=%*} " /* Pass the CPU type on to the assembler. */ \
"%{mrelax=-mQ} " /* Pass the relax option on to the assembler. */ \
- "%{mlarge:-ml} " /* Tell the assembler if we are building for the LARGE pointer model. */ \
- "%{!msim:-md} %{msim:%{mlarge:-md}} " /* Copy data from ROM to RAM if necessary. */ \
- "%{msilicon-errata=*:-msilicon-errata=%*} " /* Pass on -msilicon-errata. */ \
- "%{msilicon-errata-warn=*:-msilicon-errata-warn=%*} " /* Pass on -msilicon-errata-warn. */ \
- "%{ffunction-sections:-gdwarf-sections} " /* If function sections are being created then create DWARF line number sections as well. */ \
- "%{mdata-region=*:-mdata-region=%*} " /* Pass on -mdata-region. */
+ /* Tell the assembler if we are building for the LARGE pointer model. */ \
+ "%{mlarge:-ml} " \
+ /* Copy data from ROM to RAM if necessary. */ \
+ "%{!msim:-md} %{msim:%{mlarge:-md}} " \
+ "%{msilicon-errata=*:-msilicon-errata=%*} " \
+ "%{msilicon-errata-warn=*:-msilicon-errata-warn=%*} " \
+ /* Create DWARF line number sections for -ffunction-sections. */ \
+ "%{ffunction-sections:-gdwarf-sections} " \
+ "%{mdata-region=*:-mdata-region=%*} "
/* Enable linker section garbage collection by default, unless we
are creating a relocatable binary (gc does not work) or debugging
- is enabled (the GDB testsuite relies upon unused entities not being deleted). */
+ is enabled (the GDB testsuite relies upon unused entities not being
+ deleted). */
#define LINK_SPEC "%{mrelax:--relax} %{mlarge:%{!r:%{!g:--gc-sections}}} " \
"%{mcode-region=*:--code-region=%*} %{mdata-region=*:--data-region=%*}"
+#define DRIVER_SELF_SPECS \
+ " %{!mlarge:%{mcode-region=*:%{mdata-region=*:%e-mcode-region and " \
+ "-mdata-region require the large memory model (-mlarge)}}}" \
+ " %{!mlarge:%{mcode-region=*:" \
+ "%e-mcode-region requires the large memory model (-mlarge)}}" \
+ " %{!mlarge:%{mdata-region=*:" \
+ "%e-mdata-region requires the large memory model (-mlarge)}}" \
+ " %{mno-warn-devices-csv:%:msp430_set_driver_var(msp430_warn_devices_csv 0)}"\
+ " %{mdevices-csv-loc=*:%:msp430_set_driver_var(msp430_devices_csv_loc %*)}"\
+ " %{I*:%:msp430_check_path_for_devices(%{I*:%*})}" \
+ " %{L*:%:msp430_check_path_for_devices(%{L*:%*})}" \
+ " %{!mcpu=*:%{mmcu=*:%:msp430_select_cpu(%{mmcu=*:%*})}}"
+
extern const char * msp430_select_hwmult_lib (int, const char **);
+extern const char * msp430_select_cpu (int, const char **);
+extern const char * msp430_set_driver_var (int, const char **);
+extern const char * msp430_check_path_for_devices (int, const char **);
+
# define EXTRA_SPEC_FUNCTIONS \
- { "msp430_hwmult_lib", msp430_select_hwmult_lib },
+ { "msp430_hwmult_lib", msp430_select_hwmult_lib }, \
+ { "msp430_select_cpu", msp430_select_cpu }, \
+ { "msp430_set_driver_var", msp430_set_driver_var }, \
+ { "msp430_check_path_for_devices", msp430_check_path_for_devices },
/* Specify the libraries to include on the linker command line.
@@ -89,7 +115,8 @@ extern const char * msp430_select_hwmult_lib (int, const char **);
#undef LIB_SPEC
#define LIB_SPEC " \
--start-group \
-%{mhwmult=auto:%{mmcu=*:%:msp430_hwmult_lib(mcu %{mmcu=*:%*});:%:msp430_hwmult_lib(default)}; \
+%{mhwmult=auto:%{mmcu=*:%:msp430_hwmult_lib(mcu %{mmcu=*:%*});\
+ :%:msp430_hwmult_lib(default)}; \
mhwmult=*:%:msp430_hwmult_lib(hwmult %{mhwmult=*:%*}); \
mmcu=*:%:msp430_hwmult_lib(mcu %{mmcu=*:%*}); \
:%:msp430_hwmult_lib(default)} \
@@ -224,6 +251,28 @@ extern const char * msp430_select_hwmult_lib (int, const char **);
"argptr" \
}
+/* Allow lowercase "r" to be used in register names instead of upper
+ case "R". */
+#define ADDITIONAL_REGISTER_NAMES \
+{ \
+ { "r0", 0 }, \
+ { "r1", 1 }, \
+ { "r2", 2 }, \
+ { "r3", 3 }, \
+ { "r4", 4 }, \
+ { "r5", 5 }, \
+ { "r6", 6 }, \
+ { "r7", 7 }, \
+ { "r8", 8 }, \
+ { "r9", 9 }, \
+ { "r10", 10 }, \
+ { "r11", 11 }, \
+ { "r12", 12 }, \
+ { "r13", 13 }, \
+ { "r14", 14 }, \
+ { "r15", 15 } \
+}
+
enum reg_class
{
NO_REGS,
@@ -262,9 +311,9 @@ enum reg_class
#define INDEX_REG_CLASS GEN_REGS
#define N_REG_CLASSES (int) LIM_REG_CLASSES
-#define PC_REGNUM 0
-#define STACK_POINTER_REGNUM 1
-#define CC_REGNUM 2
+#define PC_REGNUM 0
+#define STACK_POINTER_REGNUM 1
+#define CC_REGNUM 2
#define FRAME_POINTER_REGNUM 4 /* not usually used, call preserved */
#define ARG_POINTER_REGNUM 16
#define STATIC_CHAIN_REGNUM 5 /* FIXME */
@@ -352,7 +401,8 @@ typedef struct
(((N) < 3) ? ((N) + 12) : INVALID_REGNUM)
#define EH_RETURN_HANDLER_RTX \
- gen_rtx_MEM(Pmode, gen_rtx_PLUS (Pmode, gen_rtx_REG(Pmode, SP_REGNO), gen_rtx_REG (Pmode, 15)))
+ gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, SP_REGNO), \
+ gen_rtx_REG (Pmode, 15)))
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, 15)
@@ -396,7 +446,7 @@ typedef struct
do \
{ \
if ((LOG) == 0) \
- break; \
+ break; \
fprintf (STREAM, "\t.balign %d\n", 1 << (LOG)); \
} \
while (0)
@@ -416,7 +466,8 @@ typedef struct
/* Prevent reload (and others) from choosing HImode stack slots
when spilling hard registers when they may contain PSImode values. */
#define HARD_REGNO_CALLER_SAVE_MODE(REGNO,NREGS,MODE) \
- ((TARGET_LARGE && ((NREGS) <= 2)) ? PSImode : choose_hard_reg_mode ((REGNO), (NREGS), false))
+ ((TARGET_LARGE && ((NREGS) <= 2)) ? PSImode \
+ : choose_hard_reg_mode ((REGNO), (NREGS), false))
#define ACCUMULATE_OUTGOING_ARGS 1
diff --git a/gcc/config/msp430/msp430.opt b/gcc/config/msp430/msp430.opt
index c027201..cbbe0fa 100644
--- a/gcc/config/msp430/msp430.opt
+++ b/gcc/config/msp430/msp430.opt
@@ -14,6 +14,10 @@ mwarn-mcu
Target Report Var(msp430_warn_mcu) Init(1)
Warn if an MCU name is unrecognized or conflicts with other options (default: on).
+mwarn-devices-csv
+Target Report Var(msp430_warn_devices_csv) Init(1)
+Warn if devices.csv is not found or there are problem parsing it (default: on).
+
mcpu=
Target Report Joined RejectNegative Var(target_cpu)
Specify the ISA to build for: msp430, msp430x, msp430xv2.
@@ -92,3 +96,8 @@ Passes on a request to the assembler to enable fixes for various silicon errata.
msilicon-errata-warn=
Target Joined RejectNegative Report ToLower
Passes on a request to the assembler to warn about various silicon errata.
+
+mdevices-csv-loc=
+Target Joined Var(msp430_devices_csv_loc) RejectNegative Report
+The path to devices.csv. The GCC driver can normally locate devices.csv itself
+and pass this option to the compiler, so the user shouldn't need to pass this.
diff --git a/gcc/config/msp430/t-msp430 b/gcc/config/msp430/t-msp430
index edfdad7..b956510 100644
--- a/gcc/config/msp430/t-msp430
+++ b/gcc/config/msp430/t-msp430
@@ -22,6 +22,10 @@ driver-msp430.o: $(srcdir)/config/msp430/driver-msp430.c \
$(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+msp430-devices.o: $(srcdir)/config/msp430/msp430-devices.c \
+ $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
+
# Enable multilibs:
MULTILIB_OPTIONS = mcpu=msp430 mlarge
@@ -30,235 +34,9 @@ MULTILIB_DIRNAMES = 430 large
# Match -mcpu=430
MULTILIB_MATCHES = mcpu?msp430=mcpu?430
-# Match the known 430 ISA mcu names.
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c091
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c092
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c111
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c1111
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c112
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c1121
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c1331
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c1351
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c311s
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c312
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c313
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c314
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c315
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c323
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c325
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c412
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c413
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430e112
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430e313
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430e315
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430e325
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f110
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1101
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1101a
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1111
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1111a
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f112
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1121
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1121a
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1122
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1132
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f122
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1222
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f123
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1232
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f133
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f135
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f155
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f156
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f157
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2001
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2002
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2003
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2011
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2012
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2013
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2101
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2111
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2112
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2121
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2122
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2131
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2132
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2232
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2234
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2252
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2254
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2272
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2274
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f412
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f413
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f4132
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f415
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f4152
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f417
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f4250
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f4260
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f4270
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f435
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f4351
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f436
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f4361
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f437
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f4371
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f438
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f439
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f477
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f478
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f479
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fe423
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fe4232
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fe423a
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fe4242
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fe425
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fe4252
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fe425a
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fe427
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fe4272
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fe427a
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fg4250
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fg4260
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fg4270
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fg437
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fg438
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fg439
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fg477
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fg478
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fg479
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fw423
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fw425
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fw427
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fw428
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430fw429
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2001
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2101
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2102
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2111
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2112
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2113
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2121
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2131
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2132
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2152
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2153
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2201
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2202
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2203
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2210
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2211
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2212
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2213
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2221
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2230
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2231
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2232
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2233
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2252
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2253
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2302
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2303
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2312
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2313
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2332
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2333
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2352
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2353
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2402
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2403
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2412
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2413
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2432
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2433
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2444
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2452
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2453
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2513
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2533
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2544
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2553
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2744
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2755
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2855
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430g2955
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430l092
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430p112
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430p313
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430p315
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430p315s
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430p325
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430tch5e
-MULTILIB_MATCHES += mcpu?msp430=mmcu?rf430frl152h
-MULTILIB_MATCHES += mcpu?msp430=mmcu?rf430frl152h_rom
-MULTILIB_MATCHES += mcpu?msp430=mmcu?rf430frl153h
-MULTILIB_MATCHES += mcpu?msp430=mmcu?rf430frl153h_rom
-MULTILIB_MATCHES += mcpu?msp430=mmcu?rf430frl154h
-MULTILIB_MATCHES += mcpu?msp430=mmcu?rf430frl154h_rom
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c336
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430c337
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430e337
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f147
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1471
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f148
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1481
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f149
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1491
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1610
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1611
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f1612
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f167
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f168
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f169
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f423
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f423a
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f425
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f425a
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f427
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f427a
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f447
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f448
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f4481
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f449
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f4491
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430p337
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430afe221
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430afe222
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430afe223
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430afe231
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430afe232
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430afe233
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430afe251
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430afe252
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430afe253
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f233
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2330
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f235
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2350
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2370
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2410
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f247
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2471
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f248
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2481
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f249
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f2491
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430i2020
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430i2021
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430i2030
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430i2031
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430i2040
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430i2041
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430i2xxgeneric
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f4783
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f4784
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f4793
-MULTILIB_MATCHES += mcpu?msp430=mmcu?msp430f4794
-
-# Add additional MCU matches like this:
-# MULTILIB_MATCHES += mcpu?msp430x=mmcu?xxxxxxxxxx
+# The correct multilib for a given mmcu is selected without the need for
+# hard-coded data here, because DRIVER_SELF_SPECS will place the correct
+# -mcpu option for a given mcu onto the command line.
MULTILIB_EXCEPTIONS = mcpu=msp430/mlarge
diff --git a/gcc/config/nds32/nds32-intrinsic.c b/gcc/config/nds32/nds32-intrinsic.c
index c78dc93..1348591 100644
--- a/gcc/config/nds32/nds32-intrinsic.c
+++ b/gcc/config/nds32/nds32-intrinsic.c
@@ -993,7 +993,7 @@ nds32_expand_builtin_impl (tree exp,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
unsigned i;
struct builtin_description *d;
diff --git a/gcc/config/nios2/nios2.c b/gcc/config/nios2/nios2.c
index 250c6ac..e54bdba 100644
--- a/gcc/config/nios2/nios2.c
+++ b/gcc/config/nios2/nios2.c
@@ -4009,7 +4009,7 @@ nios2_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
if (fcode < nios2_fpu_builtin_base)
{
diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c
index c53a1ae..ce4602f 100644
--- a/gcc/config/nvptx/nvptx.c
+++ b/gcc/config/nvptx/nvptx.c
@@ -5452,7 +5452,7 @@ nvptx_expand_builtin (tree exp, rtx target, rtx ARG_UNUSED (subtarget),
machine_mode mode, int ignore)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- switch (DECL_FUNCTION_CODE (fndecl))
+ switch (DECL_MD_FUNCTION_CODE (fndecl))
{
case NVPTX_BUILTIN_SHUFFLE:
case NVPTX_BUILTIN_SHUFFLELL:
diff --git a/gcc/config/pa/pa-netbsd.h b/gcc/config/pa/pa-netbsd.h
new file mode 100644
index 0000000..af07444
--- /dev/null
+++ b/gcc/config/pa/pa-netbsd.h
@@ -0,0 +1,137 @@
+/* Definitions for PA_RISC with ELF format
+ Copyright (C) 1999-2019 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/>. */
+
+
+#undef TARGET_OS_CPP_BUILTINS
+#define TARGET_OS_CPP_BUILTINS() \
+ do \
+ { \
+ NETBSD_OS_CPP_BUILTINS_ELF(); \
+ builtin_assert ("machine=bigendian"); \
+ } \
+ while (0)
+
+#undef CPP_SPEC
+#define CPP_SPEC NETBSD_CPP_SPEC
+
+#undef ASM_SPEC
+#define ASM_SPEC \
+ "%{v:-V} %{n} %{T} %{Ym,*} %{Yd,*} %{Wa,*:%*}"
+
+#undef EXTRA_SPECS
+#define EXTRA_SPECS NETBSD_SUBTARGET_EXTRA_SPECS
+#undef SUBTARGET_EXTRA_SPECS
+
+#define NETBSD_ENTRY_POINT "__start"
+
+#undef LINK_SPEC
+#define LINK_SPEC NETBSD_LINK_SPEC_ELF
+
+/* NetBSD profiling functions don't need gcc to allocate counters. */
+#define NO_DEFERRED_PROFILE_COUNTERS 1
+
+/* Define the strings used for the special svr4 .type and .size directives.
+ These strings generally do not vary from one system running svr4 to
+ another, but if a given system (e.g. m88k running svr) needs to use
+ different pseudo-op names for these, they may be overridden in the
+ file which includes this one. */
+
+#undef STRING_ASM_OP
+#define STRING_ASM_OP "\t.stringz\t"
+
+#define TEXT_SECTION_ASM_OP "\t.text"
+#define DATA_SECTION_ASM_OP "\t.data"
+#define BSS_SECTION_ASM_OP "\t.section\t.bss"
+
+#define TARGET_ASM_FILE_START pa_linux_file_start
+
+/* We want local labels to start with period if made with asm_fprintf. */
+#undef LOCAL_LABEL_PREFIX
+#define LOCAL_LABEL_PREFIX "."
+
+/* Define these to generate the Linux/ELF/SysV style of internal
+ labels all the time - i.e. to be compatible with
+ ASM_GENERATE_INTERNAL_LABEL in <elfos.h>. Compare these with the
+ ones in pa.h and note the lack of dollar signs in these. FIXME:
+ shouldn't we fix pa.h to use ASM_GENERATE_INTERNAL_LABEL instead? */
+
+#undef ASM_OUTPUT_ADDR_VEC_ELT
+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
+ fprintf (FILE, "\t.word .L%d\n", VALUE)
+
+#undef ASM_OUTPUT_ADDR_DIFF_ELT
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
+ fprintf (FILE, "\t.word .L%d-.L%d\n", VALUE, REL)
+
+/* Use the default. */
+#undef ASM_OUTPUT_LABEL
+
+/* NOTE: (*targetm.asm_out.internal_label)() is defined for us by elfos.h, and
+ does what we want (i.e. uses colons). It must be compatible with
+ ASM_GENERATE_INTERNAL_LABEL(), so do not define it here. */
+
+/* Use the default. */
+#undef ASM_OUTPUT_INTERNAL_LABEL
+
+/* Use the default. */
+#undef TARGET_ASM_GLOBALIZE_LABEL
+/* Globalizing directive for a label. */
+#define GLOBAL_ASM_OP ".globl "
+
+/* FIXME: Hacked from the <elfos.h> one so that we avoid multiple
+ labels in a function declaration (since pa.c seems determined to do
+ it differently) */
+
+#undef ASM_DECLARE_FUNCTION_NAME
+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
+ do \
+ { \
+ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
+ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
+ } \
+ while (0)
+
+/* As well as globalizing the label, we need to encode the label
+ to ensure a plabel is generated in an indirect call. */
+
+#undef ASM_OUTPUT_EXTERNAL_LIBCALL
+#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, FUN) \
+ do \
+ { \
+ if (!FUNCTION_NAME_P (XSTR (FUN, 0))) \
+ pa_encode_label (FUN); \
+ (*targetm.asm_out.globalize_label) (FILE, XSTR (FUN, 0)); \
+ } \
+ while (0)
+
+/* NetBSD always uses gas. */
+#undef TARGET_GAS
+#define TARGET_GAS 1
+
+/* Use long int for these type to make hppa64 compatibility easier. */
+#undef SIZE_TYPE
+#define SIZE_TYPE "long unsigned int"
+
+#undef PTRDIFF_TYPE
+#define PTRDIFF_TYPE "long int"
+
+#if 0
+#undef TARGET_SYNC_LIBCALL
+#define TARGET_SYNC_LIBCALL 1
+#endif
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index f54ca6e..0ab95d8 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -653,7 +653,7 @@ pa_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
switch (fcode)
{
diff --git a/gcc/config/pa/pa32-netbsd.h b/gcc/config/pa/pa32-netbsd.h
new file mode 100644
index 0000000..43a435c
--- /dev/null
+++ b/gcc/config/pa/pa32-netbsd.h
@@ -0,0 +1,37 @@
+/* Definitions for PA_RISC with ELF-32 format
+ Copyright (C) 2000-2019 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 2, 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 COPYING. If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Turn off various SOM crap we don't want. */
+#undef TARGET_ELF32
+#define TARGET_ELF32 1
+
+/* The libcall __canonicalize_funcptr_for_compare is referenced in
+ crtend.o and the reference isn't resolved in objects that don't
+ compare function pointers. Thus, we need to play games to provide
+ a reference in crtbegin.o. The rest of the define is the same
+ as that in crtstuff.c */
+#define CTOR_LIST_BEGIN \
+ asm (".type __canonicalize_funcptr_for_compare,@function\n" \
+" .text\n" \
+" .word __canonicalize_funcptr_for_compare-$PIC_pcrel$0"); \
+ STATIC func_ptr __CTOR_LIST__[1] \
+ __attribute__ ((__used__, section(".ctors"), \
+ aligned(sizeof(func_ptr)))) \
+ = { (func_ptr) (-1) }
diff --git a/gcc/config/pru/pru.c b/gcc/config/pru/pru.c
index c764694..4e1c081 100644
--- a/gcc/config/pru/pru.c
+++ b/gcc/config/pru/pru.c
@@ -2873,7 +2873,7 @@ pru_expand_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
if (fcode == PRU_BUILTIN_DELAY_CYCLES)
diff --git a/gcc/config/riscv/multilib-generator b/gcc/config/riscv/multilib-generator
index a711153..a4125ff 100755
--- a/gcc/config/riscv/multilib-generator
+++ b/gcc/config/riscv/multilib-generator
@@ -36,6 +36,41 @@ abis = collections.OrderedDict()
required = []
reuse = []
+canonical_order = "mafdgqlcbjtpvn"
+
+def arch_canonicalize(arch):
+ # TODO: Support Z, S, H, or X extensions.
+ # TODO: Support implied extensions, e.g. D implied F in latest spec.
+ # TODO: Support extension version.
+ new_arch = ""
+ if arch[:5] in ['rv32e', 'rv32i', 'rv32g', 'rv64i', 'rv64g']:
+ new_arch = arch[:5]
+ else:
+ raise Exception("Unexpected arch: `%s`" % arch[:5])
+
+ # Find any Z, S, H or X
+ long_ext_prefixes = ['z', 's', 'h', 'x']
+ long_ext_prefixes_idx = map(lambda x: arch.find(x), long_ext_prefixes)
+
+ # Filter out any non-existent index.
+ long_ext_prefixes_idx = list(filter(lambda x: x != -1, long_ext_prefixes_idx))
+ if long_ext_prefixes_idx:
+ first_long_ext_idx = min(long_ext_prefixes_idx)
+ long_exts = arch[first_long_ext_idx:]
+ std_exts = arch[5:first_long_ext_idx]
+ else:
+ long_exts = ""
+ std_exts = arch[5:]
+
+ # Put extensions in canonical order.
+ for ext in canonical_order:
+ if ext in std_exts:
+ new_arch += ext
+
+ # Concat rest of the multi-char extensions.
+ new_arch += long_exts
+ return new_arch
+
for cfg in sys.argv[1:]:
(arch, abi, extra, ext) = cfg.split('-')
arches[arch] = 1
@@ -43,7 +78,9 @@ for cfg in sys.argv[1:]:
extra = list(filter(None, extra.split(',')))
ext = list(filter(None, ext.split(',')))
alts = sum([[x] + [x + y for y in ext] for x in [arch] + extra], [])
+ # TODO: We should expand g to imadzifencei once we support newer spec.
alts = alts + [x.replace('imafd', 'g') for x in alts if 'imafd' in x]
+ alts = list(map(arch_canonicalize, alts))
for alt in alts[1:]:
arches[alt] = 1
reuse.append('march.%s/mabi.%s=march.%s/mabi.%s' % (arch, abi, alt, abi))
diff --git a/gcc/config/riscv/riscv-builtins.c b/gcc/config/riscv/riscv-builtins.c
index 5482671..80169fa 100644
--- a/gcc/config/riscv/riscv-builtins.c
+++ b/gcc/config/riscv/riscv-builtins.c
@@ -256,7 +256,7 @@ riscv_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
const struct riscv_builtin_description *d = &riscv_builtins[fcode];
switch (d->builtin_type)
diff --git a/gcc/config/riscv/riscv.c b/gcc/config/riscv/riscv.c
index e274f1b..c12b26f 100644
--- a/gcc/config/riscv/riscv.c
+++ b/gcc/config/riscv/riscv.c
@@ -2383,7 +2383,8 @@ typedef struct {
static int
riscv_flatten_aggregate_field (const_tree type,
riscv_aggregate_field fields[2],
- int n, HOST_WIDE_INT offset)
+ int n, HOST_WIDE_INT offset,
+ bool ignore_zero_width_bit_field_p)
{
switch (TREE_CODE (type))
{
@@ -2400,8 +2401,21 @@ riscv_flatten_aggregate_field (const_tree type,
if (!TYPE_P (TREE_TYPE (f)))
return -1;
- HOST_WIDE_INT pos = offset + int_byte_position (f);
- n = riscv_flatten_aggregate_field (TREE_TYPE (f), fields, n, pos);
+ /* The C++ front end strips zero-length bit-fields from structs.
+ So we need to ignore them in the C front end to make C code
+ compatible with C++ code. */
+ if (ignore_zero_width_bit_field_p
+ && DECL_BIT_FIELD (f)
+ && (DECL_SIZE (f) == NULL_TREE
+ || integer_zerop (DECL_SIZE (f))))
+ ;
+ else
+ {
+ HOST_WIDE_INT pos = offset + int_byte_position (f);
+ n = riscv_flatten_aggregate_field (TREE_TYPE (f),
+ fields, n, pos,
+ ignore_zero_width_bit_field_p);
+ }
if (n < 0)
return -1;
}
@@ -2414,7 +2428,8 @@ riscv_flatten_aggregate_field (const_tree type,
tree index = TYPE_DOMAIN (type);
tree elt_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
int n_subfields = riscv_flatten_aggregate_field (TREE_TYPE (type),
- subfields, 0, offset);
+ subfields, 0, offset,
+ ignore_zero_width_bit_field_p);
/* Can't handle incomplete types nor sizes that are not fixed. */
if (n_subfields <= 0
@@ -2487,12 +2502,14 @@ riscv_flatten_aggregate_field (const_tree type,
static int
riscv_flatten_aggregate_argument (const_tree type,
- riscv_aggregate_field fields[2])
+ riscv_aggregate_field fields[2],
+ bool ignore_zero_width_bit_field_p)
{
if (!type || TREE_CODE (type) != RECORD_TYPE)
return -1;
- return riscv_flatten_aggregate_field (type, fields, 0, 0);
+ return riscv_flatten_aggregate_field (type, fields, 0, 0,
+ ignore_zero_width_bit_field_p);
}
/* See whether TYPE is a record whose fields should be returned in one or
@@ -2502,13 +2519,34 @@ static unsigned
riscv_pass_aggregate_in_fpr_pair_p (const_tree type,
riscv_aggregate_field fields[2])
{
- int n = riscv_flatten_aggregate_argument (type, fields);
+ static int warned = 0;
- for (int i = 0; i < n; i++)
+ /* This is the old ABI, which differs for C++ and C. */
+ int n_old = riscv_flatten_aggregate_argument (type, fields, false);
+ for (int i = 0; i < n_old; i++)
if (!SCALAR_FLOAT_TYPE_P (fields[i].type))
- return 0;
+ {
+ n_old = -1;
+ break;
+ }
- return n > 0 ? n : 0;
+ /* This is the new ABI, which is the same for C++ and C. */
+ int n_new = riscv_flatten_aggregate_argument (type, fields, true);
+ for (int i = 0; i < n_new; i++)
+ if (!SCALAR_FLOAT_TYPE_P (fields[i].type))
+ {
+ n_new = -1;
+ break;
+ }
+
+ if ((n_old != n_new) && (warned == 0))
+ {
+ warning (0, "ABI for flattened struct with zero-length bit-fields "
+ "changed in GCC 10");
+ warned = 1;
+ }
+
+ return n_new > 0 ? n_new : 0;
}
/* See whether TYPE is a record whose fields should be returned in one or
@@ -2519,16 +2557,38 @@ static bool
riscv_pass_aggregate_in_fpr_and_gpr_p (const_tree type,
riscv_aggregate_field fields[2])
{
- unsigned num_int = 0, num_float = 0;
- int n = riscv_flatten_aggregate_argument (type, fields);
+ static int warned = 0;
- for (int i = 0; i < n; i++)
+ /* This is the old ABI, which differs for C++ and C. */
+ unsigned num_int_old = 0, num_float_old = 0;
+ int n_old = riscv_flatten_aggregate_argument (type, fields, false);
+ for (int i = 0; i < n_old; i++)
{
- num_float += SCALAR_FLOAT_TYPE_P (fields[i].type);
- num_int += INTEGRAL_TYPE_P (fields[i].type);
+ num_float_old += SCALAR_FLOAT_TYPE_P (fields[i].type);
+ num_int_old += INTEGRAL_TYPE_P (fields[i].type);
}
- return num_int == 1 && num_float == 1;
+ /* This is the new ABI, which is the same for C++ and C. */
+ unsigned num_int_new = 0, num_float_new = 0;
+ int n_new = riscv_flatten_aggregate_argument (type, fields, true);
+ for (int i = 0; i < n_new; i++)
+ {
+ num_float_new += SCALAR_FLOAT_TYPE_P (fields[i].type);
+ num_int_new += INTEGRAL_TYPE_P (fields[i].type);
+ }
+
+ if (((num_int_old == 1 && num_float_old == 1
+ && (num_int_old != num_int_new || num_float_old != num_float_new))
+ || (num_int_new == 1 && num_float_new == 1
+ && (num_int_old != num_int_new || num_float_old != num_float_new)))
+ && (warned == 0))
+ {
+ warning (0, "ABI for flattened struct with zero-length bit-fields "
+ "changed in GCC 10");
+ warned = 1;
+ }
+
+ return num_int_new == 1 && num_float_new == 1;
}
/* Return the representation of an argument passed or returned in an FPR
@@ -4910,6 +4970,32 @@ riscv_constant_alignment (const_tree exp, HOST_WIDE_INT align)
return align;
}
+/* Implement TARGET_PROMOTE_FUNCTION_MODE. */
+
+/* This function is equivalent to default_promote_function_mode_always_promote
+ except that it returns a promoted mode even if type is NULL_TREE. This is
+ needed by libcalls which have no type (only a mode) such as fixed conversion
+ routines that take a signed or unsigned char/short/int argument and convert
+ it to a fixed type. */
+
+static machine_mode
+riscv_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
+ machine_mode mode,
+ int *punsignedp ATTRIBUTE_UNUSED,
+ const_tree fntype ATTRIBUTE_UNUSED,
+ int for_return ATTRIBUTE_UNUSED)
+{
+ int unsignedp;
+
+ if (type != NULL_TREE)
+ return promote_mode (type, mode, punsignedp);
+
+ unsignedp = *punsignedp;
+ PROMOTE_MODE (mode, unsignedp, type);
+ *punsignedp = unsignedp;
+ return mode;
+}
+
/* Initialize the GCC target structure. */
#undef TARGET_ASM_ALIGNED_HI_OP
#define TARGET_ASM_ALIGNED_HI_OP "\t.half\t"
@@ -4951,7 +5037,7 @@ riscv_constant_alignment (const_tree exp, HOST_WIDE_INT align)
#define TARGET_EXPAND_BUILTIN_VA_START riscv_va_start
#undef TARGET_PROMOTE_FUNCTION_MODE
-#define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
+#define TARGET_PROMOTE_FUNCTION_MODE riscv_promote_function_mode
#undef TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY riscv_return_in_memory
diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h
index 1bfb577..a626325 100644
--- a/gcc/config/rs6000/darwin.h
+++ b/gcc/config/rs6000/darwin.h
@@ -52,19 +52,28 @@
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
- if (!TARGET_64BIT) builtin_define ("__ppc__"); \
- if (!TARGET_64BIT) builtin_define ("__PPC__"); \
- if (TARGET_64BIT) builtin_define ("__ppc64__"); \
- if (TARGET_64BIT) builtin_define ("__PPC64__"); \
builtin_define ("__POWERPC__"); \
+ builtin_define ("__PPC__"); \
+ if (TARGET_64BIT) \
+ { \
+ builtin_define ("__ppc64__"); \
+ builtin_define ("__PPC64__"); \
+ builtin_define ("__powerpc64__"); \
+ builtin_assert ("cpu=powerpc64"); \
+ builtin_assert ("machine=powerpc64"); \
+ } \
+ else \
+ { \
+ builtin_define ("__ppc__"); \
+ builtin_define_std ("PPC"); \
+ builtin_assert ("cpu=powerpc"); \
+ builtin_assert ("machine=powerpc"); \
+ } \
builtin_define ("__NATURAL_ALIGNMENT__"); \
darwin_cpp_builtins (pfile); \
} \
while (0)
-/* Generate pic symbol stubs if this is true. */
-extern int darwin_emit_picsym_stub;
-
#define SUBTARGET_OVERRIDE_OPTIONS darwin_rs6000_override_options ()
#define C_COMMON_OVERRIDE_OPTIONS do { \
@@ -117,11 +126,10 @@ extern int darwin_emit_picsym_stub;
%<faltivec %<fno-altivec " \
DARWIN_CC1_SPEC
-#define DARWIN_ARCH_SPEC "%{m64:ppc64;:ppc}"
+/* Default to PPC for single arch builds. */
+#define DARWIN_ARCH_SPEC "ppc"
#define DARWIN_SUBARCH_SPEC " \
- %{m64: ppc64} \
- %{!m64: \
%{mcpu=601:ppc601; \
mcpu=603:ppc603; \
mcpu=603e:ppc603; \
@@ -136,7 +144,7 @@ extern int darwin_emit_picsym_stub;
mcpu=970:ppc970; \
mcpu=power4:ppc970; \
mcpu=G5:ppc970; \
- :ppc}}"
+ :ppc}"
/* We need to jam the crt to 10.5 for 10.6 (Rosetta) use. */
#undef DARWIN_CRT1_SPEC
diff --git a/gcc/config/rs6000/darwin32-biarch.h b/gcc/config/rs6000/darwin32-biarch.h
new file mode 100644
index 0000000..743aabf
--- /dev/null
+++ b/gcc/config/rs6000/darwin32-biarch.h
@@ -0,0 +1,49 @@
+/* Target definitions for PowerPC running Darwin (Mac OS X) for a 32b host
+ with a 64b miultilib.
+ Copyright (C) 2019 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/>. */
+
+#undef DARWIN_ARCH_SPEC
+#define DARWIN_ARCH_SPEC "%{m64:ppc64;:ppc}"
+
+#undef DARWIN_SUBARCH_SPEC
+#define DARWIN_SUBARCH_SPEC " \
+ %{m64: ppc64} \
+ %{!m64: \
+ %{mcpu=601:ppc601; \
+ mcpu=603:ppc603; \
+ mcpu=603e:ppc603; \
+ mcpu=604:ppc604; \
+ mcpu=604e:ppc604e; \
+ mcpu=740:ppc750; \
+ mcpu=750:ppc750; \
+ mcpu=G3:ppc750; \
+ mcpu=7400:ppc7400; \
+ mcpu=G4:ppc7400; \
+ mcpu=7450:ppc7450; \
+ mcpu=970:ppc970; \
+ mcpu=power4:ppc970; \
+ mcpu=G5:ppc970; \
+ :ppc}}"
+
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ DARWIN_EXTRA_SPECS \
+ { "darwin_arch", DARWIN_ARCH_SPEC }, \
+ { "darwin_crt2", DARWIN_CRT2_SPEC }, \
+ { "darwin_subarch", DARWIN_SUBARCH_SPEC },
diff --git a/gcc/config/rs6000/darwin64.h b/gcc/config/rs6000/darwin64-biarch.h
index a131ff2..4f78954 100644
--- a/gcc/config/rs6000/darwin64.h
+++ b/gcc/config/rs6000/darwin64-biarch.h
@@ -1,4 +1,5 @@
-/* Target definitions for PowerPC running Darwin (Mac OS X).
+/* Target definitions for PowerPC64 running Darwin (Mac OS X) for a 64b host
+ supporting a 32b multilib.
Copyright (C) 2006-2019 Free Software Foundation, Inc.
Contributed by Apple Computer Inc.
@@ -25,8 +26,13 @@
#undef DARWIN_ARCH_SPEC
#define DARWIN_ARCH_SPEC "%{m32:ppc;:ppc64}"
+/* Actually, there's really only 970 as an active option. */
#undef DARWIN_SUBARCH_SPEC
#define DARWIN_SUBARCH_SPEC DARWIN_ARCH_SPEC
-#undef DARWIN_CRT2_SPEC
-#define DARWIN_CRT2_SPEC ""
+#undef SUBTARGET_EXTRA_SPECS
+#define SUBTARGET_EXTRA_SPECS \
+ DARWIN_EXTRA_SPECS \
+ { "darwin_arch", DARWIN_ARCH_SPEC }, \
+ { "darwin_crt2", "" }, \
+ { "darwin_subarch", DARWIN_SUBARCH_SPEC },
diff --git a/gcc/config/rs6000/default64.h b/gcc/config/rs6000/default64.h
index 0cceefe..10743fe 100644
--- a/gcc/config/rs6000/default64.h
+++ b/gcc/config/rs6000/default64.h
@@ -25,7 +25,11 @@ along with GCC; see the file COPYING3. If not see
#if (TARGET_DEFAULT & MASK_LITTLE_ENDIAN)
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (ISA_2_7_MASKS_SERVER | MASK_POWERPC64 | MASK_64BIT | MASK_LITTLE_ENDIAN)
+#undef ASM_DEFAULT_SPEC
+#define ASM_DEFAULT_SPEC "-mpower8"
#else
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_PPC_GFXOPT | MASK_PPC_GPOPT | MASK_MFCRF | MASK_POWERPC64 | MASK_64BIT)
+#undef ASM_DEFAULT_SPEC
+#define ASM_DEFAULT_SPEC "-mpower4"
#endif
diff --git a/gcc/config/rs6000/dfp.md b/gcc/config/rs6000/dfp.md
index 1b238d2..659b3c9 100644
--- a/gcc/config/rs6000/dfp.md
+++ b/gcc/config/rs6000/dfp.md
@@ -28,6 +28,11 @@
UNSPEC_MOVSD_STORE
])
+; Either of the two decimal modes.
+(define_mode_iterator DDTD [DD TD])
+
+(define_mode_attr q [(DD "") (TD "q")])
+
(define_insn "movsd_store"
[(set (match_operand:DD 0 "nonimmediate_operand" "=m")
@@ -150,84 +155,44 @@
[(set_attr "type" "dfp")
(set_attr "length" "8")])
-(define_insn "adddd3"
- [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
- (plus:DD (match_operand:DD 1 "gpc_reg_operand" "%d")
- (match_operand:DD 2 "gpc_reg_operand" "d")))]
- "TARGET_DFP"
- "dadd %0,%1,%2"
- [(set_attr "type" "dfp")])
-
-(define_insn "addtd3"
- [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
- (plus:TD (match_operand:TD 1 "gpc_reg_operand" "%d")
- (match_operand:TD 2 "gpc_reg_operand" "d")))]
- "TARGET_DFP"
- "daddq %0,%1,%2"
- [(set_attr "type" "dfp")])
-
-(define_insn "subdd3"
- [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
- (minus:DD (match_operand:DD 1 "gpc_reg_operand" "d")
- (match_operand:DD 2 "gpc_reg_operand" "d")))]
- "TARGET_DFP"
- "dsub %0,%1,%2"
- [(set_attr "type" "dfp")])
-
-(define_insn "subtd3"
- [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
- (minus:TD (match_operand:TD 1 "gpc_reg_operand" "d")
- (match_operand:TD 2 "gpc_reg_operand" "d")))]
- "TARGET_DFP"
- "dsubq %0,%1,%2"
- [(set_attr "type" "dfp")])
-
-(define_insn "muldd3"
- [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
- (mult:DD (match_operand:DD 1 "gpc_reg_operand" "%d")
- (match_operand:DD 2 "gpc_reg_operand" "d")))]
- "TARGET_DFP"
- "dmul %0,%1,%2"
- [(set_attr "type" "dfp")])
-
-(define_insn "multd3"
- [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
- (mult:TD (match_operand:TD 1 "gpc_reg_operand" "%d")
- (match_operand:TD 2 "gpc_reg_operand" "d")))]
+(define_insn "add<mode>3"
+ [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
+ (plus:DDTD (match_operand:DDTD 1 "gpc_reg_operand" "%d")
+ (match_operand:DDTD 2 "gpc_reg_operand" "d")))]
"TARGET_DFP"
- "dmulq %0,%1,%2"
+ "dadd<q> %0,%1,%2"
[(set_attr "type" "dfp")])
-(define_insn "divdd3"
- [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
- (div:DD (match_operand:DD 1 "gpc_reg_operand" "d")
- (match_operand:DD 2 "gpc_reg_operand" "d")))]
+(define_insn "sub<mode>3"
+ [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
+ (minus:DDTD (match_operand:DDTD 1 "gpc_reg_operand" "d")
+ (match_operand:DDTD 2 "gpc_reg_operand" "d")))]
"TARGET_DFP"
- "ddiv %0,%1,%2"
+ "dsub<q> %0,%1,%2"
[(set_attr "type" "dfp")])
-(define_insn "divtd3"
- [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
- (div:TD (match_operand:TD 1 "gpc_reg_operand" "d")
- (match_operand:TD 2 "gpc_reg_operand" "d")))]
+(define_insn "mul<mode>3"
+ [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
+ (mult:DDTD (match_operand:DDTD 1 "gpc_reg_operand" "%d")
+ (match_operand:DDTD 2 "gpc_reg_operand" "d")))]
"TARGET_DFP"
- "ddivq %0,%1,%2"
+ "dmul<q> %0,%1,%2"
[(set_attr "type" "dfp")])
-(define_insn "*cmpdd_internal1"
- [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (compare:CCFP (match_operand:DD 1 "gpc_reg_operand" "d")
- (match_operand:DD 2 "gpc_reg_operand" "d")))]
+(define_insn "div<mode>3"
+ [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
+ (div:DDTD (match_operand:DDTD 1 "gpc_reg_operand" "d")
+ (match_operand:DDTD 2 "gpc_reg_operand" "d")))]
"TARGET_DFP"
- "dcmpu %0,%1,%2"
+ "ddiv<q> %0,%1,%2"
[(set_attr "type" "dfp")])
-(define_insn "*cmptd_internal1"
+(define_insn "*cmp<mode>_internal1"
[(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
- (compare:CCFP (match_operand:TD 1 "gpc_reg_operand" "d")
- (match_operand:TD 2 "gpc_reg_operand" "d")))]
+ (compare:CCFP (match_operand:DDTD 1 "gpc_reg_operand" "d")
+ (match_operand:DDTD 2 "gpc_reg_operand" "d")))]
"TARGET_DFP"
- "dcmpuq %0,%1,%2"
+ "dcmpu<q> %0,%1,%2"
[(set_attr "type" "dfp")])
(define_insn "floatdidd2"
@@ -244,46 +209,25 @@
"dcffixq %0,%1"
[(set_attr "type" "dfp")])
-;; Convert a decimal64 to a decimal64 whose value is an integer.
-;; This is the first stage of converting it to an integer type.
-
-(define_insn "ftruncdd2"
- [(set (match_operand:DD 0 "gpc_reg_operand" "=d")
- (fix:DD (match_operand:DD 1 "gpc_reg_operand" "d")))]
- "TARGET_DFP"
- "drintn. 0,%0,%1,1"
- [(set_attr "type" "dfp")])
-
-;; Convert a decimal64 whose value is an integer to an actual integer.
-;; This is the second stage of converting decimal float to integer type.
-
-(define_insn "fixdddi2"
- [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
- (fix:DI (match_operand:DD 1 "gpc_reg_operand" "d")))]
- "TARGET_DFP"
- "dctfix %0,%1"
- [(set_attr "type" "dfp")])
-
-;; Convert a decimal128 to a decimal128 whose value is an integer.
+;; Convert a decimal64/128 to a decimal64/128 whose value is an integer.
;; This is the first stage of converting it to an integer type.
-(define_insn "ftrunctd2"
- [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
- (fix:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
+(define_insn "ftrunc<mode>2"
+ [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
+ (fix:DDTD (match_operand:DDTD 1 "gpc_reg_operand" "d")))]
"TARGET_DFP"
- "drintnq. 0,%0,%1,1"
+ "drintn<q>. 0,%0,%1,1"
[(set_attr "type" "dfp")])
-;; Convert a decimal128 whose value is an integer to an actual integer.
+;; Convert a decimal64/128 whose value is an integer to an actual integer.
;; This is the second stage of converting decimal float to integer type.
-(define_insn "fixtddi2"
+(define_insn "fix<mode>di2"
[(set (match_operand:DI 0 "gpc_reg_operand" "=d")
- (fix:DI (match_operand:TD 1 "gpc_reg_operand" "d")))]
+ (fix:DI (match_operand:DDTD 1 "gpc_reg_operand" "d")))]
"TARGET_DFP"
- "dctfixq %0,%1"
+ "dctfix<q> %0,%1"
[(set_attr "type" "dfp")])
-
;; Decimal builtin support
@@ -298,70 +242,62 @@
(define_code_iterator DFP_TEST [eq lt gt unordered])
-(define_mode_iterator D64_D128 [DD TD])
-
-(define_mode_attr dfp_suffix [(DD "")
- (TD "q")])
-
(define_insn "dfp_ddedpd_<mode>"
- [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
- (unspec:D64_D128 [(match_operand:QI 1 "const_0_to_3_operand" "i")
- (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
- UNSPEC_DDEDPD))]
+ [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
+ (unspec:DDTD [(match_operand:QI 1 "const_0_to_3_operand" "i")
+ (match_operand:DDTD 2 "gpc_reg_operand" "d")]
+ UNSPEC_DDEDPD))]
"TARGET_DFP"
- "ddedpd<dfp_suffix> %1,%0,%2"
+ "ddedpd<q> %1,%0,%2"
[(set_attr "type" "dfp")])
(define_insn "dfp_denbcd_<mode>"
- [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
- (unspec:D64_D128 [(match_operand:QI 1 "const_0_to_1_operand" "i")
- (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
- UNSPEC_DENBCD))]
+ [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
+ (unspec:DDTD [(match_operand:QI 1 "const_0_to_1_operand" "i")
+ (match_operand:DDTD 2 "gpc_reg_operand" "d")]
+ UNSPEC_DENBCD))]
"TARGET_DFP"
- "denbcd<dfp_suffix> %1,%0,%2"
+ "denbcd<q> %1,%0,%2"
[(set_attr "type" "dfp")])
(define_insn "dfp_dxex_<mode>"
[(set (match_operand:DI 0 "gpc_reg_operand" "=d")
- (unspec:DI [(match_operand:D64_D128 1 "gpc_reg_operand" "d")]
+ (unspec:DI [(match_operand:DDTD 1 "gpc_reg_operand" "d")]
UNSPEC_DXEX))]
"TARGET_DFP"
- "dxex<dfp_suffix> %0,%1"
+ "dxex<q> %0,%1"
[(set_attr "type" "dfp")])
(define_insn "dfp_diex_<mode>"
- [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
- (unspec:D64_D128 [(match_operand:DI 1 "gpc_reg_operand" "d")
- (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
- UNSPEC_DXEX))]
+ [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
+ (unspec:DDTD [(match_operand:DI 1 "gpc_reg_operand" "d")
+ (match_operand:DDTD 2 "gpc_reg_operand" "d")]
+ UNSPEC_DXEX))]
"TARGET_DFP"
- "diex<dfp_suffix> %0,%1,%2"
+ "diex<q> %0,%1,%2"
[(set_attr "type" "dfp")])
(define_expand "dfptstsfi_<code>_<mode>"
[(set (match_dup 3)
- (compare:CCFP
- (unspec:D64_D128
- [(match_operand:SI 1 "const_int_operand")
- (match_operand:D64_D128 2 "gpc_reg_operand")]
- UNSPEC_DTSTSFI)
- (match_dup 4)))
+ (compare:CCFP (unspec:DDTD [(match_operand:SI 1 "const_int_operand")
+ (match_operand:DDTD 2 "gpc_reg_operand")]
+ UNSPEC_DTSTSFI)
+ (const_int 0)))
(set (match_operand:SI 0 "register_operand")
- (DFP_TEST:SI (match_dup 3)
+ (DFP_TEST:SI (match_dup 3)
(const_int 0)))
]
"TARGET_P9_MISC"
{
operands[3] = gen_reg_rtx (CCFPmode);
- operands[4] = const0_rtx;
})
(define_insn "*dfp_sgnfcnc_<mode>"
[(set (match_operand:CCFP 0 "" "=y")
- (compare:CCFP
- (unspec:D64_D128 [(match_operand:SI 1 "const_int_operand" "n")
- (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
- UNSPEC_DTSTSFI)
+ (compare:CCFP
+ (unspec:DDTD [(match_operand:SI 1 "const_int_operand" "n")
+ (match_operand:DDTD 2 "gpc_reg_operand" "d")]
+ UNSPEC_DTSTSFI)
(match_operand:SI 3 "zero_constant" "j")))]
"TARGET_P9_MISC"
{
@@ -370,24 +306,24 @@
immediate operand values greater than 63. */
if (!(IN_RANGE (INTVAL (operands[1]), 0, 63)))
operands[1] = GEN_INT (63);
- return "dtstsfi<dfp_suffix> %0,%1,%2";
+ return "dtstsfi<q> %0,%1,%2";
}
[(set_attr "type" "fp")])
(define_insn "dfp_dscli_<mode>"
- [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
- (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
- (match_operand:QI 2 "immediate_operand" "i")]
- UNSPEC_DSCLI))]
+ [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
+ (unspec:DDTD [(match_operand:DDTD 1 "gpc_reg_operand" "d")
+ (match_operand:QI 2 "immediate_operand" "i")]
+ UNSPEC_DSCLI))]
"TARGET_DFP"
- "dscli<dfp_suffix> %0,%1,%2"
+ "dscli<q> %0,%1,%2"
[(set_attr "type" "dfp")])
(define_insn "dfp_dscri_<mode>"
- [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
- (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
- (match_operand:QI 2 "immediate_operand" "i")]
- UNSPEC_DSCRI))]
+ [(set (match_operand:DDTD 0 "gpc_reg_operand" "=d")
+ (unspec:DDTD [(match_operand:DDTD 1 "gpc_reg_operand" "d")
+ (match_operand:QI 2 "immediate_operand" "i")]
+ UNSPEC_DSCRI))]
"TARGET_DFP"
- "dscri<dfp_suffix> %0,%1,%2"
+ "dscri<q> %0,%1,%2"
[(set_attr "type" "dfp")])
diff --git a/gcc/config/rs6000/eabialtivec.h b/gcc/config/rs6000/eabialtivec.h
index 6a95f90..6daa922 100644
--- a/gcc/config/rs6000/eabialtivec.h
+++ b/gcc/config/rs6000/eabialtivec.h
@@ -23,5 +23,8 @@
#undef TARGET_DEFAULT
#define TARGET_DEFAULT (MASK_EABI | MASK_ALTIVEC)
+#undef ASM_DEFAULT_EXTRA
+#define ASM_DEFAULT_EXTRA " %{!mvsx:%{!maltivec:%{!no-maltivec:-maltivec}}}"
+
#undef SUBSUBTARGET_OVERRIDE_OPTIONS
#define SUBSUBTARGET_OVERRIDE_OPTIONS rs6000_altivec_abi = 1
diff --git a/gcc/config/rs6000/freebsd64.h b/gcc/config/rs6000/freebsd64.h
index 7e819d1..9367a6e 100644
--- a/gcc/config/rs6000/freebsd64.h
+++ b/gcc/config/rs6000/freebsd64.h
@@ -17,6 +17,10 @@
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
+/* Undef gnu-user.h macros we don't want. */
+#undef CPLUSPLUS_CPP_SPEC
+#undef LINK_GCC_C_SEQUENCE_SPEC
+
/* Override the defaults, which exist to force the proper definition. */
#ifdef IN_LIBGCC2
@@ -134,11 +138,9 @@ extern int dot_symbols;
} \
while (0)
-#undef ASM_DEFAULT_SPEC
#undef ASM_SPEC
#undef LINK_OS_FREEBSD_SPEC
-#define ASM_DEFAULT_SPEC "-mppc%{!m32:64}"
#define ASM_SPEC "%{m32:%(asm_spec32)}%{!m32:%(asm_spec64)} %(asm_spec_common)"
#define LINK_OS_FREEBSD_SPEC "%{m32:%(link_os_freebsd_spec32)}%{!m32:%(link_os_freebsd_spec64)}"
diff --git a/gcc/config/rs6000/future.md b/gcc/config/rs6000/future.md
new file mode 100644
index 0000000..454092b
--- /dev/null
+++ b/gcc/config/rs6000/future.md
@@ -0,0 +1,521 @@
+;; Scheduling description for a future IBM processor.
+;; Copyright (C) 2016-2019 Free Software Foundation, Inc.
+;;
+;; This is a clone of power9.md. It is intended to be a placeholder until a
+;; real scheduler module can be contributed.
+;; The original power9.md was contributed by Pat Haugen (pthaugen@us.ibm.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/>.
+;;
+;; This file was cloned from power9.md. In the future, we will have future
+;; specific optimizations here.
+
+(define_automaton "futuredsp,futurelsu,futurevsu,futurefpdiv,futuremisc")
+
+(define_cpu_unit "lsu0_future,lsu1_future,lsu2_future,lsu3_future" "futurelsu")
+(define_cpu_unit "vsu0_future,vsu1_future,vsu2_future,vsu3_future" "futurevsu")
+; Two vector permute units, part of vsu
+(define_cpu_unit "prm0_future,prm1_future" "futurevsu")
+; Two fixed point divide units, not pipelined
+(define_cpu_unit "fx_div0_future,fx_div1_future" "futuremisc")
+(define_cpu_unit "bru_future,cryptu_future,dfu_future" "futuremisc")
+; Create a false unit for use by non-pipelined FP div/sqrt
+(define_cpu_unit "fp_div0_future,fp_div1_future,fp_div2_future,fp_div3_future"
+ "futurefpdiv")
+
+
+(define_cpu_unit "x0_future,x1_future,xa0_future,xa1_future,
+ x2_future,x3_future,xb0_future,xb1_future,
+ br0_future,br1_future" "futuredsp")
+
+
+; Dispatch port reservations
+;
+; Future can dispatch a maximum of 6 iops per cycle with the following
+; general restrictions (other restrictions also apply):
+; 1) At most 2 iops per execution slice
+; 2) At most 2 iops to the branch unit
+; Note that insn position in a dispatch group of 6 insns does not infer which
+; execution slice the insn is routed to. The units are used to infer the
+; conflicts that exist (i.e. an 'even' requirement will preclude dispatch
+; with 2 insns with 'superslice' requirement).
+
+; The xa0/xa1 units really represent the 3rd dispatch port for a superslice but
+; are listed as separate units to allow those insns that preclude its use to
+; still be scheduled two to a superslice while reserving the 3rd slot. The
+; same applies for xb0/xb1.
+(define_reservation "DU_xa_future" "xa0_future+xa1_future")
+(define_reservation "DU_xb_future" "xb0_future+xb1_future")
+
+; Any execution slice dispatch
+(define_reservation "DU_any_future"
+ "x0_future|x1_future|DU_xa_future|x2_future|x3_future|
+ DU_xb_future")
+
+; Even slice, actually takes even/odd slots
+(define_reservation "DU_even_future" "x0_future+x1_future|x2_future+x3_future")
+
+; Slice plus 3rd slot
+(define_reservation "DU_slice_3_future"
+ "x0_future+xa0_future|x1_future+xa1_future|
+ x2_future+xb0_future|x3_future+xb1_future")
+
+; Superslice
+(define_reservation "DU_super_future"
+ "x0_future+x1_future|x2_future+x3_future")
+
+; 2-way cracked
+(define_reservation "DU_C2_future" "x0_future+x1_future|
+ x1_future+DU_xa_future|
+ x1_future+x2_future|
+ DU_xa_future+x2_future|
+ x2_future+x3_future|
+ x3_future+DU_xb_future")
+
+; 2-way cracked plus 3rd slot
+(define_reservation "DU_C2_3_future" "x0_future+x1_future+xa0_future|
+ x1_future+x2_future+xa1_future|
+ x2_future+x3_future+xb0_future")
+
+; 3-way cracked (consumes whole decode/dispatch cycle)
+(define_reservation "DU_C3_future"
+ "x0_future+x1_future+xa0_future+xa1_future+x2_future+
+ x3_future+xb0_future+xb1_future+br0_future+br1_future")
+
+; Branch ports
+(define_reservation "DU_branch_future" "br0_future|br1_future")
+
+
+; Execution unit reservations
+(define_reservation "LSU_future"
+ "lsu0_future|lsu1_future|lsu2_future|lsu3_future")
+
+(define_reservation "LSU_pair_future"
+ "lsu0_future+lsu1_future|lsu1_future+lsu2_future|
+ lsu2_future+lsu3_future|lsu3_future+lsu0_future")
+
+(define_reservation "VSU_future"
+ "vsu0_future|vsu1_future|vsu2_future|vsu3_future")
+
+(define_reservation "VSU_super_future"
+ "vsu0_future+vsu1_future|vsu2_future+vsu3_future")
+
+(define_reservation "VSU_PRM_future" "prm0_future|prm1_future")
+
+; Define the reservation to be used by FP div/sqrt which allows other insns
+; to be issued to the VSU, but blocks other div/sqrt for a number of cycles.
+; Note that the number of cycles blocked varies depending on insn, but we
+; just use the same number for all in order to keep the number of DFA states
+; reasonable.
+(define_reservation "FP_DIV_future"
+ "fp_div0_future*8|fp_div1_future*8|fp_div2_future*8|
+ fp_div3_future*8")
+(define_reservation "VEC_DIV_future"
+ "fp_div0_future*8+fp_div1_future*8|
+ fp_div2_future*8+fp_div3_future*8")
+
+
+; LS Unit
+(define_insn_reservation "future-load" 4
+ (and (eq_attr "type" "load")
+ (eq_attr "sign_extend" "no")
+ (eq_attr "update" "no")
+ (eq_attr "cpu" "future"))
+ "DU_any_future,LSU_future")
+
+(define_insn_reservation "future-load-update" 4
+ (and (eq_attr "type" "load")
+ (eq_attr "sign_extend" "no")
+ (eq_attr "update" "yes")
+ (eq_attr "cpu" "future"))
+ "DU_C2_future,LSU_future+VSU_future")
+
+(define_insn_reservation "future-load-ext" 6
+ (and (eq_attr "type" "load")
+ (eq_attr "sign_extend" "yes")
+ (eq_attr "update" "no")
+ (eq_attr "cpu" "future"))
+ "DU_C2_future,LSU_future")
+
+(define_insn_reservation "future-load-ext-update" 6
+ (and (eq_attr "type" "load")
+ (eq_attr "sign_extend" "yes")
+ (eq_attr "update" "yes")
+ (eq_attr "cpu" "future"))
+ "DU_C3_future,LSU_future+VSU_future")
+
+(define_insn_reservation "future-fpload-double" 4
+ (and (eq_attr "type" "fpload")
+ (eq_attr "update" "no")
+ (eq_attr "size" "64")
+ (eq_attr "cpu" "future"))
+ "DU_slice_3_future,LSU_future")
+
+(define_insn_reservation "future-fpload-update-double" 4
+ (and (eq_attr "type" "fpload")
+ (eq_attr "update" "yes")
+ (eq_attr "size" "64")
+ (eq_attr "cpu" "future"))
+ "DU_C2_3_future,LSU_future+VSU_future")
+
+; SFmode loads are cracked and have additional 2 cycles over DFmode
+(define_insn_reservation "future-fpload-single" 6
+ (and (eq_attr "type" "fpload")
+ (eq_attr "update" "no")
+ (eq_attr "size" "32")
+ (eq_attr "cpu" "future"))
+ "DU_C2_3_future,LSU_future")
+
+(define_insn_reservation "future-fpload-update-single" 6
+ (and (eq_attr "type" "fpload")
+ (eq_attr "update" "yes")
+ (eq_attr "size" "32")
+ (eq_attr "cpu" "future"))
+ "DU_C3_future,LSU_future+VSU_future")
+
+(define_insn_reservation "future-vecload" 5
+ (and (eq_attr "type" "vecload")
+ (eq_attr "cpu" "future"))
+ "DU_any_future,LSU_pair_future")
+
+; Store data can issue 2 cycles after AGEN issue, 3 cycles for vector store
+(define_insn_reservation "future-store" 0
+ (and (eq_attr "type" "store")
+ (eq_attr "update" "no")
+ (eq_attr "indexed" "no")
+ (eq_attr "cpu" "future"))
+ "DU_slice_3_future,LSU_future")
+
+(define_insn_reservation "future-store-indexed" 0
+ (and (eq_attr "type" "store")
+ (eq_attr "update" "no")
+ (eq_attr "indexed" "yes")
+ (eq_attr "cpu" "future"))
+ "DU_slice_3_future,LSU_future")
+
+; Update forms have 2 cycle latency for updated addr reg
+(define_insn_reservation "future-store-update" 2
+ (and (eq_attr "type" "store")
+ (eq_attr "update" "yes")
+ (eq_attr "indexed" "no")
+ (eq_attr "cpu" "future"))
+ "DU_C2_3_future,LSU_future+VSU_future")
+
+; Update forms have 2 cycle latency for updated addr reg
+(define_insn_reservation "future-store-update-indexed" 2
+ (and (eq_attr "type" "store")
+ (eq_attr "update" "yes")
+ (eq_attr "indexed" "yes")
+ (eq_attr "cpu" "future"))
+ "DU_C2_3_future,LSU_future+VSU_future")
+
+(define_insn_reservation "future-fpstore" 0
+ (and (eq_attr "type" "fpstore")
+ (eq_attr "update" "no")
+ (eq_attr "cpu" "future"))
+ "DU_slice_3_future,LSU_future")
+
+; Update forms have 2 cycle latency for updated addr reg
+(define_insn_reservation "future-fpstore-update" 2
+ (and (eq_attr "type" "fpstore")
+ (eq_attr "update" "yes")
+ (eq_attr "cpu" "future"))
+ "DU_C2_3_future,LSU_future+VSU_future")
+
+(define_insn_reservation "future-vecstore" 0
+ (and (eq_attr "type" "vecstore")
+ (eq_attr "cpu" "future"))
+ "DU_super_future,LSU_pair_future")
+
+(define_insn_reservation "future-larx" 4
+ (and (eq_attr "type" "load_l")
+ (eq_attr "cpu" "future"))
+ "DU_any_future,LSU_future")
+
+(define_insn_reservation "future-stcx" 2
+ (and (eq_attr "type" "store_c")
+ (eq_attr "cpu" "future"))
+ "DU_C2_3_future,LSU_future+VSU_future")
+
+(define_insn_reservation "future-sync" 4
+ (and (eq_attr "type" "sync,isync")
+ (eq_attr "cpu" "future"))
+ "DU_any_future,LSU_future")
+
+
+; VSU Execution Unit
+
+; Fixed point ops
+
+; Most ALU insns are simple 2 cycle, including record form
+(define_insn_reservation "future-alu" 2
+ (and (eq_attr "type" "add,exts,integer,logical,isel")
+ (eq_attr "cpu" "future"))
+ "DU_any_future,VSU_future")
+; 5 cycle CR latency
+(define_bypass 5 "future-alu"
+ "future-crlogical,future-mfcr,future-mfcrf")
+
+; Rotate/shift prevent use of third slot
+(define_insn_reservation "future-rot" 2
+ (and (eq_attr "type" "insert,shift")
+ (eq_attr "dot" "no")
+ (eq_attr "cpu" "future"))
+ "DU_slice_3_future,VSU_future")
+
+; Record form rotate/shift are cracked
+(define_insn_reservation "future-cracked-alu" 2
+ (and (eq_attr "type" "insert,shift")
+ (eq_attr "dot" "yes")
+ (eq_attr "cpu" "future"))
+ "DU_C2_3_future,VSU_future")
+; 7 cycle CR latency
+(define_bypass 7 "future-cracked-alu"
+ "future-crlogical,future-mfcr,future-mfcrf")
+
+(define_insn_reservation "future-alu2" 3
+ (and (eq_attr "type" "cntlz,popcnt,trap")
+ (eq_attr "cpu" "future"))
+ "DU_any_future,VSU_future")
+; 6 cycle CR latency
+(define_bypass 6 "future-alu2"
+ "future-crlogical,future-mfcr,future-mfcrf")
+
+(define_insn_reservation "future-cmp" 2
+ (and (eq_attr "type" "cmp")
+ (eq_attr "cpu" "future"))
+ "DU_any_future,VSU_future")
+
+
+; Treat 'two' and 'three' types as 2 or 3 way cracked
+(define_insn_reservation "future-two" 4
+ (and (eq_attr "type" "two")
+ (eq_attr "cpu" "future"))
+ "DU_C2_future,VSU_future")
+
+(define_insn_reservation "future-three" 6
+ (and (eq_attr "type" "three")
+ (eq_attr "cpu" "future"))
+ "DU_C3_future,VSU_future")
+
+(define_insn_reservation "future-mul" 5
+ (and (eq_attr "type" "mul")
+ (eq_attr "dot" "no")
+ (eq_attr "cpu" "future"))
+ "DU_slice_3_future,VSU_future")
+
+(define_insn_reservation "future-mul-compare" 5
+ (and (eq_attr "type" "mul")
+ (eq_attr "dot" "yes")
+ (eq_attr "cpu" "future"))
+ "DU_C2_3_future,VSU_future")
+; 10 cycle CR latency
+(define_bypass 10 "future-mul-compare"
+ "future-crlogical,future-mfcr,future-mfcrf")
+
+; Fixed point divides reserve the divide units for a minimum of 8 cycles
+(define_insn_reservation "future-idiv" 16
+ (and (eq_attr "type" "div")
+ (eq_attr "size" "32")
+ (eq_attr "cpu" "future"))
+ "DU_even_future,fx_div0_future*8|fx_div1_future*8")
+
+(define_insn_reservation "future-ldiv" 24
+ (and (eq_attr "type" "div")
+ (eq_attr "size" "64")
+ (eq_attr "cpu" "future"))
+ "DU_even_future,fx_div0_future*8|fx_div1_future*8")
+
+(define_insn_reservation "future-crlogical" 2
+ (and (eq_attr "type" "cr_logical")
+ (eq_attr "cpu" "future"))
+ "DU_any_future,VSU_future")
+
+(define_insn_reservation "future-mfcrf" 2
+ (and (eq_attr "type" "mfcrf")
+ (eq_attr "cpu" "future"))
+ "DU_any_future,VSU_future")
+
+(define_insn_reservation "future-mfcr" 6
+ (and (eq_attr "type" "mfcr")
+ (eq_attr "cpu" "future"))
+ "DU_C3_future,VSU_future")
+
+; Should differentiate between 1 cr field and > 1 since target of > 1 cr
+; is cracked
+(define_insn_reservation "future-mtcr" 2
+ (and (eq_attr "type" "mtcr")
+ (eq_attr "cpu" "future"))
+ "DU_any_future,VSU_future")
+
+; Move to LR/CTR are executed in VSU
+(define_insn_reservation "future-mtjmpr" 5
+ (and (eq_attr "type" "mtjmpr")
+ (eq_attr "cpu" "future"))
+ "DU_any_future,VSU_future")
+
+; Floating point/Vector ops
+(define_insn_reservation "future-fpsimple" 2
+ (and (eq_attr "type" "fpsimple")
+ (eq_attr "cpu" "future"))
+ "DU_slice_3_future,VSU_future")
+
+(define_insn_reservation "future-fp" 5
+ (and (eq_attr "type" "fp,dmul")
+ (eq_attr "cpu" "future"))
+ "DU_slice_3_future,VSU_future")
+
+(define_insn_reservation "future-fpcompare" 3
+ (and (eq_attr "type" "fpcompare")
+ (eq_attr "cpu" "future"))
+ "DU_slice_3_future,VSU_future")
+
+; FP div/sqrt are executed in the VSU slices. They are not pipelined wrt other
+; div/sqrt insns, but for the most part do not block pipelined ops.
+(define_insn_reservation "future-sdiv" 22
+ (and (eq_attr "type" "sdiv")
+ (eq_attr "cpu" "future"))
+ "DU_slice_3_future,VSU_future,FP_DIV_future")
+
+(define_insn_reservation "future-ddiv" 27
+ (and (eq_attr "type" "ddiv")
+ (eq_attr "cpu" "future"))
+ "DU_slice_3_future,VSU_future,FP_DIV_future")
+
+(define_insn_reservation "future-sqrt" 26
+ (and (eq_attr "type" "ssqrt")
+ (eq_attr "cpu" "future"))
+ "DU_slice_3_future,VSU_future,FP_DIV_future")
+
+(define_insn_reservation "future-dsqrt" 36
+ (and (eq_attr "type" "dsqrt")
+ (eq_attr "cpu" "future"))
+ "DU_slice_3_future,VSU_future,FP_DIV_future")
+
+(define_insn_reservation "future-vec-2cyc" 2
+ (and (eq_attr "type" "vecmove,veclogical,vecexts,veccmpfx")
+ (eq_attr "cpu" "future"))
+ "DU_super_future,VSU_super_future")
+
+(define_insn_reservation "future-veccmp" 3
+ (and (eq_attr "type" "veccmp")
+ (eq_attr "cpu" "future"))
+ "DU_super_future,VSU_super_future")
+
+(define_insn_reservation "future-vecsimple" 3
+ (and (eq_attr "type" "vecsimple")
+ (eq_attr "cpu" "future"))
+ "DU_super_future,VSU_super_future")
+
+(define_insn_reservation "future-vecnormal" 7
+ (and (eq_attr "type" "vecfloat,vecdouble")
+ (eq_attr "size" "!128")
+ (eq_attr "cpu" "future"))
+ "DU_super_future,VSU_super_future")
+
+; Quad-precision FP ops, execute in DFU
+(define_insn_reservation "future-qp" 12
+ (and (eq_attr "type" "vecfloat,vecdouble")
+ (eq_attr "size" "128")
+ (eq_attr "cpu" "future"))
+ "DU_super_future,dfu_future")
+
+(define_insn_reservation "future-vecperm" 3
+ (and (eq_attr "type" "vecperm")
+ (eq_attr "cpu" "future"))
+ "DU_super_future,VSU_PRM_future")
+
+(define_insn_reservation "future-veccomplex" 7
+ (and (eq_attr "type" "veccomplex")
+ (eq_attr "cpu" "future"))
+ "DU_super_future,VSU_super_future")
+
+(define_insn_reservation "future-vecfdiv" 24
+ (and (eq_attr "type" "vecfdiv")
+ (eq_attr "cpu" "future"))
+ "DU_super_future,VSU_super_future,VEC_DIV_future")
+
+(define_insn_reservation "future-vecdiv" 27
+ (and (eq_attr "type" "vecdiv")
+ (eq_attr "size" "!128")
+ (eq_attr "cpu" "future"))
+ "DU_super_future,VSU_super_future,VEC_DIV_future")
+
+; Use 8 for DFU reservation on QP div/mul to limit DFA state size
+(define_insn_reservation "future-qpdiv" 56
+ (and (eq_attr "type" "vecdiv")
+ (eq_attr "size" "128")
+ (eq_attr "cpu" "future"))
+ "DU_super_future,dfu_future*8")
+
+(define_insn_reservation "future-qpmul" 24
+ (and (eq_attr "type" "qmul")
+ (eq_attr "size" "128")
+ (eq_attr "cpu" "future"))
+ "DU_super_future,dfu_future*8")
+
+(define_insn_reservation "future-mffgpr" 2
+ (and (eq_attr "type" "mffgpr")
+ (eq_attr "cpu" "future"))
+ "DU_slice_3_future,VSU_future")
+
+(define_insn_reservation "future-mftgpr" 2
+ (and (eq_attr "type" "mftgpr")
+ (eq_attr "cpu" "future"))
+ "DU_slice_3_future,VSU_future")
+
+
+; Branch Unit
+; Move from LR/CTR are executed in BRU but consume a writeback port from an
+; execution slice.
+(define_insn_reservation "future-mfjmpr" 6
+ (and (eq_attr "type" "mfjmpr")
+ (eq_attr "cpu" "future"))
+ "DU_branch_future,bru_future+VSU_future")
+
+; Branch is 2 cycles
+(define_insn_reservation "future-branch" 2
+ (and (eq_attr "type" "jmpreg,branch")
+ (eq_attr "cpu" "future"))
+ "DU_branch_future,bru_future")
+
+
+; Crypto Unit
+(define_insn_reservation "future-crypto" 6
+ (and (eq_attr "type" "crypto")
+ (eq_attr "cpu" "future"))
+ "DU_super_future,cryptu_future")
+
+
+; HTM Unit
+(define_insn_reservation "future-htm" 4
+ (and (eq_attr "type" "htm")
+ (eq_attr "cpu" "future"))
+ "DU_C2_future,LSU_future")
+
+(define_insn_reservation "future-htm-simple" 2
+ (and (eq_attr "type" "htmsimple")
+ (eq_attr "cpu" "future"))
+ "DU_any_future,VSU_future")
+
+
+; DFP Unit
+(define_insn_reservation "future-dfp" 12
+ (and (eq_attr "type" "dfp")
+ (eq_attr "cpu" "future"))
+ "DU_even_future,dfu_future")
+
diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h
index 96b9787..ffceb32 100644
--- a/gcc/config/rs6000/linux.h
+++ b/gcc/config/rs6000/linux.h
@@ -59,19 +59,6 @@
} \
while (0)
-#define GNU_USER_TARGET_D_OS_VERSIONS() \
- do { \
- builtin_version ("linux"); \
- if (OPTION_GLIBC) \
- builtin_version ("CRuntime_Glibc"); \
- else if (OPTION_UCLIBC) \
- builtin_version ("CRuntime_UClibc"); \
- else if (OPTION_BIONIC) \
- builtin_version ("CRuntime_Bionic"); \
- else if (OPTION_MUSL) \
- builtin_version ("CRuntime_Musl"); \
- } while (0)
-
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux)"
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index bd19749..4d329b5 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -181,24 +181,20 @@ extern int dot_symbols;
} \
while (0)
-#undef ASM_DEFAULT_SPEC
#undef ASM_SPEC
#undef LINK_OS_LINUX_SPEC
#undef LINK_SECURE_PLT_SPEC
#ifndef RS6000_BI_ARCH
-#define ASM_DEFAULT_SPEC "-mppc64"
#define ASM_SPEC "%(asm_spec64) %(asm_spec_common)"
#define LINK_OS_LINUX_SPEC "%(link_os_linux_spec64)"
#define LINK_SECURE_PLT_SPEC ""
#else
#if DEFAULT_ARCH64_P
-#define ASM_DEFAULT_SPEC "-mppc%{!m32:64}"
#define ASM_SPEC "%{m32:%(asm_spec32)}%{!m32:%(asm_spec64)} %(asm_spec_common)"
#define LINK_OS_LINUX_SPEC "%{m32:%(link_os_linux_spec32)}%{!m32:%(link_os_linux_spec64)}"
#define LINK_SECURE_PLT_SPEC "%{m32: " LINK_SECURE_PLT_DEFAULT_SPEC "}"
#else
-#define ASM_DEFAULT_SPEC "-mppc%{m64:64}"
#define ASM_SPEC "%{!m64:%(asm_spec32)}%{m64:%(asm_spec64)} %(asm_spec_common)"
#define LINK_OS_LINUX_SPEC "%{!m64:%(link_os_linux_spec32)}%{m64:%(link_os_linux_spec64)}"
#define LINK_SECURE_PLT_SPEC "%{!m64: " LINK_SECURE_PLT_DEFAULT_SPEC "}"
@@ -376,7 +372,8 @@ extern int dot_symbols;
#define TARGET_OS_CPP_BUILTINS() \
do \
{ \
- if (strcmp (rs6000_abi_name, "linux") == 0) \
+ if (strcmp (rs6000_abi_name, "linux") == 0 \
+ || strcmp (rs6000_abi_name, "aixdesc") == 0) \
GNU_USER_TARGET_OS_CPP_BUILTINS(); \
if (TARGET_64BIT) \
{ \
@@ -400,19 +397,6 @@ extern int dot_symbols;
} \
while (0)
-#define GNU_USER_TARGET_D_OS_VERSIONS() \
- do { \
- builtin_version ("linux"); \
- if (OPTION_GLIBC) \
- builtin_version ("CRuntime_Glibc"); \
- else if (OPTION_UCLIBC) \
- builtin_version ("CRuntime_UClibc"); \
- else if (OPTION_BIONIC) \
- builtin_version ("CRuntime_Bionic"); \
- else if (OPTION_MUSL) \
- builtin_version ("CRuntime_Musl"); \
- } while (0)
-
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_linux) %(include_extra)"
diff --git a/gcc/config/rs6000/linuxaltivec.h b/gcc/config/rs6000/linuxaltivec.h
index 0f3e24f..8578f42 100644
--- a/gcc/config/rs6000/linuxaltivec.h
+++ b/gcc/config/rs6000/linuxaltivec.h
@@ -28,5 +28,8 @@
#define TARGET_DEFAULT MASK_ALTIVEC
#endif
+#undef ASM_DEFAULT_EXTRA
+#define ASM_DEFAULT_EXTRA " %{!mvsx:%{!maltivec:%{!mno-altivec:-maltivec}}}"
+
#undef SUBSUBTARGET_OVERRIDE_OPTIONS
#define SUBSUBTARGET_OVERRIDE_OPTIONS rs6000_altivec_abi = 1
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 5a2d2d3..4e77063 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -1656,7 +1656,7 @@
;; Return true if the operand is an external symbol whose address can be loaded
;; into a register using:
-;; PLA reg,label@pcrel@got
+;; PLD reg,label@pcrel@got
;;
;; The linker will either optimize this to either a PADDI if the label is
;; defined locally in another module or a PLD of the address if the label is
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index 7f0cdc7..bd4b19d 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -6124,7 +6124,7 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
unsigned int nargs = vec_safe_length (arglist);
enum rs6000_builtins fcode
- = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
+ = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
tree fnargs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
tree types[3], args[3];
const struct altivec_builtin_types *desc;
diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c
index 2ef8c7f..62aa4bf 100644
--- a/gcc/config/rs6000/rs6000-call.c
+++ b/gcc/config/rs6000/rs6000-call.c
@@ -4003,7 +4003,8 @@ htm_expand_builtin (tree exp, rtx target, bool * expandedp)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
bool nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
- enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+ enum rs6000_builtins fcode
+ = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
const struct builtin_description *d;
size_t i;
@@ -4472,7 +4473,8 @@ altivec_expand_dst_builtin (tree exp, rtx target ATTRIBUTE_UNUSED,
bool *expandedp)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- enum rs6000_builtins fcode = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+ enum rs6000_builtins fcode
+ = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
tree arg0, arg1, arg2;
machine_mode mode0, mode1;
rtx pat, op0, op1, op2;
@@ -4666,7 +4668,7 @@ altivec_expand_builtin (tree exp, rtx target, bool *expandedp)
rtx op0, pat;
machine_mode tmode, mode0;
enum rs6000_builtins fcode
- = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+ = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
if (rs6000_overloaded_builtin_p (fcode))
{
@@ -5325,7 +5327,7 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
tree fndecl = gimple_call_fndecl (stmt);
gcc_checking_assert (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD);
enum rs6000_builtins fn_code
- = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+ = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
tree arg0, arg1, lhs, temp;
enum tree_code bcode;
gimple *g;
@@ -6216,7 +6218,7 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
enum rs6000_builtins fcode
- = (enum rs6000_builtins)DECL_FUNCTION_CODE (fndecl);
+ = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
size_t uns_fcode = (size_t)fcode;
const struct builtin_description *d;
size_t i;
@@ -8099,20 +8101,7 @@ rs6000_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
funexp = XEXP (DECL_RTL (function), 0);
funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
-#if TARGET_MACHO
- if (MACHOPIC_INDIRECT)
- funexp = machopic_indirect_call_target (funexp);
-#endif
-
- /* gen_sibcall expects reload to convert scratch pseudo to LR so we must
- generate sibcall RTL explicitly. */
- insn = emit_call_insn (
- gen_rtx_PARALLEL (VOIDmode,
- gen_rtvec (3,
- gen_rtx_CALL (VOIDmode,
- funexp, const0_rtx),
- gen_rtx_USE (VOIDmode, const0_rtx),
- simple_return_rtx)));
+ insn = emit_call_insn (gen_sibcall (funexp, const0_rtx, const0_rtx));
SIBLING_CALL_P (insn) = 1;
emit_barrier ();
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index edd8f2b..e792116 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3489,9 +3489,6 @@ rs6000_option_override_internal (bool global_init_p)
/* Don't override by the processor default if given explicitly. */
set_masks &= ~rs6000_isa_flags_explicit;
- if (global_init_p && rs6000_dejagnu_cpu_index >= 0)
- rs6000_cpu_index = rs6000_dejagnu_cpu_index;
-
/* Process the -mcpu=<xxx> and -mtune=<xxx> argument. If the user changed
the cpu in a target attribute or pragma, but did not specify a tuning
option, use the cpu for the tuning option rather than the option specified
@@ -5338,7 +5335,7 @@ rs6000_builtin_md_vectorized_function (tree fndecl, tree type_out,
in_n = TYPE_VECTOR_SUBPARTS (type_in);
enum rs6000_builtins fn
- = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
+ = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
switch (fn)
{
case RS6000_BUILTIN_RSQRTF:
@@ -12946,7 +12943,7 @@ print_operand (FILE *file, rtx x, int code)
{
const char *name = XSTR (x, 0);
#if TARGET_MACHO
- if (darwin_picsymbol_stubs
+ if (darwin_symbol_stubs
&& MACHOPIC_INDIRECT
&& machopic_classify_symbol (x) == MACHOPIC_UNDEFINED_FUNCTION)
name = machopic_indirection_name (x, /*stub_p=*/true);
@@ -19484,7 +19481,7 @@ get_prev_label (tree function_name)
return NULL_TREE;
}
-/* Generate PIC and indirect symbol stubs. */
+/* Generate external symbol indirection stubs (PIC and non-PIC). */
void
machopic_output_stub (FILE *file, const char *symb, const char *stub)
@@ -21303,7 +21300,7 @@ rs6000_ira_change_pseudo_allocno_class (int regno ATTRIBUTE_UNUSED,
static tree
rs6000_builtin_reciprocal (tree fndecl)
{
- switch (DECL_FUNCTION_CODE (fndecl))
+ switch (DECL_MD_FUNCTION_CODE (fndecl))
{
case VSX_BUILTIN_XVSQRTDP:
if (!RS6000_RECIP_AUTO_RSQRTE_P (V2DFmode))
@@ -24526,8 +24523,9 @@ rs6000_call_darwin_1 (rtx value, rtx func_desc, rtx tlsarg,
if ((cookie_val & CALL_LONG) != 0
&& GET_CODE (func_desc) == SYMBOL_REF)
{
- /* FIXME: the longcall opt should not hang off picsymbol stubs. */
- if (darwin_picsymbol_stubs && TARGET_32BIT)
+ /* FIXME: the longcall opt should not hang off this flag, it is most
+ likely incorrect for kernel-mode code-generation. */
+ if (darwin_symbol_stubs && TARGET_32BIT)
make_island = true; /* Do nothing yet, retain the CALL_LONG flag. */
else
{
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 70e0616..9c11a3e 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -77,6 +77,20 @@
#define PPC405_ERRATUM77 0
#endif
+#ifndef SUBTARGET_DRIVER_SELF_SPECS
+# define SUBTARGET_DRIVER_SELF_SPECS ""
+#endif
+
+/* Only for use in the testsuite: -mdejagnu-cpu= simply overrides -mcpu=.
+ With older versions of Dejagnu the command line arguments you set in
+ RUNTESTFLAGS override those set in the testcases; with this option,
+ the testcase will always win. Ditto for -mdejagnu-tune=. */
+#define DRIVER_SELF_SPECS \
+ "%{mdejagnu-cpu=*: %<mcpu=* -mcpu=%*}", \
+ "%{mdejagnu-tune=*: %<mtune=* -mtune=%*}", \
+ "%{mdejagnu-*: %<mdejagnu-*}", \
+ SUBTARGET_DRIVER_SELF_SPECS
+
#if CHECKING_P
#define ASM_OPT_ANY ""
#else
@@ -157,6 +171,7 @@ ASM_OPT_ANY
#define CPP_DEFAULT_SPEC ""
#define ASM_DEFAULT_SPEC ""
+#define ASM_DEFAULT_EXTRA ""
/* This macro defines names of additional specifications to put in the specs
that can be used in various specifications like CC1_SPEC. Its definition
@@ -174,7 +189,7 @@ ASM_OPT_ANY
{ "cpp_default", CPP_DEFAULT_SPEC }, \
{ "asm_cpu", ASM_CPU_SPEC }, \
{ "asm_cpu_native", ASM_CPU_NATIVE_SPEC }, \
- { "asm_default", ASM_DEFAULT_SPEC }, \
+ { "asm_default", ASM_DEFAULT_SPEC ASM_DEFAULT_EXTRA }, \
{ "cc1_cpu", CC1_CPU_SPEC }, \
SUBTARGET_EXTRA_SPECS
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 4ef1993..9a7a1da 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -349,6 +349,7 @@
(include "power7.md")
(include "power8.md")
(include "power9.md")
+(include "future.md")
(include "cell.md")
(include "a2.md")
(include "titan.md")
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index 342a349..1b69507 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -388,13 +388,6 @@ mtune=
Target RejectNegative Joined Var(rs6000_tune_index) Init(-1) Enum(rs6000_cpu_opt_value) Save
-mtune= Schedule code for given CPU.
-; Only for use in the testsuite. This simply overrides -mcpu=. With older
-; versions of Dejagnu the command line arguments you set in RUNTESTFLAGS
-; override those set in the testcases; with this option, the testcase will
-; always win.
-mdejagnu-cpu=
-Target Undocumented RejectNegative Joined Var(rs6000_dejagnu_cpu_index) Init(-1) Enum(rs6000_cpu_opt_value) Save
-
mtraceback=
Target RejectNegative Joined Enum(rs6000_traceback_type) Var(rs6000_traceback)
-mtraceback=[full,part,no] Select type of traceback table.
diff --git a/gcc/config/rs6000/rtems.h b/gcc/config/rs6000/rtems.h
index 401077d..0c19802 100644
--- a/gcc/config/rs6000/rtems.h
+++ b/gcc/config/rs6000/rtems.h
@@ -254,9 +254,6 @@
%{mcpu=8540: %{!Dppc*: %{!Dmpc*: -Dppc8540} } } \
%{mcpu=e6500: -D__PPC_CPU_E6500__}"
-#undef ASM_DEFAULT_SPEC
-#define ASM_DEFAULT_SPEC "-mppc%{m64:64}"
-
#undef ASM_SPEC
#define ASM_SPEC "%{!m64:%(asm_spec32)}%{m64:%(asm_spec64)} %(asm_spec_common)"
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index 17fea80..4645ef3 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -39,7 +39,7 @@
/* Override rs6000.h definition. */
#undef ASM_DEFAULT_SPEC
-#define ASM_DEFAULT_SPEC "-mppc"
+#define ASM_DEFAULT_SPEC "-mppc%{m64:64}"
#define TARGET_HAS_TOC (TARGET_64BIT \
|| (TARGET_MINIMAL_TOC \
diff --git a/gcc/config/rs6000/t-darwin8 b/gcc/config/rs6000/t-darwin32-biarch
index 2f3bb32..2f3bb32 100644
--- a/gcc/config/rs6000/t-darwin8
+++ b/gcc/config/rs6000/t-darwin32-biarch
diff --git a/gcc/config/rs6000/t-darwin64 b/gcc/config/rs6000/t-darwin64-biarch
index b0a04c7..b0a04c7 100644
--- a/gcc/config/rs6000/t-darwin64
+++ b/gcc/config/rs6000/t-darwin64-biarch
diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000
index 59a1424..c2da303 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -73,6 +73,7 @@ MD_INCLUDES = $(srcdir)/config/rs6000/rs64.md \
$(srcdir)/config/rs6000/power7.md \
$(srcdir)/config/rs6000/power8.md \
$(srcdir)/config/rs6000/power9.md \
+ $(srcdir)/config/rs6000/future.md \
$(srcdir)/config/rs6000/cell.md \
$(srcdir)/config/rs6000/a2.md \
$(srcdir)/config/rs6000/predicates.md \
diff --git a/gcc/config/rs6000/vector.md b/gcc/config/rs6000/vector.md
index 70bcfe0..886cbad 100644
--- a/gcc/config/rs6000/vector.md
+++ b/gcc/config/rs6000/vector.md
@@ -1260,6 +1260,19 @@
"VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
"")
+;; Expanders for rotatert to make use of vrotl
+(define_expand "vrotr<mode>3"
+ [(set (match_operand:VEC_I 0 "vint_operand")
+ (rotatert:VEC_I (match_operand:VEC_I 1 "vint_operand")
+ (match_operand:VEC_I 2 "vint_operand")))]
+ "VECTOR_UNIT_ALTIVEC_OR_VSX_P (<MODE>mode)"
+{
+ rtx rot_count = gen_reg_rtx (<MODE>mode);
+ emit_insn (gen_neg<mode>2 (rot_count, operands[2]));
+ emit_insn (gen_vrotl<mode>3 (operands[0], operands[1], rot_count));
+ DONE;
+})
+
;; Expanders for arithmetic shift left on each vector element
(define_expand "vashl<mode>3"
[(set (match_operand:VEC_I 0 "vint_operand")
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index 0695f3b..10b8f6e 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -2616,7 +2616,7 @@ rx_expand_builtin (tree exp,
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
tree arg = call_expr_nargs (exp) >= 1 ? CALL_EXPR_ARG (exp, 0) : NULL_TREE;
rtx op = arg ? expand_normal (arg) : NULL_RTX;
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
switch (fcode)
{
diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index 4d2f8b2..fa15c05 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -585,3 +585,9 @@
return s390_valid_shift_count (op, 0);
}
)
+
+; An integer constant which can be used in a signed add with overflow
+; pattern without being reloaded.
+(define_predicate "addv_const_operand"
+ (and (match_code "const_int")
+ (match_test "INTVAL (op) >= -32768 && INTVAL (op) <= 32767")))
diff --git a/gcc/config/s390/s390-c.c b/gcc/config/s390/s390-c.c
index 97debdc..fd98a39 100644
--- a/gcc/config/s390/s390-c.c
+++ b/gcc/config/s390/s390-c.c
@@ -860,7 +860,7 @@ s390_resolve_overloaded_builtin (location_t loc,
vec<tree, va_gc> *arglist = static_cast<vec<tree, va_gc> *> (passed_arglist);
unsigned int in_args_num = vec_safe_length (arglist);
unsigned int ob_args_num = 0;
- unsigned int ob_fcode = DECL_FUNCTION_CODE (ob_fndecl);
+ unsigned int ob_fcode = DECL_MD_FUNCTION_CODE (ob_fndecl);
enum s390_overloaded_builtin_vars bindex;
unsigned int i;
int last_match_type = INT_MAX;
diff --git a/gcc/config/s390/s390-modes.def b/gcc/config/s390/s390-modes.def
index 88c8673..7b7c114 100644
--- a/gcc/config/s390/s390-modes.def
+++ b/gcc/config/s390/s390-modes.def
@@ -31,6 +31,8 @@ FLOAT_MODE (TF, 16, ieee_quad_format);
Condition Codes
+ CC0 CC1 CC2 CC3
+
Check for zero
CCZ: EQ NE NE NE
@@ -57,6 +59,10 @@ CCA: EQ LT GT Overflow
CCAP: EQ LT GT LT (AGHI, AHI)
CCAN: EQ LT GT GT (AGHI, AHI)
+Condition codes for overflow checking resulting from signed adds/subs/mults
+
+CCO: EQ EQ EQ NE (AGR, AGHI, SGR, MSC, ...)
+
Condition codes of unsigned adds and subs
CCL: EQ NE EQ NE (ALGF/R, ALG/R, AL/R/Y,
@@ -98,6 +104,13 @@ If you know whether the used constant is positive or negative you can predict
the sign of the result even in case of an overflow.
+CCO
+
+This mode is used to check whether there was an overflow condition in
+a signed add, sub, or mul operation. See (addv<mode>4, subv<mode>4,
+mulv<mode>4 patterns).
+
+
CCT, CCT1, CCT2, CCT3
If bits of an integer masked with an AND instruction are checked, the test under
@@ -204,6 +217,7 @@ CC_MODE (CCZ1);
CC_MODE (CCA);
CC_MODE (CCAP);
CC_MODE (CCAN);
+CC_MODE (CCO);
CC_MODE (CCL);
CC_MODE (CCL1);
CC_MODE (CCL2);
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 75b0b5b..74f1d25 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -770,7 +770,7 @@ s390_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
#define MAX_ARGS 6
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
enum insn_code icode;
rtx op[MAX_ARGS], pat;
int arity;
@@ -1378,6 +1378,7 @@ s390_match_ccmode_set (rtx set, machine_mode req_mode)
case E_CCSRmode:
case E_CCUmode:
case E_CCURmode:
+ case E_CCOmode:
case E_CCLmode:
case E_CCL1mode:
case E_CCL2mode:
@@ -2071,6 +2072,15 @@ s390_branch_condition_mask (rtx code)
}
break;
+ case E_CCOmode:
+ switch (GET_CODE (code))
+ {
+ case EQ: return CC0 | CC1 | CC2;
+ case NE: return CC3;
+ default: return -1;
+ }
+ break;
+
case E_CCSmode:
switch (GET_CODE (code))
{
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 94a7340..e4516f6 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -5961,6 +5961,83 @@
"agh\t%0,%2"
[(set_attr "op_type" "RXY")])
+
+; Jump to label OP3 if OP1 + OP2 results in a signed overflow
+
+; addv_const_operand accepts all constants which can be handled
+; without reloads. These will be handled primarily by
+; "*addv<mode>3_ccoverflow_const" which doesn't provide a register
+; alternative. Hence we have to match the operand exactly.
+; For immediates we have to avoid the SIGN_EXTEND around OP2.
+(define_expand "addv<mode>4"
+ [(parallel
+ [(set (reg:CCO CC_REGNUM)
+ (compare:CCO (plus:<DBL>
+ (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand"))
+ (match_dup 4))
+ (sign_extend:<DBL> (plus:GPR (match_dup 1)
+ (match_operand:GPR 2 "general_operand")))))
+ (set (match_operand:GPR 0 "nonimmediate_operand")
+ (plus:GPR (match_dup 1) (match_dup 2)))])
+ (set (pc)
+ (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
+ (label_ref (match_operand 3))
+ (pc)))]
+ ""
+{
+ if (CONSTANT_P (operands[2])
+ && !addv_const_operand (operands[2], GET_MODE (operands[2])))
+ operands[2] = force_reg (<GPR:MODE>mode, operands[2]);
+
+ if (GET_MODE (operands[2]) != VOIDmode)
+ operands[4] = gen_rtx_SIGN_EXTEND (<DBL>mode, operands[2]);
+ else
+ /* This is what CSE does when propagating a constant into the pattern. */
+ operands[4] = simplify_unary_operation (SIGN_EXTEND, <GPR:DBL>mode, operands[2], <GPR:MODE>mode);
+})
+
+; ark, agrk, ar, ahi, ahik, aghik, a, ay, agr, aghi, ag, asi, agsi
+(define_insn "*addv<mode>3_ccoverflow"
+ [(set (reg CC_REGNUM)
+ (compare (plus:<DBL>
+ (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0,d,0,0,0"))
+ (sign_extend:<DBL> (match_operand:GPR 2 "general_operand" " d,d,K,K,R,T,C")))
+ (sign_extend:<DBL> (plus:GPR (match_dup 1) (match_dup 2)))))
+ (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,d,d,d,d,S")
+ (plus:GPR (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCOmode)"
+ "@
+ a<g>r\t%0,%2
+ a<g>rk\t%0,%1,%2
+ a<g>hi\t%0,%h2
+ a<g>hik\t%0,%1,%h2
+ a<g>\t%0,%2
+ a<y>\t%0,%2
+ a<g>si\t%0,%c2"
+ [(set_attr "op_type" "RR<E>,RRF,RI,RIE,RX<Y>,RXY,SIY")
+ (set_attr "cpu_facility" "*,z196,*,z196,*,longdisp,z10")
+ (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,*,
+ z10_super_E1,z10_super_E1,z10_super_E1")])
+
+; ahi, aghi, ahik, aghik, asi, agsi
+(define_insn "*addv<mode>3_ccoverflow_const"
+ [(set (reg CC_REGNUM)
+ (compare (plus:<DBL>
+ (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "%0,d,0"))
+ (match_operand:<DBL> 2 "addv_const_operand" "K,K,C"))
+ (sign_extend:<DBL> (plus:GPR (match_dup 1) (match_dup 2)))))
+ (set (match_operand:GPR 0 "nonimmediate_operand" "=d,d,S")
+ (plus:GPR (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCOmode)"
+ "@
+ a<g>hi\t%0,%h2
+ a<g>hik\t%0,%1,%h2
+ a<g>si\t%0,%c2"
+ [(set_attr "op_type" "RI,RIE,SIY")
+ (set_attr "cpu_facility" "*,z196,z10")
+ (set_attr "z10prop" "z10_super_E1,*,z10_super_E1")])
+
+
;
; add(tf|df|sf|td|dd)3 instruction pattern(s).
;
@@ -6370,6 +6447,41 @@
"sgh\t%0,%2"
[(set_attr "op_type" "RXY")])
+; Jump to label OP3 if OP1 - OP2 results in a signed overflow
+(define_expand "subv<mode>4"
+ [(parallel
+ [(set (reg:CCO CC_REGNUM)
+ (compare:CCO (minus:<DBL>
+ (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand"))
+ (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand")))
+ (sign_extend:<DBL> (minus:GPR (match_dup 1) (match_dup 2)))))
+ (set (match_operand:GPR 0 "nonimmediate_operand")
+ (minus:GPR (match_dup 1) (match_dup 2)))])
+ (set (pc)
+ (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
+ (label_ref (match_operand 3))
+ (pc)))]
+ "")
+
+; sr, s, sy, sgr, sg, srk, sgrk
+(define_insn "*subv<mode>3_ccoverflow"
+ [(set (reg CC_REGNUM)
+ (compare (minus:<DBL>
+ (sign_extend:<DBL> (match_operand:GPR 1 "nonimmediate_operand" "0,d,0,0"))
+ (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand" "d,d,R,T")))
+ (sign_extend:<DBL> (minus:GPR (match_dup 1) (match_dup 2)))))
+ (set (match_operand:GPR 0 "register_operand" "=d,d,d,d")
+ (minus:GPR (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCOmode)"
+ "@
+ s<g>r\t%0,%2
+ s<g>rk\t%0,%1,%2
+ s<g>\t%0,%2
+ s<y>\t%0,%2"
+ [(set_attr "op_type" "RR<E>,RRF,RX<Y>,RXY")
+ (set_attr "cpu_facility" "*,z196,*,longdisp")
+ (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")])
+
;
; sub(tf|df|sf|td|dd)3 instruction pattern(s).
@@ -6888,6 +7000,38 @@
(set_attr "type" "imulsi")
(set_attr "cpu_facility" "*,*,z10")])
+; Jump to label OP3 if OP1 * OP2 results in a signed overflow
+(define_expand "mulv<mode>4"
+ [(parallel
+ [(set (reg:CCO CC_REGNUM)
+ (compare:CCO (mult:<DBL>
+ (sign_extend:<DBL> (match_operand:GPR 1 "register_operand"))
+ (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand")))
+ (sign_extend:<DBL> (mult:GPR (match_dup 1) (match_dup 2)))))
+ (set (match_operand:GPR 0 "register_operand")
+ (mult:GPR (match_dup 1) (match_dup 2)))])
+ (set (pc)
+ (if_then_else (ne (reg:CCO CC_REGNUM) (const_int 0))
+ (label_ref (match_operand 3))
+ (pc)))]
+ "TARGET_Z14")
+
+; msrkc, msc, msgrkc, msgc
+(define_insn "*mulv<mode>3_ccoverflow"
+ [(set (reg CC_REGNUM)
+ (compare (mult:<DBL>
+ (sign_extend:<DBL> (match_operand:GPR 1 "register_operand" "%d,0"))
+ (sign_extend:<DBL> (match_operand:GPR 2 "nonimmediate_operand" " d,T")))
+ (sign_extend:<DBL> (mult:GPR (match_dup 1) (match_dup 2)))))
+ (set (match_operand:GPR 0 "register_operand" "=d,d")
+ (mult:GPR (match_dup 1) (match_dup 2)))]
+ "s390_match_ccmode (insn, CCOmode) && TARGET_Z14"
+ "@
+ ms<g>rkc\t%0,%1,%2
+ ms<g>c\t%0,%2"
+ [(set_attr "op_type" "RRF,RXY")])
+
+
;
; umul instruction pattern(s).
;
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index dfaeab5..e44e46d 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -10461,7 +10461,7 @@ sh_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
machine_mode mode ATTRIBUTE_UNUSED, int ignore)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
const struct builtin_description *d = &bdesc[fcode];
enum insn_code icode = d->icode;
int signature = d->signature;
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 0227a53..a15f27f 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -11661,7 +11661,8 @@ sparc_expand_builtin (tree exp, rtx target,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- enum sparc_builtins code = (enum sparc_builtins) DECL_FUNCTION_CODE (fndecl);
+ enum sparc_builtins code
+ = (enum sparc_builtins) DECL_MD_FUNCTION_CODE (fndecl);
enum insn_code icode = sparc_builtins_icode[code];
bool nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
call_expr_arg_iterator iter;
@@ -11829,7 +11830,8 @@ static tree
sparc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED,
tree *args, bool ignore)
{
- enum sparc_builtins code = (enum sparc_builtins) DECL_FUNCTION_CODE (fndecl);
+ enum sparc_builtins code
+ = (enum sparc_builtins) DECL_MD_FUNCTION_CODE (fndecl);
tree rtype = TREE_TYPE (TREE_TYPE (fndecl));
tree arg0, arg1, arg2;
diff --git a/gcc/config/spu/spu-c.c b/gcc/config/spu/spu-c.c
index 6a52963..6312082 100644
--- a/gcc/config/spu/spu-c.c
+++ b/gcc/config/spu/spu-c.c
@@ -93,7 +93,7 @@ spu_resolve_overloaded_builtin (location_t loc, tree fndecl, void *passed_args)
|| POINTER_TYPE_P (t))
vec<tree, va_gc> *fnargs = static_cast <vec<tree, va_gc> *> (passed_args);
unsigned int nargs = vec_safe_length (fnargs);
- int new_fcode, fcode = DECL_FUNCTION_CODE (fndecl);
+ int new_fcode, fcode = DECL_MD_FUNCTION_CODE (fndecl);
struct spu_builtin_description *desc;
tree match = NULL_TREE;
diff --git a/gcc/config/spu/spu.c b/gcc/config/spu/spu.c
index 613d301..f88ad19 100644
--- a/gcc/config/spu/spu.c
+++ b/gcc/config/spu/spu.c
@@ -6591,7 +6591,7 @@ spu_expand_builtin (tree exp,
int ignore ATTRIBUTE_UNUSED)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
struct spu_builtin_description *d;
if (fcode < NUM_SPU_BUILTINS)
diff --git a/gcc/config/stormy16/stormy16.c b/gcc/config/stormy16/stormy16.c
index bd55110..aec9f2d 100644
--- a/gcc/config/stormy16/stormy16.c
+++ b/gcc/config/stormy16/stormy16.c
@@ -2326,7 +2326,7 @@ xstormy16_expand_builtin (tree exp, rtx target,
fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
argtree = TREE_OPERAND (exp, 1);
- i = DECL_FUNCTION_CODE (fndecl);
+ i = DECL_MD_FUNCTION_CODE (fndecl);
code = s16builtins[i].md_code;
for (a = 0; a < 10 && argtree; a++)
diff --git a/gcc/config/tilegx/tilegx.c b/gcc/config/tilegx/tilegx.c
index 6da9139..575780f 100644
--- a/gcc/config/tilegx/tilegx.c
+++ b/gcc/config/tilegx/tilegx.c
@@ -3531,7 +3531,7 @@ tilegx_expand_builtin (tree exp,
#define MAX_BUILTIN_ARGS 4
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
tree arg;
call_expr_arg_iterator iter;
enum insn_code icode;
diff --git a/gcc/config/tilepro/tilepro.c b/gcc/config/tilepro/tilepro.c
index f86461f..b4adfa4 100644
--- a/gcc/config/tilepro/tilepro.c
+++ b/gcc/config/tilepro/tilepro.c
@@ -3095,7 +3095,7 @@ tilepro_expand_builtin (tree exp,
#define MAX_BUILTIN_ARGS 4
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
tree arg;
call_expr_arg_iterator iter;
enum insn_code icode;
diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
index 2b97fa2..a999567 100644
--- a/gcc/config/xtensa/xtensa.c
+++ b/gcc/config/xtensa/xtensa.c
@@ -3450,7 +3450,7 @@ static tree
xtensa_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args,
bool ignore ATTRIBUTE_UNUSED)
{
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
tree arg0, arg1;
switch (fcode)
@@ -3481,7 +3481,7 @@ xtensa_expand_builtin (tree exp, rtx target,
int ignore)
{
tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
- unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
+ unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
switch (fcode)
{
diff --git a/gcc/convert.c b/gcc/convert.c
index a8f2bd0..7f0d933 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -298,92 +298,6 @@ convert_to_real_1 (tree type, tree expr, bool fold_p)
return build1 (TREE_CODE (expr), type, arg);
}
break;
- /* Convert (outertype)((innertype0)a+(innertype1)b)
- into ((newtype)a+(newtype)b) where newtype
- is the widest mode from all of these. */
- case PLUS_EXPR:
- case MINUS_EXPR:
- case MULT_EXPR:
- case RDIV_EXPR:
- {
- tree arg0 = strip_float_extensions (TREE_OPERAND (expr, 0));
- tree arg1 = strip_float_extensions (TREE_OPERAND (expr, 1));
-
- if (FLOAT_TYPE_P (TREE_TYPE (arg0))
- && FLOAT_TYPE_P (TREE_TYPE (arg1))
- && DECIMAL_FLOAT_TYPE_P (itype) == DECIMAL_FLOAT_TYPE_P (type))
- {
- tree newtype = type;
-
- if (TYPE_MODE (TREE_TYPE (arg0)) == SDmode
- || TYPE_MODE (TREE_TYPE (arg1)) == SDmode
- || TYPE_MODE (type) == SDmode)
- newtype = dfloat32_type_node;
- if (TYPE_MODE (TREE_TYPE (arg0)) == DDmode
- || TYPE_MODE (TREE_TYPE (arg1)) == DDmode
- || TYPE_MODE (type) == DDmode)
- newtype = dfloat64_type_node;
- if (TYPE_MODE (TREE_TYPE (arg0)) == TDmode
- || TYPE_MODE (TREE_TYPE (arg1)) == TDmode
- || TYPE_MODE (type) == TDmode)
- newtype = dfloat128_type_node;
- if (newtype == dfloat32_type_node
- || newtype == dfloat64_type_node
- || newtype == dfloat128_type_node)
- {
- expr = build2 (TREE_CODE (expr), newtype,
- convert_to_real_1 (newtype, arg0,
- fold_p),
- convert_to_real_1 (newtype, arg1,
- fold_p));
- if (newtype == type)
- return expr;
- break;
- }
-
- if (TYPE_PRECISION (TREE_TYPE (arg0)) > TYPE_PRECISION (newtype))
- newtype = TREE_TYPE (arg0);
- if (TYPE_PRECISION (TREE_TYPE (arg1)) > TYPE_PRECISION (newtype))
- newtype = TREE_TYPE (arg1);
- /* Sometimes this transformation is safe (cannot
- change results through affecting double rounding
- cases) and sometimes it is not. If NEWTYPE is
- wider than TYPE, e.g. (float)((long double)double
- + (long double)double) converted to
- (float)(double + double), the transformation is
- unsafe regardless of the details of the types
- involved; double rounding can arise if the result
- of NEWTYPE arithmetic is a NEWTYPE value half way
- between two representable TYPE values but the
- exact value is sufficiently different (in the
- right direction) for this difference to be
- visible in ITYPE arithmetic. If NEWTYPE is the
- same as TYPE, however, the transformation may be
- safe depending on the types involved: it is safe
- if the ITYPE has strictly more than twice as many
- mantissa bits as TYPE, can represent infinities
- and NaNs if the TYPE can, and has sufficient
- exponent range for the product or ratio of two
- values representable in the TYPE to be within the
- range of normal values of ITYPE. */
- if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)
- && (flag_unsafe_math_optimizations
- || (TYPE_PRECISION (newtype) == TYPE_PRECISION (type)
- && real_can_shorten_arithmetic (TYPE_MODE (itype),
- TYPE_MODE (type))
- && !excess_precision_type (newtype))))
- {
- expr = build2 (TREE_CODE (expr), newtype,
- convert_to_real_1 (newtype, arg0,
- fold_p),
- convert_to_real_1 (newtype, arg1,
- fold_p));
- if (newtype == type)
- return expr;
- }
- }
- }
- break;
default:
break;
}
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 960ff7e..0d5138f 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -643,7 +643,7 @@ coverage_begin_function (unsigned lineno_checksum, unsigned cfg_checksum)
(DECL_ASSEMBLER_NAME (current_function_decl)));
gcov_write_unsigned (DECL_ARTIFICIAL (current_function_decl)
&& !DECL_FUNCTION_VERSIONED (current_function_decl)
- && !DECL_LAMBDA_FUNCTION (current_function_decl));
+ && !DECL_LAMBDA_FUNCTION_P (current_function_decl));
gcov_write_filename (xloc.file);
gcov_write_unsigned (xloc.line);
gcov_write_unsigned (xloc.column);
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d645cde..c40bc9c 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,340 @@
+2019-08-19 Marek Polacek <polacek@redhat.com>
+
+ PR c++/91264 - detect modifying const objects in constexpr.
+ * constexpr.c (modifying_const_object_error): New function.
+ (cxx_eval_call_expression): Set TREE_READONLY on a CONSTRUCTOR of
+ a const-qualified object after it's been fully constructed.
+ (modifying_const_object_p): New function.
+ (cxx_eval_store_expression): Detect modifying a const object
+ during constant expression evaluation.
+ (cxx_eval_increment_expression): Use a better location when building
+ up the store.
+ (cxx_eval_constant_expression) <case DECL_EXPR>: Mark a constant
+ object's constructor TREE_READONLY.
+
+2019-08-15 Jason Merrill <jason@redhat.com>
+
+ PR c++/90393 - ICE with thow in ?:
+
+ PR c++/64372, DR 1560 - Gratuitous lvalue-to-rvalue conversion in ?:
+ * tree.c (lvalue_kind): Handle throw in one arm.
+ * typeck.c (rationalize_conditional_expr): Likewise.
+ (cp_build_modify_expr): Likewise.
+
+2019-08-14 Jason Merrill <jason@redhat.com>
+
+ Implement P0848R3, Conditionally Trivial Special Member Functions.
+ * tree.c (special_memfn_p): New.
+ * class.c (add_method): When overloading, hide ineligible special
+ member fns.
+ (check_methods): Set TYPE_HAS_COMPLEX_* here.
+ * decl.c (grok_special_member_properties): Not here.
+ * name-lookup.c (push_class_level_binding_1): Move overloaded
+ functions case down, accept FUNCTION_DECL as target_decl.
+
+2019-08-14 Jonathan Wakely <jwakely@redhat.com>
+
+ PR c++/91436
+ * name-lookup.c (get_std_name_hint): Fix min_dialect field for
+ complex_literals and make_unique entries.
+
+2019-08-14 Jakub Jelinek <jakub@redhat.com>
+ Marek Polacek <polacek@redhat.com>
+
+ PR c++/91391 - bogus -Wcomma-subscript warning.
+ * parser.c (cp_parser_postfix_open_square_expression): Don't warn about
+ a deprecated comma here. Pass warn_comma_subscript down to
+ cp_parser_expression.
+ (cp_parser_expression): New bool parameter. Warn about uses of a comma
+ operator within a subscripting expression.
+ (cp_parser_skip_to_closing_square_bracket): Revert to pre-r274121 state.
+ (cp_parser_skip_to_closing_square_bracket_1): Remove.
+
+2019-08-14 Jonathan Wakely <jwakely@redhat.com>
+
+ * name-lookup.c (get_std_name_hint): Add more entries.
+
+2019-08-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl2.c (grok_array_decl): Use the location of the open square
+ bracket in error message about invalid types.
+
+2019-08-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (grokdeclarator): Check here for typedef a function
+ definition or a member function definition.
+ (start_function): Adjust.
+ (grokmethod): Likewise.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR middle-end/91421
+ * decl.c (duplicate_decls): Use copy_decl_built_in_function.
+ * pt.c (declare_integer_pack): Use set_decl_built_in_function.
+
+2019-08-13 Marek Polacek <polacek@redhat.com>
+
+ PR c++/90473 - wrong code with nullptr in default argument.
+ * call.c (null_ptr_cst_p): Update quote from the standard.
+ * decl.c (check_default_argument): Don't return nullptr when the arg
+ has side-effects.
+
+2019-08-13 Marek Polacek <polacek@redhat.com>
+
+ * cp-tree.h (DECL_MUTABLE_P): Use FIELD_DECL_CHECK.
+
+2019-08-10 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_parser_omp_clause_name): Parse device_type.
+ (cp_parser_omp_clause_device_type): New function.
+ (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_DEVICE_TYPE.
+ (OMP_DECLARE_TARGET_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_DEVICE_TYPE.
+ (cp_parser_omp_declare_target): Handle device_type clauses. Remove
+ diagnostics for declare target with clauses nested in clause-less
+ declare target declaration-definition-seq.
+ * semantics.c (finish_omp_clauses): Handle OMP_CLAUSE_DEVICE_TYPE.
+
+2019-08-09 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (check_no_duplicate_clause): Simplify using
+ omp_find_clause.
+ (cp_parser_omp_clause_if): Fix up printing of target {enter,exit} data
+ directive name modifiers.
+
+ PR c/91401
+ * parser.c (cp_parser_omp_clause_dist_schedule): Comment out the
+ check_no_duplicate_clause call, instead emit a warning for duplicate
+ dist_schedule clauses.
+
+2019-08-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (grokdeclarator): Use id_loc and EXPR_LOCATION in
+ a few error messages.
+
+2019-08-08 Marek Polacek <polacek@redhat.com>
+
+ PR c++/87519 - bogus warning with -Wsign-conversion.
+ * typeck.c (cp_build_binary_op): Use same_type_p instead of comparing
+ the types directly.
+
+ * constexpr.c (inline_asm_in_constexpr_error): New.
+ (cxx_eval_constant_expression) <case ASM_EXPR>: Call it.
+ (potential_constant_expression_1) <case ASM_EXPR>: Likewise.
+
+2019-08-08 Jakub Jelinek <jakub@redhat.com>
+
+ * semantics.c (finish_omp_clauses): For C_ORT_OMP
+ OMP_CLAUSE_USE_DEVICE_* clauses use oacc_reduction_head bitmap
+ instead of generic_head to track duplicates.
+
+2019-08-07 Marek Polacek <polacek@redhat.com>
+
+ PR c++/81429 - wrong parsing of constructor with C++11 attribute.
+ * parser.c (cp_parser_constructor_declarator_p): Handle the scenario
+ when a parameter declaration begins with [[attribute]].
+
+2019-08-07 Marek Polacek <polacek@redhat.com>
+
+ PR c++/91346 - Implement P1668R1, allow unevaluated asm in constexpr.
+ * constexpr.c (cxx_eval_constant_expression): Handle ASM_EXPR.
+ (potential_constant_expression_1) <case ASM_EXPR>: Allow.
+ * cp-tree.h (finish_asm_stmt): Adjust.
+ * parser.c (cp_parser_asm_definition): Grab the locaion of "asm" and
+ use it. Change an error to a pedwarn. Allow asm in C++2a, warn
+ otherwise.
+ * pt.c (tsubst_expr): Pass a location down to finish_asm_stmt.
+ * semantics.c (finish_asm_stmt): New location_t parameter. Use it.
+
+2019-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_parser_omp_clause_name): Parse use_device_addr clause.
+ (cp_parser_omp_all_clauses): Handle PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR.
+ (OMP_TARGET_DATA_CLAUSE_MASK): Add PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR.
+ (cp_parser_omp_target_data): Handle PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR
+ like PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR, adjust diagnostics about no
+ map or use_device_* clauses.
+ * semantics.c (finish_omp_clauses): For OMP_CLAUSE_USE_DEVICE_PTR
+ in OpenMP, require pointer or reference to pointer type rather than
+ pointer or array or reference to pointer or array type. Handle
+ OMP_CLAUSE_USE_DEVICE_ADDR.
+ * pt.c (tsubst_omp_clauses): Handle OMP_CLAUSE_USE_DEVICE_ADDR.
+
+2019-08-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/91378 - ICE with noexcept and auto return type.
+ * pt.c (maybe_instantiate_noexcept): push_to_top_level.
+
+2019-08-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (check_array_designated_initializer): Use
+ cp_expr_loc_or_input_loc in one place.
+
+2019-08-06 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_parser_omp_for_loop): For OMP_LOOP, ignore parallel
+ clauses and predetermine iterator as lastprivate.
+ * semantics.c (handle_omp_for_class_iterator): Use
+ OMP_CLAUSE_LASTPRIVATE_LOOP_IV instead of
+ OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV, set it for lastprivate also
+ on OMP_LOOP construct. If a clause is missing for class iterator
+ on OMP_LOOP, add firstprivate clause, and if there is private
+ clause, turn it into firstprivate too.
+ (finish_omp_for): Formatting fix. For OMP_LOOP, adjust
+ OMP_CLAUSE_LASTPRIVATE_LOOP_IV clause CP_CLAUSE_INFO, so that it
+ uses copy ctor instead of default ctor.
+ * cp-gimplify.c (cp_gimplify_expr): Handle OMP_LOOP like
+ OMP_DISTRIBUTE etc.
+ (cp_fold_r): Likewise.
+ (cp_genericize_r): Likewise.
+ (cxx_omp_finish_clause): Also finish lastprivate clause with
+ OMP_CLAUSE_LASTPRIVATE_LOOP_IV flag.
+ * pt.c (tsubst_omp_clauses): Handle OMP_CLAUSE_BIND.
+ (tsubst_omp_for_iterator): For OMP_LOOP, ignore parallel
+ clauses and predetermine iterator as lastprivate.
+ * constexpr.c (potential_constant_expression_1): Handle OMP_LOOP
+ like OMP_DISTRIBUTE etc.
+
+2019-08-05 Marek Polacek <polacek@redhat.com>
+
+ DR 2413 - typename in conversion-function-ids.
+ * parser.c (cp_parser_conversion_type_id): Call
+ cp_parser_type_specifier_seq with CP_PARSER_FLAGS_TYPENAME_OPTIONAL
+ instead of CP_PARSER_FLAGS_NONE.
+
+2019-08-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * cp-tree.h (cp_expr_loc_or_input_loc): New.
+ (cxx_incomplete_type_diagnostic): Use it.
+ * call.c (build_converted_constant_expr_internal, convert_like_real,
+ convert_arg_to_ellipsis, convert_for_arg_passing, build_over_call,
+ build_cxx_call, perform_implicit_conversion_flags,
+ initialize_reference): Likewise.
+ * constexpr.c (cxx_eval_internal_function, cxx_eval_call_expression,
+ eval_and_check_array_index, cxx_eval_store_expression,
+ cxx_eval_statement_list, cxx_eval_loop_expr,
+ cxx_eval_constant_expression, potential_constant_expression_1):
+ Likewise.
+ * constraint.cc (check_for_logical_overloads,
+ satisfy_predicate_constraint): Likewise.
+ * cp-gimplify.c (cp_gimplify_expr): Likewise.
+ * cvt.c (cp_convert_to_pointer, convert_to_reference,
+ cp_convert_and_check, ocp_convert, maybe_warn_nodiscard): Likewise.
+ * decl.c (pop_switch): Likewise.
+ * decl2.c (delete_sanity): Likewise.
+ * error.c (location_of): Likewise.
+ * init.c (maybe_warn_list_ctor, build_aggr_init,
+ warn_placement_new_too_small, build_new_1, build_vec_init): Likewise.
+ * lex.c (unqualified_name_lookup_error): Likewise.
+ * parser.c (cp_parser_initializer_list, cp_parser_omp_for_cond):
+ Likewise.
+ * pt.c (check_for_bare_parameter_packs, check_valid_ptrmem_cst_expr,
+ unify_arg_conversion, convert_nontype_argument,
+ tsubst_copy_and_build, resolve_typename_type): Likewise.
+ * semantics.c (maybe_convert_cond, finish_call_expr,
+ cp_build_vec_convert): Likewise.
+ * typeck.c (decay_conversion, rationalize_conditional_expr,
+ cp_build_unary_op, build_x_compound_expr_from_list,
+ maybe_warn_about_returning_address_of_local,
+ maybe_warn_pessimizing_move): Likewise.
+ * typeck2.c (check_narrowing, digest_init_r,
+ process_init_constructor_array): Likewise.
+
+2019-08-05 Tom Honermann <tom@honermann.net>
+
+ * parser.c (cp_parser_template_declaration_after_parameters): Enable
+ class template argument deduction for non-type template parameters
+ in literal operator templates.
+
+2019-08-05 Marek Polacek <polacek@redhat.com>
+
+ PR c++/91338 - Implement P1161R3: Deprecate a[b,c].
+ * parser.c (cp_parser_postfix_open_square_expression): Warn about uses
+ of a comma operator within a subscripting expression.
+ (cp_parser_skip_to_closing_square_bracket_1): New function, made out
+ of...
+ (cp_parser_skip_to_closing_square_bracket): ...this.
+
+2019-08-05 Jason Merrill <jason@redhat.com>
+
+ * semantics.c (force_paren_expr): Preserve location.
+
+2019-08-02 Marek Polacek <polacek@redhat.com>
+
+ PR c++/91230 - wrong error with __PRETTY_FUNCTION__ and generic lambda.
+ * pt.c (value_dependent_expression_p): Consider __PRETTY_FUNCTION__
+ inside a template function value-dependent.
+
+2019-08-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * tree.c (handle_nodiscard_attribute): Do not warn about nodiscard
+ applied to a constructor.
+
+2019-08-02 Martin Liska <mliska@suse.cz>
+
+ * decl.c (grok_op_properties):
+ Mark DECL_SET_IS_OPERATOR_DELETE for user-provided delete operators.
+
+2019-08-01 Martin Sebor <msebor@redhat.com>
+
+ PR c++/90947
+ * decl.c (reshape_init_array_1): Avoid truncating initializer
+ lists containing string literals.
+
+2019-08-01 Marek Polacek <polacek@redhat.com>
+
+ PR c++/90805 - detect narrowing in case values.
+ * decl.c (case_conversion): Detect narrowing in case values.
+
+2019-07-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl2.c (delete_sanity): Improve diagnostic locations, use
+ cp_expr_loc_or_loc in four places.
+
+2019-07-31 Jason Merrill <jason@redhat.com>
+
+ PR c++/90538 - multiple expansions of capture packs
+ * cp-tree.h (DECLTYPE_FOR_INIT_CAPTURE): Remove.
+ * lambda.c (add_capture): Copy parameter packs from init.
+ (lambda_capture_field_type): Always use auto for init-capture.
+ * pt.c (uses_parameter_packs): Return tree.
+ (tsubst) [DECLTYPE_TYPE]: Remove init-capture handling.
+ (gen_elem_of_pack_expansion_instantiation): Don't push
+ local_specialization_stack.
+ (prepend_one_capture): New.
+ (tsubst_lambda_expr): Use it. Don't touch local_specializations.
+ (do_auto_deduction): Avoid redundant error.
+
+ Fix copy_node of TEMPLATE_INFO.
+ * cp-tree.h (struct tree_template_info): Use tree_base instead of
+ tree_common. Add tmpl and args fields.
+ (TI_TEMPLATE, TI_ARGS): Adjust.
+
+2019-07-30 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/91270
+ * tree-ssa-dce.c (propagate_necessity): Mark 2nd argument
+ of delete operator as needed.
+
+2019-07-25 Martin Liska <mliska@suse.cz>
+ Dominik Infuhr <dominik.infuehr@theobroma-systems.com>
+
+ PR c++/23383
+ * decl.c (cxx_init_decl_processing): Mark delete operators
+ with DECL_SET_IS_OPERATOR_DELETE.
+
+2019-07-25 Martin Liska <mliska@suse.cz>
+
+ * decl.c (duplicate_decls): Use new macros
+ (e.g. DECL_SET_LAMBDA_FUNCTION and DECL_LAMBDA_FUNCTION_P).
+ (cxx_init_decl_processing): Likewise.
+ (grok_op_properties): Likewise.
+ * parser.c (cp_parser_lambda_declarator_opt): Likewise.
+
+2019-07-24 Martin Sebor <msebor@redhat.com>
+
+ PR driver/80545
+ * decl.c (finish_function): Use lang_mask.
+
2019-07-20 Jason Merrill <jason@redhat.com>
* cp-tree.h (ovl_iterator::using_p): A USING_DECL by itself was also
@@ -132,15 +469,14 @@
* cp-tree.h (cp_omp_emit_unmappable_type_notes): New prototype.
* decl.c (cp_finish_decl): Call cp_omp_emit_unmappable_type_notes.
* decl2.c (cp_omp_mappable_type): Move contents to ...
- (cp_omp_mappable_type_1): ... here and add note output.
+ (cp_omp_mappable_type_1): ... here and add note output.
(cp_omp_emit_unmappable_type_notes): New function.
* semantics.c (finish_omp_clauses): Call
cp_omp_emit_unmappable_type_notes in four places.
2019-07-03 Martin Liska <mliska@suse.cz>
- * call.c (build_new_op_1): Remove
- dead assignemts.
+ * call.c (build_new_op_1): Remove dead assignemts.
* typeck.c (cp_build_binary_op): Likewise.
2019-06-27 Jason Merrill <jason@redhat.com>
@@ -182,6 +518,15 @@
* constexpr.c (cxx_eval_array_reference): Don't look through VCE from
vector type if lval.
+2019-06-25 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * lex.c (init_reswords): Create keyword for "__intN__" type.
+ * cp-tree.h (cp_decl_specifier_seq): New bitfield "int_n_alt".
+ * decl.c (grokdeclarator): Don't pedwarn about "__intN" ISO
+ C incompatibility if alternate "__intN__" form is used.
+ * parser.c (cp_parser_simple_type_specifier): Set
+ decl_specs->int_n_alt if "__intN__" form is used.
+
2019-06-24 Jan Hubicka <jh@suse.cz>
* lex.c (cxx_make_type): Set TYPE_CXX_ODR_P.
@@ -430,7 +775,7 @@
PR c++/90449 - add -Winaccessible-base option.
* class.c (warn_about_ambiguous_bases): Changed name to:
maybe_warn_about_inaccessible_bases.
- (maybe_warn_about_inaccessible_bases): Implemented new
+ (maybe_warn_about_inaccessible_bases): Implemented new
Winaccessible-base warning option for both direct and virtual
base warnings.
(layout_class_type): Call to warn_about_ambiguous_bases changed to fit
@@ -576,7 +921,7 @@
* cp-tree.h (IDENTIFIER_LAMBDA_P): New.
(TYPE_ANON_P): New.
- (LAMBDA_TYPE_P, TYPE_UNNAMED_P): Likewise.
+ (LAMBDA_TYPE_P, TYPE_UNNAMED_P): Likewise.
(LAMBDANAME_PREFIX, LAMBDANAME_FORMAT): Delete.
(make_lambda_name): Don't declare.
* error.c (dump_aggr_type): Check for lambdas before other
@@ -758,92 +1103,92 @@
2019-05-16 Martin Sebor <msebor@redhat.com>
- * call.c (print_z_candidate): Wrap diagnostic text in a gettext
- macro. Adjust.
- (print_z_candidates): Same.
- (build_conditional_expr_1): Quote keywords, operators, and types
- in diagnostics.
- (build_op_delete_call): Same.
- (maybe_print_user_conv_context): Wrap diagnostic text in a gettext
- macro.
- (convert_like_real): Same.
- (convert_arg_to_ellipsis): Quote keywords, operators, and types
- in diagnostics.
- (build_over_call): Same.
- (joust): Break up an overlong line. Wrap diagnostic text in a gettext
- macro.
- * constexpr.c (cxx_eval_check_shift_p): Spell out >= in English.
- (cxx_eval_constant_expression): Quote keywords, operators, and types
- in diagnostics.
- (potential_constant_expression_1): Same.
- * cp-gimplify.c (cp_genericize_r): Same.
- * cvt.c (maybe_warn_nodiscard): Quote keywords, operators, and types
- in diagnostics.
- (type_promotes_to): Same.
- * decl.c (check_previous_goto_1): Same.
- (check_goto): Same.
- (start_decl): Same.
- (cp_finish_decl): Avoid parenthesizing a sentence for consistency.
- (grok_op_properties): Quote keywords, operators, and types
- in diagnostics.
- * decl2.c (grokfield): Same.
- (coerce_delete_type): Same.
- * except.c (is_admissible_throw_operand_or_catch_parameter): Same.
- * friend.c (do_friend): Quote C++ tokens.
- * init.c (build_new_1): Quote keywords, operators, and types
- in diagnostics.
- (build_vec_delete_1): Same.
- (build_delete): Same.
- * lex.c (parse_strconst_pragma): Same.
- (handle_pragma_implementation): Same.
- (unqualified_fn_lookup_error): Same.
- * mangle.c (write_type): Same.
- * method.c (defaulted_late_check): Avoid two consecutive punctuators.
- * name-lookup.c (cp_binding_level_debug): Remove a trailing newline.
- (pop_everything): Same.
- * parser.c (cp_lexer_start_debugging): Quote a macro name.
- in a diagnostic
- (cp_lexer_stop_debugging): Same.
- (cp_parser_userdef_numeric_literal): Quote a C++ header name
- in a diagnostic.
- (cp_parser_nested_name_specifier_opt): Quote keywords, operators,
- and types in diagnostics.
- (cp_parser_question_colon_clause): Same.
- (cp_parser_asm_definition): Same.
- (cp_parser_init_declarator): Same.
- (cp_parser_template_declaration_after_parameters): Avoid capitalizing
- a sentence in a diagnostic.
- (cp_parser_omp_declare_reduction): Quote keywords, operators, and types
- in diagnostics.
- (cp_parser_transaction): Same.
- * pt.c (maybe_process_partial_specialization): Replace second call
- to permerror with inform for consistency with other uses.
- (expand_integer_pack): Quote keywords, operators, and types
- in diagnostics.
- * rtti.c (get_typeid): Quote keywords, operators, and types
- in diagnostics.
- (build_dynamic_cast_1): Same.
- * semantics.c (finish_asm_stmt): Same.
- (finish_label_decl): Same.
- (finish_bases): Same.
- (finish_offsetof): Same.
- (cp_check_omp_declare_reduction): Same.
- (finish_decltype_type): Same.
- * tree.c (handle_init_priority_attribute): Same. Add detail
- to diagnostics.
- (maybe_warn_zero_as_null_pointer_constant): Same.
- * typeck.c (cp_build_binary_op): Quote keywords, operators, and types
- in diagnostics.
- (cp_build_unary_op): Same.
- (check_for_casting_away_constness): Same.
- (build_static_cast): Same.
- (build_const_cast_1): Same.
- (maybe_warn_about_returning_address_of_local): Same.
- (check_return_expr): Same.
- * typeck2.c (abstract_virtuals_error_sfinae): Same.
- (digest_init_r): Replace a tab with spaces in a diagnostic.
- (build_functional_cast): Quote keywords, operators, and types
- in diagnostics.
+ * call.c (print_z_candidate): Wrap diagnostic text in a gettext
+ macro. Adjust.
+ (print_z_candidates): Same.
+ (build_conditional_expr_1): Quote keywords, operators, and types
+ in diagnostics.
+ (build_op_delete_call): Same.
+ (maybe_print_user_conv_context): Wrap diagnostic text in a gettext
+ macro.
+ (convert_like_real): Same.
+ (convert_arg_to_ellipsis): Quote keywords, operators, and types
+ in diagnostics.
+ (build_over_call): Same.
+ (joust): Break up an overlong line. Wrap diagnostic text in a gettext
+ macro.
+ * constexpr.c (cxx_eval_check_shift_p): Spell out >= in English.
+ (cxx_eval_constant_expression): Quote keywords, operators, and types
+ in diagnostics.
+ (potential_constant_expression_1): Same.
+ * cp-gimplify.c (cp_genericize_r): Same.
+ * cvt.c (maybe_warn_nodiscard): Quote keywords, operators, and types
+ in diagnostics.
+ (type_promotes_to): Same.
+ * decl.c (check_previous_goto_1): Same.
+ (check_goto): Same.
+ (start_decl): Same.
+ (cp_finish_decl): Avoid parenthesizing a sentence for consistency.
+ (grok_op_properties): Quote keywords, operators, and types
+ in diagnostics.
+ * decl2.c (grokfield): Same.
+ (coerce_delete_type): Same.
+ * except.c (is_admissible_throw_operand_or_catch_parameter): Same.
+ * friend.c (do_friend): Quote C++ tokens.
+ * init.c (build_new_1): Quote keywords, operators, and types
+ in diagnostics.
+ (build_vec_delete_1): Same.
+ (build_delete): Same.
+ * lex.c (parse_strconst_pragma): Same.
+ (handle_pragma_implementation): Same.
+ (unqualified_fn_lookup_error): Same.
+ * mangle.c (write_type): Same.
+ * method.c (defaulted_late_check): Avoid two consecutive punctuators.
+ * name-lookup.c (cp_binding_level_debug): Remove a trailing newline.
+ (pop_everything): Same.
+ * parser.c (cp_lexer_start_debugging): Quote a macro name.
+ in a diagnostic
+ (cp_lexer_stop_debugging): Same.
+ (cp_parser_userdef_numeric_literal): Quote a C++ header name
+ in a diagnostic.
+ (cp_parser_nested_name_specifier_opt): Quote keywords, operators,
+ and types in diagnostics.
+ (cp_parser_question_colon_clause): Same.
+ (cp_parser_asm_definition): Same.
+ (cp_parser_init_declarator): Same.
+ (cp_parser_template_declaration_after_parameters): Avoid capitalizing
+ a sentence in a diagnostic.
+ (cp_parser_omp_declare_reduction): Quote keywords, operators, and types
+ in diagnostics.
+ (cp_parser_transaction): Same.
+ * pt.c (maybe_process_partial_specialization): Replace second call
+ to permerror with inform for consistency with other uses.
+ (expand_integer_pack): Quote keywords, operators, and types
+ in diagnostics.
+ * rtti.c (get_typeid): Quote keywords, operators, and types
+ in diagnostics.
+ (build_dynamic_cast_1): Same.
+ * semantics.c (finish_asm_stmt): Same.
+ (finish_label_decl): Same.
+ (finish_bases): Same.
+ (finish_offsetof): Same.
+ (cp_check_omp_declare_reduction): Same.
+ (finish_decltype_type): Same.
+ * tree.c (handle_init_priority_attribute): Same. Add detail
+ to diagnostics.
+ (maybe_warn_zero_as_null_pointer_constant): Same.
+ * typeck.c (cp_build_binary_op): Quote keywords, operators, and types
+ in diagnostics.
+ (cp_build_unary_op): Same.
+ (check_for_casting_away_constness): Same.
+ (build_static_cast): Same.
+ (build_const_cast_1): Same.
+ (maybe_warn_about_returning_address_of_local): Same.
+ (check_return_expr): Same.
+ * typeck2.c (abstract_virtuals_error_sfinae): Same.
+ (digest_init_r): Replace a tab with spaces in a diagnostic.
+ (build_functional_cast): Quote keywords, operators, and types
+ in diagnostics.
2019-05-15 Jakub Jelinek <jakub@redhat.com>
@@ -1248,12 +1593,12 @@
PR c++/47488
* decl.c (reshape_init_array_1): Strip trailing zero-initializers
from arrays of trivial type and known size.
- * mangle.c (write_expression): Convert braced initializer lists
- to STRING_CSTs.
+ * mangle.c (write_expression): Convert braced initializer lists
+ to STRING_CSTs.
(write_expression): Trim trailing zero-initializers from arrays
of trivial type.
- (write_template_arg_literal): Mangle strings the same as braced
- initializer lists.
+ (write_template_arg_literal): Mangle strings the same as braced
+ initializer lists.
2019-04-03 Jason Merrill <jason@redhat.com>
@@ -1933,7 +2278,7 @@
* pt.c (maybe_instantiate_noexcept): Keep error_mark_node.
* typeck2.c (merge_exception_specifiers): Handle error_mark_node.
-2019-02-19 Chung-Lin Tang <cltang@codesourcery.com>
+2019-02-19 Chung-Lin Tang <cltang@codesourcery.com>
PR c/87924
* parser.c (cp_parser_oacc_clause_wait): Add representation of wait
@@ -1987,7 +2332,7 @@
* semantics.c (finish_compound_literal): Call
instantiate_non_dependent_expr_sfinae.
-2019-02-13 Alexandre Oliva <aoliva@redhat.com>
+2019-02-13 Alexandre Oliva <aoliva@redhat.com>
PR c++/86379
* cp-tree.h (USING_DECL_SCOPE): Use result rather than type.
@@ -2058,7 +2403,7 @@
invalid_array_size_error
(build_new): Call valid_array_size_p instead of error.
-2019-02-07 Alexandre Oliva <aoliva@redhat.com>
+2019-02-07 Alexandre Oliva <aoliva@redhat.com>
PR c++/86218
* call.c (compare_ics): Deal with ck_aggr in either cs.
@@ -2087,7 +2432,7 @@
* call.c (convert_like_real) <case ck_user>: Call mark_exp_read
instead of mark_rvalue_use.
-2019-02-05 Alexandre Oliva <aoliva@redhat.com>
+2019-02-05 Alexandre Oliva <aoliva@redhat.com>
PR c++/87770
* pt.c (instantiates_primary_template_p): New.
@@ -2188,7 +2533,7 @@
PR c++/89024 - ICE with incomplete enum type.
* call.c (standard_conversion): When converting an
ARITHMETIC_TYPE_P to an incomplete type, return NULL.
-
+
2019-01-25 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/88969
@@ -2292,7 +2637,7 @@
* semantics.c (process_outer_var_ref): Only skip dependent types
in templates.
-2019-01-17 Alexandre Oliva <aoliva@redhat.com>
+2019-01-17 Alexandre Oliva <aoliva@redhat.com>
PR c++/87768
* cp-tree.h (saved_scope): Add suppress_location_wrappers.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 38d229b..01a25ad 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -529,9 +529,8 @@ null_ptr_cst_p (tree t)
/* [conv.ptr]
- A null pointer constant is an integral constant expression
- (_expr.const_) rvalue of integer type that evaluates to zero or
- an rvalue of type std::nullptr_t. */
+ A null pointer constant is an integer literal ([lex.icon]) with value
+ zero or a prvalue of type std::nullptr_t. */
if (NULLPTR_TYPE_P (type))
return true;
@@ -4184,7 +4183,7 @@ build_converted_constant_expr_internal (tree type, tree expr,
conversion *conv;
void *p;
tree t;
- location_t loc = cp_expr_loc_or_loc (expr, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (expr);
if (error_operand_p (expr))
return error_mark_node;
@@ -6961,7 +6960,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
tree totype = convs->type;
diagnostic_t diag_kind;
int flags;
- location_t loc = cp_expr_loc_or_loc (expr, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (expr);
if (convs->bad_p && !(complain & tf_error))
return error_mark_node;
@@ -7481,7 +7480,7 @@ tree
convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain)
{
tree arg_type;
- location_t loc = cp_expr_loc_or_loc (arg, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (arg);
/* [expr.call]
@@ -7789,7 +7788,7 @@ convert_for_arg_passing (tree type, tree val, tsubst_flags_t complain)
"argument of function call might be a candidate "
"for a format attribute");
}
- maybe_warn_parm_abi (type, cp_expr_loc_or_loc (val, input_location));
+ maybe_warn_parm_abi (type, cp_expr_loc_or_input_loc (val));
}
if (complain & tf_warning)
@@ -8595,7 +8594,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
tree type = TREE_TYPE (to);
tree as_base = CLASSTYPE_AS_BASE (type);
tree arg = argarray[1];
- location_t loc = cp_expr_loc_or_loc (arg, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (arg);
if (is_really_empty_class (type, /*ignore_vptr*/true))
{
@@ -9143,7 +9142,7 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
tree fndecl;
/* Remember roughly where this call is. */
- location_t loc = cp_expr_loc_or_loc (fn, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (fn);
fn = build_call_a (fn, nargs, argarray);
SET_EXPR_LOCATION (fn, loc);
@@ -11183,7 +11182,7 @@ perform_implicit_conversion_flags (tree type, tree expr,
{
conversion *conv;
void *p;
- location_t loc = cp_expr_loc_or_loc (expr, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (expr);
if (TYPE_REF_P (type))
expr = mark_lvalue_use (expr);
@@ -11532,7 +11531,7 @@ initialize_reference (tree type, tree expr,
{
conversion *conv;
void *p;
- location_t loc = cp_expr_loc_or_loc (expr, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (expr);
if (type == error_mark_node || error_operand_p (expr))
return error_mark_node;
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index b61152c..cc53b15 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -994,6 +994,9 @@ add_method (tree type, tree method, bool via_using)
tree *slot = find_member_slot (type, DECL_NAME (method));
tree current_fns = slot ? *slot : NULL_TREE;
+ /* See below. */
+ int losem = -1;
+
/* Check to see if we've already got this method. */
for (ovl_iterator iter (current_fns); iter; ++iter)
{
@@ -1070,9 +1073,48 @@ add_method (tree type, tree method, bool via_using)
if (compparms (parms1, parms2)
&& (!DECL_CONV_FN_P (fn)
|| same_type_p (TREE_TYPE (fn_type),
- TREE_TYPE (method_type)))
- && equivalently_constrained (fn, method))
+ TREE_TYPE (method_type))))
{
+ if (!equivalently_constrained (fn, method))
+ {
+ special_function_kind sfk = special_memfn_p (method);
+
+ if (sfk == sfk_none)
+ /* Non-special member functions coexist if they are not
+ equivalently constrained. */
+ continue;
+
+ /* P0848: For special member functions, deleted, unsatisfied, or
+ less constrained overloads are ineligible. We implement this
+ by removing them from CLASSTYPE_MEMBER_VEC. Destructors don't
+ use the notion of eligibility, and the selected destructor can
+ be deleted, but removing unsatisfied or less constrained
+ overloads has the same effect as overload resolution. */
+ bool dtor = (sfk == sfk_destructor);
+ if (losem == -1)
+ losem = ((!dtor && DECL_DELETED_FN (method))
+ || !constraints_satisfied_p (method));
+ bool losef = ((!dtor && DECL_DELETED_FN (fn))
+ || !constraints_satisfied_p (fn));
+ int win;
+ if (losem || losef)
+ win = losem - losef;
+ else
+ win = more_constrained (fn, method);
+ if (win > 0)
+ /* Leave FN in the method vec, discard METHOD. */
+ return false;
+ else if (win < 0)
+ {
+ /* Remove FN, add METHOD. */
+ current_fns = iter.remove_node (current_fns);
+ continue;
+ }
+ else
+ /* Let them coexist for now. */
+ continue;
+ }
+
/* If these are versions of the same function, process and
move on. */
if (TREE_CODE (fn) == FUNCTION_DECL
@@ -4468,11 +4510,6 @@ check_methods (tree t)
vec_safe_push (CLASSTYPE_PURE_VIRTUALS (t), x);
}
- /* All user-provided destructors are non-trivial.
- Constructors and assignment ops are handled in
- grok_special_member_properties. */
- if (DECL_DESTRUCTOR_P (x) && user_provided_p (x))
- TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = 1;
if (!DECL_VIRTUAL_P (x)
&& lookup_attribute ("transaction_safe_dynamic",
DECL_ATTRIBUTES (x)))
@@ -4480,6 +4517,51 @@ check_methods (tree t)
"%<transaction_safe_dynamic%> may only be specified for "
"a virtual function");
}
+
+ /* Check whether the eligible special member functions (P0848) are
+ user-provided. add_method arranged that the CLASSTYPE_MEMBER_VEC only
+ has the eligible ones; TYPE_FIELDS also contains ineligible overloads,
+ which is why this needs to be separate from the loop above. */
+
+ if (tree dtor = CLASSTYPE_DESTRUCTOR (t))
+ {
+ if (TREE_CODE (dtor) == OVERLOAD)
+ {
+ /* P0848: At the end of the definition of a class, overload
+ resolution is performed among the prospective destructors declared
+ in that class with an empty argument list to select the destructor
+ for the class, also known as the selected destructor. The program
+ is ill-formed if overload resolution fails. */
+ auto_diagnostic_group d;
+ error_at (location_of (t), "destructor for %qT is ambiguous", t);
+ print_candidates (dtor);
+ }
+ else if (user_provided_p (dtor))
+ TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = true;
+ }
+
+ for (ovl_iterator i (CLASSTYPE_CONSTRUCTORS (t)); i; ++i)
+ {
+ tree fn = *i;
+ if (!user_provided_p (fn))
+ /* Might be trivial. */;
+ else if (copy_fn_p (fn))
+ TYPE_HAS_COMPLEX_COPY_CTOR (t) = true;
+ else if (move_fn_p (fn))
+ TYPE_HAS_COMPLEX_MOVE_CTOR (t) = true;
+ }
+
+ for (ovl_iterator i (get_class_binding_direct (t, assign_op_identifier));
+ i; ++i)
+ {
+ tree fn = *i;
+ if (!user_provided_p (fn))
+ /* Might be trivial. */;
+ else if (copy_fn_p (fn))
+ TYPE_HAS_COMPLEX_COPY_ASSIGN (t) = true;
+ else if (move_fn_p (fn))
+ TYPE_HAS_COMPLEX_MOVE_ASSIGN (t) = true;
+ }
}
/* FN is a constructor or destructor. Clone the declaration to create
@@ -4950,7 +5032,7 @@ set_method_tm_attributes (tree t)
/* Returns true if FN is a default constructor. */
bool
-default_ctor_p (tree fn)
+default_ctor_p (const_tree fn)
{
return (DECL_CONSTRUCTOR_P (fn)
&& sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (fn)));
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index c1b8b9b..dbd0dc3 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1527,7 +1527,7 @@ cxx_eval_internal_function (const constexpr_ctx *ctx, tree t,
default:
if (!ctx->quiet)
- error_at (cp_expr_loc_or_loc (t, input_location),
+ error_at (cp_expr_loc_or_input_loc (t),
"call to internal function %qE", t);
*non_constant_p = true;
return t;
@@ -1542,7 +1542,7 @@ cxx_eval_internal_function (const constexpr_ctx *ctx, tree t,
if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
{
- location_t loc = cp_expr_loc_or_loc (t, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (t);
tree type = TREE_TYPE (TREE_TYPE (t));
tree result = fold_binary_loc (loc, opcode, type,
fold_convert_loc (loc, type, arg0),
@@ -1575,6 +1575,19 @@ clear_no_implicit_zero (tree ctor)
}
}
+/* Complain about a const object OBJ being modified in a constant expression.
+ EXPR is the MODIFY_EXPR expression performing the modification. */
+
+static void
+modifying_const_object_error (tree expr, tree obj)
+{
+ location_t loc = cp_expr_loc_or_input_loc (expr);
+ auto_diagnostic_group d;
+ error_at (loc, "modifying a const object %qE is not allowed in "
+ "a constant expression", TREE_OPERAND (expr, 0));
+ inform (location_of (obj), "originally declared %<const%> here");
+}
+
/* Subroutine of cxx_eval_constant_expression.
Evaluate the call expression tree T in the context of OLD_CALL expression
evaluation. */
@@ -1584,7 +1597,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
bool lval,
bool *non_constant_p, bool *overflow_p)
{
- location_t loc = cp_expr_loc_or_loc (t, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (t);
tree fun = get_function_named_in_call (t);
constexpr_call new_call
= { NULL, NULL, NULL, 0, ctx->manifestly_const_eval };
@@ -1775,6 +1788,19 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
depth_ok = push_cx_call_context (t);
+ /* Remember the object we are constructing. */
+ tree new_obj = NULL_TREE;
+ if (DECL_CONSTRUCTOR_P (fun))
+ {
+ /* In a constructor, it should be the first `this' argument.
+ At this point it has already been evaluated in the call
+ to cxx_bind_parameters_in_call. */
+ new_obj = TREE_VEC_ELT (new_call.bindings, 0);
+ STRIP_NOPS (new_obj);
+ if (TREE_CODE (new_obj) == ADDR_EXPR)
+ new_obj = TREE_OPERAND (new_obj, 0);
+ }
+
tree result = NULL_TREE;
constexpr_call *entry = NULL;
@@ -1910,6 +1936,23 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
}
}
+ /* At this point, the object's constructor will have run, so
+ the object is no longer under construction, and its possible
+ 'const' semantics now apply. Make a note of this fact by
+ marking the CONSTRUCTOR TREE_READONLY. */
+ if (new_obj
+ && CLASS_TYPE_P (TREE_TYPE (new_obj))
+ && CP_TYPE_CONST_P (TREE_TYPE (new_obj)))
+ {
+ /* Subobjects might not be stored in ctx->values but we can
+ get its CONSTRUCTOR by evaluating *this. */
+ tree e = cxx_eval_constant_expression (ctx, new_obj,
+ /*lval*/false,
+ non_constant_p,
+ overflow_p);
+ TREE_READONLY (e) = true;
+ }
+
/* Forget the saved values of the callee's SAVE_EXPRs. */
unsigned int i;
tree save_expr;
@@ -2580,7 +2623,7 @@ eval_and_check_array_index (const constexpr_ctx *ctx,
tree t, bool allow_one_past,
bool *non_constant_p, bool *overflow_p)
{
- location_t loc = cp_expr_loc_or_loc (t, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (t);
tree ary = TREE_OPERAND (t, 0);
t = TREE_OPERAND (t, 1);
tree index = cxx_eval_constant_expression (ctx, t, false,
@@ -3724,6 +3767,26 @@ maybe_simplify_trivial_copy (tree &target, tree &init)
}
}
+/* Return true if we are modifying something that is const during constant
+ expression evaluation. CODE is the code of the statement, OBJ is the
+ object in question, MUTABLE_P is true if one of the subobjects were
+ declared mutable. */
+
+static bool
+modifying_const_object_p (tree_code code, tree obj, bool mutable_p)
+{
+ /* If this is initialization, there's no problem. */
+ if (code != MODIFY_EXPR)
+ return false;
+
+ /* [basic.type.qualifier] "A const object is an object of type
+ const T or a non-mutable subobject of a const object." */
+ if (mutable_p)
+ return false;
+
+ return (TREE_READONLY (obj) || CP_TYPE_CONST_P (TREE_TYPE (obj)));
+}
+
/* Evaluate an INIT_EXPR or MODIFY_EXPR. */
static tree
@@ -3773,6 +3836,9 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
/* Find the underlying variable. */
releasing_vec refs;
tree object = NULL_TREE;
+ /* If we're modifying a const object, save it. */
+ tree const_object_being_modified = NULL_TREE;
+ bool mutable_p = false;
for (tree probe = target; object == NULL_TREE; )
{
switch (TREE_CODE (probe))
@@ -3783,6 +3849,12 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
{
tree ob = TREE_OPERAND (probe, 0);
tree elt = TREE_OPERAND (probe, 1);
+ if (DECL_P (elt) && DECL_MUTABLE_P (elt))
+ mutable_p = true;
+ if (evaluated
+ && modifying_const_object_p (TREE_CODE (t), probe, mutable_p)
+ && const_object_being_modified == NULL_TREE)
+ const_object_being_modified = probe;
if (TREE_CODE (probe) == ARRAY_REF)
{
elt = eval_and_check_array_index (ctx, probe, false,
@@ -3811,6 +3883,10 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
}
}
+ if (modifying_const_object_p (TREE_CODE (t), object, mutable_p)
+ && const_object_being_modified == NULL_TREE)
+ const_object_being_modified = object;
+
/* And then find/build up our initializer for the path to the subobject
we're initializing. */
tree *valp;
@@ -3909,7 +3985,7 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
if (cxx_dialect < cxx2a)
{
if (!ctx->quiet)
- error_at (cp_expr_loc_or_loc (t, input_location),
+ error_at (cp_expr_loc_or_input_loc (t),
"change of the active member of a union "
"from %qD to %qD",
CONSTRUCTOR_ELT (*valp, 0)->index,
@@ -3950,6 +4026,62 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
valp = &cep->value;
}
+ /* Detect modifying a constant object in constexpr evaluation.
+ We have found a const object that is being modified. Figure out
+ if we need to issue an error. Consider
+
+ struct A {
+ int n;
+ constexpr A() : n(1) { n = 2; } // #1
+ };
+ struct B {
+ const A a;
+ constexpr B() { a.n = 3; } // #2
+ };
+ constexpr B b{};
+
+ #1 is OK, since we're modifying an object under construction, but
+ #2 is wrong, since "a" is const and has been fully constructed.
+ To track it, we use the TREE_READONLY bit in the object's CONSTRUCTOR
+ which means that the object is read-only. For the example above, the
+ *ctors stack at the point of #2 will look like:
+
+ ctors[0] = {.a={.n=2}} TREE_READONLY = 0
+ ctors[1] = {.n=2} TREE_READONLY = 1
+
+ and we're modifying "b.a", so we search the stack and see if the
+ constructor for "b.a" has already run. */
+ if (const_object_being_modified)
+ {
+ bool fail = false;
+ if (!CLASS_TYPE_P (TREE_TYPE (const_object_being_modified)))
+ fail = true;
+ else
+ {
+ /* [class.ctor]p5 "A constructor can be invoked for a const,
+ volatile, or const volatile object. const and volatile
+ semantics are not applied on an object under construction.
+ They come into effect when the constructor for the most
+ derived object ends." */
+ tree elt;
+ unsigned int i;
+ FOR_EACH_VEC_ELT (*ctors, i, elt)
+ if (same_type_ignoring_top_level_qualifiers_p
+ (TREE_TYPE (const_object_being_modified), TREE_TYPE (elt)))
+ {
+ fail = TREE_READONLY (elt);
+ break;
+ }
+ }
+ if (fail)
+ {
+ if (!ctx->quiet)
+ modifying_const_object_error (t, const_object_being_modified);
+ *non_constant_p = true;
+ return t;
+ }
+ }
+
if (!preeval)
{
/* Create a new CONSTRUCTOR in case evaluation of the initializer
@@ -4063,7 +4195,8 @@ cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
VERIFY_CONSTANT (mod);
/* Storing the modified value. */
- tree store = build2 (MODIFY_EXPR, type, op, mod);
+ tree store = build2_loc (cp_expr_loc_or_loc (t, input_location),
+ MODIFY_EXPR, type, op, mod);
cxx_eval_constant_expression (ctx, store,
true, non_constant_p, overflow_p);
ggc_free (store);
@@ -4220,7 +4353,7 @@ cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
/* We aren't communicating the jump to our caller, so give up. We don't
need to support evaluation of jumps out of statement-exprs. */
if (!ctx->quiet)
- error_at (cp_expr_loc_or_loc (r, input_location),
+ error_at (cp_expr_loc_or_input_loc (r),
"statement is not a constant expression");
*non_constant_p = true;
}
@@ -4320,7 +4453,7 @@ cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
if (++count >= constexpr_loop_limit)
{
if (!ctx->quiet)
- error_at (cp_expr_loc_or_loc (t, input_location),
+ error_at (cp_expr_loc_or_input_loc (t),
"%<constexpr%> loop iteration count exceeds limit of %d "
"(use %<-fconstexpr-loop-limit=%> to increase the limit)",
constexpr_loop_limit);
@@ -4411,6 +4544,17 @@ lookup_placeholder (const constexpr_ctx *ctx, bool lval, tree type)
return ob;
}
+/* Complain about an attempt to evaluate inline assembly. */
+
+static void
+inline_asm_in_constexpr_error (location_t loc)
+{
+ auto_diagnostic_group d;
+ error_at (loc, "inline assembly is not a constant expression");
+ inform (loc, "only unevaluated inline assembly is allowed in a "
+ "%<constexpr%> function in C++2a");
+}
+
/* Attempt to reduce the expression T to a constant value.
On failure, issue diagnostic and return error_mark_node. */
/* FIXME unify with c_fully_fold */
@@ -4482,7 +4626,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
if (++*ctx->constexpr_ops_count >= constexpr_ops_limit)
{
if (!ctx->quiet)
- error_at (cp_expr_loc_or_loc (t, input_location),
+ error_at (cp_expr_loc_or_input_loc (t),
"%<constexpr%> evaluation operation count exceeds limit of "
"%wd (use %<-fconstexpr-ops-limit=%> to increase the limit)",
constexpr_ops_limit);
@@ -4639,6 +4783,11 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
non_constant_p, overflow_p);
/* Don't share a CONSTRUCTOR that might be changed. */
init = unshare_constructor (init);
+ /* Remember that a constant object's constructor has already
+ run. */
+ if (CLASS_TYPE_P (TREE_TYPE (r))
+ && CP_TYPE_CONST_P (TREE_TYPE (r)))
+ TREE_READONLY (init) = true;
ctx->values->put (r, init);
}
else if (ctx == &new_ctx)
@@ -5036,7 +5185,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
if (REINTERPRET_CAST_P (t))
{
if (!ctx->quiet)
- error_at (cp_expr_loc_or_loc (t, input_location),
+ error_at (cp_expr_loc_or_input_loc (t),
"%<reinterpret_cast%> is not a constant expression");
*non_constant_p = true;
return t;
@@ -5077,7 +5226,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
if (TYPE_REF_P (type))
{
if (!ctx->quiet)
- error_at (cp_expr_loc_or_loc (t, input_location),
+ error_at (cp_expr_loc_or_input_loc (t),
"dereferencing a null pointer");
*non_constant_p = true;
return t;
@@ -5089,7 +5238,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
if (!can_convert (type, from, tf_none))
{
if (!ctx->quiet)
- error_at (cp_expr_loc_or_loc (t, input_location),
+ error_at (cp_expr_loc_or_input_loc (t),
"conversion of %qT null pointer to %qT "
"is not a constant expression",
from, type);
@@ -5104,7 +5253,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
reinterpret_cast<void*>(sizeof 0)
*/
if (!ctx->quiet)
- error_at (cp_expr_loc_or_loc (t, input_location),
+ error_at (cp_expr_loc_or_input_loc (t),
"%<reinterpret_cast<%T>(%E)%> is not "
"a constant expression",
type, op);
@@ -5178,7 +5327,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
case BASELINK:
case OFFSET_REF:
if (!ctx->quiet)
- error_at (cp_expr_loc_or_loc (t, input_location),
+ error_at (cp_expr_loc_or_input_loc (t),
"expression %qE is not a constant expression", t);
*non_constant_p = true;
break;
@@ -5196,7 +5345,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
|| !DECL_P (get_base_address (TREE_OPERAND (obj, 0))))
{
if (!ctx->quiet)
- error_at (cp_expr_loc_or_loc (t, input_location),
+ error_at (cp_expr_loc_or_input_loc (t),
"expression %qE is not a constant expression", t);
*non_constant_p = true;
return t;
@@ -5289,6 +5438,12 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
r = void_node;
break;
+ case ASM_EXPR:
+ if (!ctx->quiet)
+ inline_asm_in_constexpr_error (cp_expr_loc_or_input_loc (t));
+ *non_constant_p = true;
+ return t;
+
default:
if (STATEMENT_CODE_P (TREE_CODE (t)))
{
@@ -5960,7 +6115,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
return false;
if (t == NULL_TREE)
return true;
- location_t loc = cp_expr_loc_or_loc (t, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (t);
if (*jump_target)
/* If we are jumping, ignore everything. This is simpler than the
@@ -6437,6 +6592,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
case OMP_SIMD:
case OMP_DISTRIBUTE:
case OMP_TASKLOOP:
+ case OMP_LOOP:
case OMP_TEAMS:
case OMP_TARGET_DATA:
case OMP_TARGET:
@@ -6468,13 +6624,17 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
/* GCC internal stuff. */
case VA_ARG_EXPR:
case TRANSACTION_EXPR:
- case ASM_EXPR:
case AT_ENCODE_EXPR:
fail:
if (flags & tf_error)
error_at (loc, "expression %qE is not a constant expression", t);
return false;
+ case ASM_EXPR:
+ if (flags & tf_error)
+ inline_asm_in_constexpr_error (loc);
+ return false;
+
case OBJ_TYPE_REF:
if (cxx_dialect >= cxx2a)
/* In C++2a virtual calls can be constexpr, don't give up yet. */
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index cc578bb..48ecb76 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -805,7 +805,7 @@ check_for_logical_overloads (tree t)
if (DECL_OVERLOADED_OPERATOR_P (fn))
{
- location_t loc = cp_expr_loc_or_loc (t, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (t);
error_at (loc, "constraint %qE, uses overloaded operator", t);
return true;
}
@@ -2016,7 +2016,7 @@ satisfy_predicate_constraint (tree t, tree args,
tree type = cv_unqualified (TREE_TYPE (expr));
if (!same_type_p (type, boolean_type_node))
{
- error_at (cp_expr_loc_or_loc (expr, input_location),
+ error_at (cp_expr_loc_or_input_loc (expr),
"constraint %qE does not have type %qT",
expr, boolean_type_node);
return boolean_false_node;
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index bce01f5..065dcb7 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -644,7 +644,7 @@ int
cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
{
int saved_stmts_are_full_exprs_p = 0;
- location_t loc = cp_expr_loc_or_loc (*expr_p, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (*expr_p);
enum tree_code code = TREE_CODE (*expr_p);
enum gimplify_status ret;
@@ -796,6 +796,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
case OMP_FOR:
case OMP_SIMD:
case OMP_DISTRIBUTE:
+ case OMP_LOOP:
case OMP_TASKLOOP:
ret = cp_gimplify_omp_for (expr_p, pre_p);
break;
@@ -1053,7 +1054,7 @@ cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data)
code = TREE_CODE (stmt);
if (code == OMP_FOR || code == OMP_SIMD || code == OMP_DISTRIBUTE
- || code == OMP_TASKLOOP || code == OACC_LOOP)
+ || code == OMP_LOOP || code == OMP_TASKLOOP || code == OACC_LOOP)
{
tree x;
int i, n;
@@ -1544,6 +1545,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
case OMP_FOR:
case OMP_SIMD:
case OMP_DISTRIBUTE:
+ case OMP_LOOP:
case OACC_LOOP:
genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
break;
@@ -2097,7 +2099,9 @@ cxx_omp_finish_clause (tree c, gimple_seq *)
tree decl, inner_type;
bool make_shared = false;
- if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE)
+ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE
+ && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LASTPRIVATE
+ || !OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)))
return;
decl = OMP_CLAUSE_DECL (c);
@@ -2115,9 +2119,11 @@ cxx_omp_finish_clause (tree c, gimple_seq *)
/* Check for special function availability by building a call to one.
Save the results, because later we won't be in the right context
for making these queries. */
+ bool first = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE;
if (!make_shared
&& CLASS_TYPE_P (inner_type)
- && cxx_omp_create_clause_info (c, inner_type, false, true, false, true))
+ && cxx_omp_create_clause_info (c, inner_type, !first, first, !first,
+ true))
make_shared = true;
if (make_shared)
diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index 21d162e..4c95180 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -373,7 +373,6 @@ cp_common_init_ts (void)
MARK_TS_COMMON (TEMPLATE_TYPE_PARM);
MARK_TS_COMMON (TEMPLATE_PARM_INDEX);
MARK_TS_COMMON (OVERLOAD);
- MARK_TS_COMMON (TEMPLATE_INFO);
MARK_TS_COMMON (TYPENAME_TYPE);
MARK_TS_COMMON (TYPEOF_TYPE);
MARK_TS_COMMON (UNDERLYING_TYPE);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 688924c..05f9186 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -423,7 +423,6 @@ extern GTY(()) tree cp_global_trees[CPTI_MAX];
LAMBDA_EXPR_MUTABLE_P (in LAMBDA_EXPR)
DECL_FINAL_P (in FUNCTION_DECL)
QUALIFIED_NAME_IS_TEMPLATE (in SCOPE_REF)
- DECLTYPE_FOR_INIT_CAPTURE (in DECLTYPE_TYPE)
CONSTRUCTOR_IS_DEPENDENT (in CONSTRUCTOR)
TINFO_USED_TEMPLATE_ID (in TEMPLATE_INFO)
PACK_EXPANSION_SIZEOF_P (in *_PACK_EXPANSION)
@@ -1437,7 +1436,9 @@ typedef struct qualified_typedef_usage_s qualified_typedef_usage_t;
(TREE_LANG_FLAG_1 (TEMPLATE_INFO_CHECK (NODE)))
struct GTY(()) tree_template_info {
- struct tree_common common;
+ struct tree_base base;
+ tree tmpl;
+ tree args;
vec<qualified_typedef_usage_t, va_gc> *typedefs_needing_access_checking;
};
@@ -3064,9 +3065,9 @@ struct GTY(()) lang_decl {
(DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) \
|| TREE_CODE (NODE) == FIELD_DECL)
-/* Nonzero for _DECL means that this member object type
+/* Nonzero for a FIELD_DECL means that this member object type
is mutable. */
-#define DECL_MUTABLE_P(NODE) (DECL_LANG_FLAG_0 (NODE))
+#define DECL_MUTABLE_P(NODE) (DECL_LANG_FLAG_0 (FIELD_DECL_CHECK (NODE)))
/* Nonzero for _DECL means that this constructor or conversion function is
non-converting. */
@@ -3420,8 +3421,10 @@ struct GTY(()) lang_decl {
? (TYPE_LANG_SLOT_1 (NODE) = (VAL)) \
: (DECL_TEMPLATE_INFO (TYPE_NAME (NODE)) = (VAL)))
-#define TI_TEMPLATE(NODE) TREE_TYPE (TEMPLATE_INFO_CHECK (NODE))
-#define TI_ARGS(NODE) TREE_CHAIN (TEMPLATE_INFO_CHECK (NODE))
+#define TI_TEMPLATE(NODE) \
+ ((struct tree_template_info*)TEMPLATE_INFO_CHECK (NODE))->tmpl
+#define TI_ARGS(NODE) \
+ ((struct tree_template_info*)TEMPLATE_INFO_CHECK (NODE))->args
#define TI_PENDING_TEMPLATE_FLAG(NODE) \
TREE_LANG_FLAG_1 (TEMPLATE_INFO_CHECK (NODE))
/* For a given TREE_VEC containing a template argument list,
@@ -4480,12 +4483,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
(DECLTYPE_TYPE_CHECK (NODE))->type_common.string_flag
/* These flags indicate that we want different semantics from normal
- decltype: lambda capture just drops references, init capture
- uses auto semantics, lambda proxies look through implicit dereference. */
+ decltype: lambda capture just drops references,
+ lambda proxies look through implicit dereference. */
#define DECLTYPE_FOR_LAMBDA_CAPTURE(NODE) \
TREE_LANG_FLAG_0 (DECLTYPE_TYPE_CHECK (NODE))
-#define DECLTYPE_FOR_INIT_CAPTURE(NODE) \
- TREE_LANG_FLAG_1 (DECLTYPE_TYPE_CHECK (NODE))
#define DECLTYPE_FOR_LAMBDA_PROXY(NODE) \
TREE_LANG_FLAG_2 (DECLTYPE_TYPE_CHECK (NODE))
#define DECLTYPE_FOR_REF_CAPTURE(NODE) \
@@ -6312,7 +6313,7 @@ extern void determine_key_method (tree);
extern void check_for_override (tree, tree);
extern void push_class_stack (void);
extern void pop_class_stack (void);
-extern bool default_ctor_p (tree);
+extern bool default_ctor_p (const_tree);
extern bool type_has_user_nondefault_constructor (tree);
extern tree in_class_defaulted_default_constructor (tree);
extern bool user_provided_p (tree);
@@ -6790,7 +6791,7 @@ extern bool maybe_instantiate_noexcept (tree, tsubst_flags_t = tf_warning_or_er
extern tree instantiate_decl (tree, bool, bool);
extern int comp_template_parms (const_tree, const_tree);
extern bool builtin_pack_fn_p (tree);
-extern bool uses_parameter_packs (tree);
+extern tree uses_parameter_packs (tree);
extern bool template_parameter_pack_p (const_tree);
extern bool function_parameter_pack_p (const_tree);
extern bool function_parameter_expanded_from_pack_p (tree, tree);
@@ -7051,8 +7052,8 @@ enum {
extern tree begin_compound_stmt (unsigned int);
extern void finish_compound_stmt (tree);
-extern tree finish_asm_stmt (int, tree, tree, tree, tree,
- tree, bool);
+extern tree finish_asm_stmt (location_t, int, tree, tree,
+ tree, tree, tree, bool);
extern tree finish_label_stmt (tree);
extern void finish_label_decl (tree);
extern cp_expr finish_parenthesized_expr (cp_expr);
@@ -7321,6 +7322,7 @@ extern tree cp_build_qualified_type_real (tree, int, tsubst_flags_t);
extern bool cv_qualified_p (const_tree);
extern tree cv_unqualified (tree);
extern special_function_kind special_function_p (const_tree);
+extern special_function_kind special_memfn_p (const_tree);
extern int count_trees (tree);
extern int char_type_p (tree);
extern void verify_stmt_tree (tree);
@@ -7508,11 +7510,17 @@ cp_expr_loc_or_loc (const_tree t, location_t or_loc)
return loc;
}
+inline location_t
+cp_expr_loc_or_input_loc (const_tree t)
+{
+ return cp_expr_loc_or_loc (t, input_location);
+}
+
inline void
cxx_incomplete_type_diagnostic (const_tree value, const_tree type,
diagnostic_t diag_kind)
{
- cxx_incomplete_type_diagnostic (cp_expr_loc_or_loc (value, input_location),
+ cxx_incomplete_type_diagnostic (cp_expr_loc_or_input_loc (value),
value, type, diag_kind);
}
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 23d2aab..364af72 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -77,7 +77,7 @@ cp_convert_to_pointer (tree type, tree expr, bool dofold,
tree intype = TREE_TYPE (expr);
enum tree_code form;
tree rval;
- location_t loc = cp_expr_loc_or_loc (expr, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (expr);
if (intype == error_mark_node)
return error_mark_node;
@@ -419,7 +419,7 @@ convert_to_reference (tree reftype, tree expr, int convtype,
tree rval = NULL_TREE;
tree rval_as_conversion = NULL_TREE;
bool can_convert_intype_to_type;
- location_t loc = cp_expr_loc_or_loc (expr, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (expr);
if (TREE_CODE (type) == FUNCTION_TYPE
&& TREE_TYPE (expr) == unknown_type_node)
@@ -671,7 +671,7 @@ cp_convert_and_check (tree type, tree expr, tsubst_flags_t complain)
folded_result = fold_simple (folded_result);
if (!TREE_OVERFLOW_P (folded)
&& folded_result != error_mark_node)
- warnings_for_convert_and_check (cp_expr_loc_or_loc (expr, input_location),
+ warnings_for_convert_and_check (cp_expr_loc_or_input_loc (expr),
type, folded, folded_result);
}
@@ -690,7 +690,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
enum tree_code code = TREE_CODE (type);
const char *invalid_conv_diag;
tree e1;
- location_t loc = cp_expr_loc_or_loc (expr, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (expr);
bool dofold = (convtype & CONV_FOLD);
if (error_operand_p (e) || type == error_mark_node)
@@ -1013,7 +1013,7 @@ maybe_warn_nodiscard (tree expr, impl_conv_void implicit)
tree call = expr;
if (TREE_CODE (expr) == TARGET_EXPR)
call = TARGET_EXPR_INITIAL (expr);
- location_t loc = cp_expr_loc_or_loc (call, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (call);
tree callee = cp_get_callee (call);
if (!callee)
return;
@@ -1093,7 +1093,7 @@ maybe_warn_nodiscard (tree expr, impl_conv_void implicit)
tree
convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain)
{
- location_t loc = cp_expr_loc_or_loc (expr, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (expr);
if (expr == error_mark_node
|| TREE_TYPE (expr) == error_mark_node)
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index dbcf681..08b7baa 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2293,7 +2293,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (newdecl)
|= DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (olddecl);
DECL_NO_LIMIT_STACK (newdecl) |= DECL_NO_LIMIT_STACK (olddecl);
- DECL_IS_OPERATOR_NEW (newdecl) |= DECL_IS_OPERATOR_NEW (olddecl);
+ if (DECL_IS_OPERATOR_NEW_P (olddecl))
+ DECL_SET_IS_OPERATOR_NEW (newdecl, true);
DECL_LOOPING_CONST_OR_PURE_P (newdecl)
|= DECL_LOOPING_CONST_OR_PURE_P (olddecl);
@@ -2543,8 +2544,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
if (fndecl_built_in_p (olddecl)
&& (new_defines_function ? GNU_INLINE_P (newdecl) : types_match))
{
- DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
- DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
+ copy_decl_built_in_function (newdecl, olddecl);
/* If we're keeping the built-in definition, keep the rtl,
regardless of declaration matches. */
COPY_DECL_RTL (olddecl, newdecl);
@@ -3559,7 +3559,7 @@ pop_switch (void)
location_t switch_location;
/* Emit warnings as needed. */
- switch_location = cp_expr_loc_or_loc (cs->switch_stmt, input_location);
+ switch_location = cp_expr_loc_or_input_loc (cs->switch_stmt);
const bool bool_cond_p
= (SWITCH_STMT_TYPE (cs->switch_stmt)
&& TREE_CODE (SWITCH_STMT_TYPE (cs->switch_stmt)) == BOOLEAN_TYPE);
@@ -3630,16 +3630,23 @@ case_conversion (tree type, tree value)
value = mark_rvalue_use (value);
+ if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
+ type = type_promotes_to (type);
+
+ tree ovalue = value;
+ /* The constant-expression VALUE shall be a converted constant expression
+ of the adjusted type of the switch condition, which doesn't allow
+ narrowing conversions. */
+ value = build_converted_constant_expr (type, value, tf_warning_or_error);
+
if (cxx_dialect >= cxx11
&& (SCOPED_ENUM_P (type)
- || !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (value))))
- {
- if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
- type = type_promotes_to (type);
- value = (perform_implicit_conversion_flags
- (type, value, tf_warning_or_error,
- LOOKUP_IMPLICIT | LOOKUP_NO_NON_INTEGRAL));
- }
+ || !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (ovalue))))
+ /* Use the converted value. */;
+ else
+ /* The already integral case. */
+ value = ovalue;
+
return cxx_constant_value (value);
}
@@ -4358,12 +4365,14 @@ cxx_init_decl_processing (void)
deltype = build_exception_variant (deltype, empty_except_spec);
tree opnew = push_cp_library_fn (NEW_EXPR, newtype, 0);
DECL_IS_MALLOC (opnew) = 1;
- DECL_IS_OPERATOR_NEW (opnew) = 1;
+ DECL_SET_IS_OPERATOR_NEW (opnew, true);
opnew = push_cp_library_fn (VEC_NEW_EXPR, newtype, 0);
DECL_IS_MALLOC (opnew) = 1;
- DECL_IS_OPERATOR_NEW (opnew) = 1;
- push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
- push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
+ DECL_SET_IS_OPERATOR_NEW (opnew, true);
+ tree opdel = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
+ DECL_SET_IS_OPERATOR_DELETE (opdel, true);
+ opdel = push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
+ DECL_SET_IS_OPERATOR_DELETE (opdel, true);
if (flag_sized_deallocation)
{
/* Also push the sized deallocation variants:
@@ -4375,8 +4384,10 @@ cxx_init_decl_processing (void)
deltype = cp_build_type_attribute_variant (void_ftype_ptr_size,
extvisattr);
deltype = build_exception_variant (deltype, empty_except_spec);
- push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
- push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
+ opdel = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
+ DECL_SET_IS_OPERATOR_DELETE (opdel, true);
+ opdel = push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
+ DECL_SET_IS_OPERATOR_DELETE (opdel, true);
}
if (aligned_new_threshold)
@@ -4394,18 +4405,20 @@ cxx_init_decl_processing (void)
newtype = build_exception_variant (newtype, new_eh_spec);
opnew = push_cp_library_fn (NEW_EXPR, newtype, 0);
DECL_IS_MALLOC (opnew) = 1;
- DECL_IS_OPERATOR_NEW (opnew) = 1;
+ DECL_SET_IS_OPERATOR_NEW (opnew, true);
opnew = push_cp_library_fn (VEC_NEW_EXPR, newtype, 0);
DECL_IS_MALLOC (opnew) = 1;
- DECL_IS_OPERATOR_NEW (opnew) = 1;
+ DECL_SET_IS_OPERATOR_NEW (opnew, true);
/* operator delete (void *, align_val_t); */
deltype = build_function_type_list (void_type_node, ptr_type_node,
align_type_node, NULL_TREE);
deltype = cp_build_type_attribute_variant (deltype, extvisattr);
deltype = build_exception_variant (deltype, empty_except_spec);
- push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
- push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
+ opdel = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
+ DECL_SET_IS_OPERATOR_DELETE (opdel, true);
+ opdel = push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
+ DECL_SET_IS_OPERATOR_DELETE (opdel, true);
if (flag_sized_deallocation)
{
@@ -4415,8 +4428,10 @@ cxx_init_decl_processing (void)
NULL_TREE);
deltype = cp_build_type_attribute_variant (deltype, extvisattr);
deltype = build_exception_variant (deltype, empty_except_spec);
- push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
- push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
+ opdel = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
+ DECL_SET_IS_OPERATOR_DELETE (opdel, true);
+ opdel = push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
+ DECL_SET_IS_OPERATOR_DELETE (opdel, true);
}
}
@@ -5504,8 +5519,9 @@ check_array_designated_initializer (constructor_elt *ce,
sorry ("non-trivial designated initializers not supported");
}
else
- error ("C99 designator %qE is not an integral constant-expression",
- ce->index);
+ error_at (cp_expr_loc_or_input_loc (ce->index),
+ "C99 designator %qE is not an integral constant-expression",
+ ce->index);
return false;
}
@@ -5883,8 +5899,9 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
/* Pointers initialized to strings must be treated as non-zero
even if the string is empty. */
tree init_type = TREE_TYPE (elt_init);
- if ((POINTER_TYPE_P (elt_type) != POINTER_TYPE_P (init_type))
- || !initializer_zerop (elt_init))
+ if ((POINTER_TYPE_P (elt_type) != POINTER_TYPE_P (init_type)))
+ last_nonzero = index;
+ else if (!type_initializer_zero_p (elt_type, elt_init))
last_nonzero = index;
/* This can happen with an invalid initializer (c++/54501). */
@@ -10561,7 +10578,8 @@ grokdeclarator (const cp_declarator *declarator,
ctype = qualifying_scope;
if (!MAYBE_CLASS_TYPE_P (ctype))
{
- error ("%q#T is not a class or a namespace", ctype);
+ error_at (id_declarator->id_loc,
+ "%q#T is not a class or namespace", ctype);
ctype = NULL_TREE;
}
else if (innermost_code != cdk_function
@@ -10583,13 +10601,15 @@ grokdeclarator (const cp_declarator *declarator,
{
if (innermost_code != cdk_function)
{
- error ("declaration of %qD as non-function", decl);
+ error_at (EXPR_LOCATION (decl),
+ "declaration of %qE as non-function", decl);
return error_mark_node;
}
else if (!qualifying_scope
&& !(current_class_type && at_class_scope_p ()))
{
- error ("declaration of %qD as non-member", decl);
+ error_at (EXPR_LOCATION (decl),
+ "declaration of %qE as non-member", decl);
return error_mark_node;
}
@@ -12144,6 +12164,17 @@ grokdeclarator (const cp_declarator *declarator,
bool alias_p = decl_spec_seq_has_spec_p (declspecs, ds_alias);
tree decl;
+ if (funcdef_flag)
+ {
+ if (decl_context == NORMAL)
+ error_at (id_loc,
+ "typedef may not be a function definition");
+ else
+ error_at (id_loc,
+ "typedef may not be a member function definition");
+ return error_mark_node;
+ }
+
/* This declaration:
typedef void f(int) const;
@@ -12492,7 +12523,7 @@ grokdeclarator (const cp_declarator *declarator,
else if (in_namespace && !friendp)
{
/* Something like struct S { int N::j; }; */
- error ("invalid use of %<::%>");
+ error_at (id_loc, "invalid use of %<::%>");
return error_mark_node;
}
else if (FUNC_OR_METHOD_TYPE_P (type) && unqualified_id)
@@ -12547,15 +12578,15 @@ grokdeclarator (const cp_declarator *declarator,
if (!ctype)
{
gcc_assert (friendp);
- error ("expected qualified name in friend declaration "
- "for destructor %qD", uqname);
+ error_at (id_loc, "expected qualified name in friend "
+ "declaration for destructor %qD", uqname);
return error_mark_node;
}
if (!check_dtor_name (ctype, TREE_OPERAND (uqname, 0)))
{
- error ("declaration of %qD as member of %qT",
- uqname, ctype);
+ error_at (id_loc, "declaration of %qD as member of %qT",
+ uqname, ctype);
return error_mark_node;
}
if (concept_p)
@@ -13156,7 +13187,9 @@ check_default_argument (tree decl, tree arg, tsubst_flags_t complain)
/* Avoid redundant -Wzero-as-null-pointer-constant warnings at
the call sites. */
if (TYPE_PTR_OR_PTRMEM_P (decl_type)
- && null_ptr_cst_p (arg))
+ && null_ptr_cst_p (arg)
+ /* Don't lose side-effects as in PR90473. */
+ && !TREE_SIDE_EFFECTS (arg))
return nullptr_node;
/* [dcl.fct.default]
@@ -13501,15 +13534,11 @@ grok_special_member_properties (tree decl)
are no other parameters or else all other parameters have
default arguments. */
TYPE_HAS_COPY_CTOR (class_type) = 1;
- if (user_provided_p (decl))
- TYPE_HAS_COMPLEX_COPY_CTOR (class_type) = 1;
if (ctor > 1)
TYPE_HAS_CONST_COPY_CTOR (class_type) = 1;
}
else if (sufficient_parms_p (FUNCTION_FIRST_USER_PARMTYPE (decl)))
TYPE_HAS_DEFAULT_CONSTRUCTOR (class_type) = 1;
- else if (move_fn_p (decl) && user_provided_p (decl))
- TYPE_HAS_COMPLEX_MOVE_CTOR (class_type) = 1;
else if (is_list_ctor (decl))
TYPE_HAS_LIST_CTOR (class_type) = 1;
@@ -13530,13 +13559,9 @@ grok_special_member_properties (tree decl)
if (assop)
{
TYPE_HAS_COPY_ASSIGN (class_type) = 1;
- if (user_provided_p (decl))
- TYPE_HAS_COMPLEX_COPY_ASSIGN (class_type) = 1;
if (assop != 1)
TYPE_HAS_CONST_COPY_ASSIGN (class_type) = 1;
}
- else if (move_fn_p (decl) && user_provided_p (decl))
- TYPE_HAS_COMPLEX_MOVE_ASSIGN (class_type) = 1;
}
else if (IDENTIFIER_CONV_OP_P (DECL_NAME (decl)))
TYPE_HAS_CONVERSION (class_type) = true;
@@ -13661,10 +13686,13 @@ grok_op_properties (tree decl, bool complain)
}
if (op_flags & OVL_OP_FLAG_DELETE)
- coerce_delete_type (decl, loc);
+ {
+ DECL_SET_IS_OPERATOR_DELETE (decl, true);
+ coerce_delete_type (decl, loc);
+ }
else
{
- DECL_IS_OPERATOR_NEW (decl) = 1;
+ DECL_SET_IS_OPERATOR_NEW (decl, true);
TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl), loc);
}
@@ -15751,13 +15779,6 @@ start_function (cp_decl_specifier_seq *declspecs,
invoke_plugin_callbacks (PLUGIN_START_PARSE_FUNCTION, decl1);
if (decl1 == error_mark_node)
return false;
- /* If the declarator is not suitable for a function definition,
- cause a syntax error. */
- if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL)
- {
- error ("invalid function declaration");
- return false;
- }
if (DECL_MAIN_P (decl1))
/* main must return int. grokfndecl should have corrected it
@@ -16301,6 +16322,7 @@ finish_function (bool inline_p)
&& same_type_ignoring_top_level_qualifiers_p
(TREE_TYPE (valtype), TREE_TYPE (current_class_ref))
&& global_dc->option_enabled (OPT_Wreturn_type,
+ global_dc->lang_mask,
global_dc->option_state))
add_return_star_this_fixit (&richloc, fndecl);
}
@@ -16411,12 +16433,6 @@ grokmethod (cp_decl_specifier_seq *declspecs,
if (fndecl == error_mark_node)
return error_mark_node;
- if (fndecl == NULL || TREE_CODE (fndecl) != FUNCTION_DECL)
- {
- error ("invalid member function declaration");
- return error_mark_node;
- }
-
if (attrlist)
cplus_decl_attributes (&fndecl, attrlist, 0);
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 3aba194..a32108f 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -434,8 +434,8 @@ grok_array_decl (location_t loc, tree array_expr, tree index_exp,
array_expr = p2, index_exp = i1;
else
{
- error ("invalid types %<%T[%T]%> for array subscript",
- type, TREE_TYPE (index_exp));
+ error_at (loc, "invalid types %<%T[%T]%> for array subscript",
+ type, TREE_TYPE (index_exp));
return error_mark_node;
}
@@ -487,15 +487,19 @@ delete_sanity (tree exp, tree size, bool doing_vec, int use_global_delete,
}
/* An array can't have been allocated by new, so complain. */
- if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE)
- warning (0, "deleting array %q#E", exp);
+ if (TREE_CODE (TREE_TYPE (exp)) == ARRAY_TYPE
+ && (complain & tf_warning))
+ warning_at (cp_expr_loc_or_input_loc (exp), 0,
+ "deleting array %q#E", exp);
t = build_expr_type_conversion (WANT_POINTER, exp, true);
if (t == NULL_TREE || t == error_mark_node)
{
- error ("type %q#T argument given to %<delete%>, expected pointer",
- TREE_TYPE (exp));
+ if (complain & tf_error)
+ error_at (cp_expr_loc_or_input_loc (exp),
+ "type %q#T argument given to %<delete%>, expected pointer",
+ TREE_TYPE (exp));
return error_mark_node;
}
@@ -506,15 +510,19 @@ delete_sanity (tree exp, tree size, bool doing_vec, int use_global_delete,
/* You can't delete functions. */
if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)
{
- error ("cannot delete a function. Only pointer-to-objects are "
- "valid arguments to %<delete%>");
+ if (complain & tf_error)
+ error_at (cp_expr_loc_or_input_loc (exp),
+ "cannot delete a function. Only pointer-to-objects are "
+ "valid arguments to %<delete%>");
return error_mark_node;
}
/* Deleting ptr to void is undefined behavior [expr.delete/3]. */
if (VOID_TYPE_P (TREE_TYPE (type)))
{
- warning (OPT_Wdelete_incomplete, "deleting %qT is undefined", type);
+ if (complain & tf_warning)
+ warning_at (cp_expr_loc_or_input_loc (exp), OPT_Wdelete_incomplete,
+ "deleting %qT is undefined", type);
doing_vec = 0;
}
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 5943762..5620134 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -3053,7 +3053,7 @@ location_of (tree t)
return DECL_SOURCE_LOCATION (t);
if (TREE_CODE (t) == DEFERRED_PARSE)
return defparse_location (t);
- return cp_expr_loc_or_loc (t, input_location);
+ return cp_expr_loc_or_input_loc (t);
}
/* Now the interfaces from error et al to dump_type et al. Each takes an
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index d0f73ff..67e0656 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -749,7 +749,7 @@ maybe_warn_list_ctor (tree member, tree init)
if (!begin)
return;
- location_t loc = cp_expr_loc_or_loc (init, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (init);
warning_at (loc, OPT_Winit_list_lifetime,
"initializing %qD from %qE does not extend the lifetime "
"of the underlying array", member, begin);
@@ -1749,7 +1749,7 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
return error_mark_node;
location_t init_loc = (init
- ? cp_expr_loc_or_loc (init, input_location)
+ ? cp_expr_loc_or_input_loc (init)
: location_of (exp));
TREE_READONLY (exp) = 0;
@@ -2578,7 +2578,7 @@ find_flexarray_init (tree t, tree init)
static void
warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
{
- location_t loc = cp_expr_loc_or_loc (oper, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (oper);
/* The number of bytes to add to or subtract from the size of the provided
buffer based on an offset into an array or an array element reference.
@@ -2975,7 +2975,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
{
if (complain & tf_error)
{
- error_at (cp_expr_loc_or_loc (inner_nelts, input_location),
+ error_at (cp_expr_loc_or_input_loc (inner_nelts),
"array size in new-expression must be constant");
cxx_constant_value(inner_nelts);
}
@@ -3004,7 +3004,7 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
{
if (complain & tf_warning_or_error)
{
- pedwarn (cp_expr_loc_or_loc (outer_nelts, input_location), OPT_Wvla,
+ pedwarn (cp_expr_loc_or_input_loc (outer_nelts), OPT_Wvla,
typedef_variant_p (orig_type)
? G_("non-constant array new length must be specified "
"directly, not by %<typedef%>")
@@ -4140,7 +4140,7 @@ build_vec_init (tree base, tree maxindex, tree init,
tree obase = base;
bool xvalue = false;
bool errors = false;
- location_t loc = (init ? cp_expr_loc_or_loc (init, input_location)
+ location_t loc = (init ? cp_expr_loc_or_input_loc (init)
: location_of (base));
if (TREE_CODE (atype) == ARRAY_TYPE && TYPE_DOMAIN (atype))
diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c
index 758773b..c4fed16 100644
--- a/gcc/cp/lambda.c
+++ b/gcc/cp/lambda.c
@@ -213,16 +213,7 @@ lambda_capture_field_type (tree expr, bool explicit_init_p,
tree type;
bool is_this = is_this_parameter (tree_strip_nop_conversions (expr));
- if (!is_this && type_dependent_expression_p (expr))
- {
- type = cxx_make_type (DECLTYPE_TYPE);
- DECLTYPE_TYPE_EXPR (type) = expr;
- DECLTYPE_FOR_LAMBDA_CAPTURE (type) = true;
- DECLTYPE_FOR_INIT_CAPTURE (type) = explicit_init_p;
- DECLTYPE_FOR_REF_CAPTURE (type) = by_reference_p;
- SET_TYPE_STRUCTURAL_EQUALITY (type);
- }
- else if (!is_this && explicit_init_p)
+ if (!is_this && explicit_init_p)
{
tree auto_node = make_auto ();
@@ -233,6 +224,14 @@ lambda_capture_field_type (tree expr, bool explicit_init_p,
type = build_reference_type (type);
type = do_auto_deduction (type, expr, auto_node);
}
+ else if (!is_this && type_dependent_expression_p (expr))
+ {
+ type = cxx_make_type (DECLTYPE_TYPE);
+ DECLTYPE_TYPE_EXPR (type) = expr;
+ DECLTYPE_FOR_LAMBDA_CAPTURE (type) = true;
+ DECLTYPE_FOR_REF_CAPTURE (type) = by_reference_p;
+ SET_TYPE_STRUCTURAL_EQUALITY (type);
+ }
else
{
type = non_reference (unlowered_expr_type (expr));
@@ -594,7 +593,16 @@ add_capture (tree lambda, tree id, tree orig_init, bool by_reference_p,
name = get_identifier (buf);
if (variadic)
- type = make_pack_expansion (type);
+ {
+ type = make_pack_expansion (type);
+ if (explicit_init_p)
+ /* With an explicit initializer 'type' is auto, which isn't really a
+ parameter pack in this context. We will want as many fields as we
+ have elements in the expansion of the initializer, so use its packs
+ instead. */
+ PACK_EXPANSION_PARAMETER_PACKS (type)
+ = uses_parameter_packs (initializer);
+ }
/* Make member variable. */
member = build_decl (input_location, FIELD_DECL, name, type);
diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c
index 5bfb1e5..12567da 100644
--- a/gcc/cp/lex.c
+++ b/gcc/cp/lex.c
@@ -502,7 +502,7 @@ tree
unqualified_name_lookup_error (tree name, location_t loc)
{
if (loc == UNKNOWN_LOCATION)
- loc = cp_expr_loc_or_loc (name, input_location);
+ loc = cp_expr_loc_or_input_loc (name);
if (IDENTIFIER_ANY_OP_P (name))
error_at (loc, "%qD not defined", name);
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 9f27822..5f5ff81 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4504,9 +4504,6 @@ push_class_level_binding_1 (tree name, tree x)
binding->type = NULL_TREE;
}
}
- else if (TREE_CODE (target_decl) == OVERLOAD
- && OVL_P (target_bval))
- old_decl = bval;
else if (TREE_CODE (decl) == USING_DECL
&& TREE_CODE (bval) == USING_DECL
&& same_type_p (USING_DECL_SCOPE (decl),
@@ -4525,6 +4522,9 @@ push_class_level_binding_1 (tree name, tree x)
else if (TREE_CODE (bval) == USING_DECL
&& OVL_P (target_decl))
return true;
+ else if (OVL_P (target_decl)
+ && OVL_P (target_bval))
+ old_decl = bval;
if (old_decl && binding->scope == class_binding_level)
{
@@ -5550,14 +5550,16 @@ get_std_name_hint (const char *name)
{"make_any", "<any>", cxx17},
/* <array>. */
{"array", "<array>", cxx11},
+ {"to_array", "<array>", cxx2a},
/* <atomic>. */
{"atomic", "<atomic>", cxx11},
{"atomic_flag", "<atomic>", cxx11},
+ {"atomic_ref", "<atomic>", cxx2a},
/* <bitset>. */
{"bitset", "<bitset>", cxx11},
/* <complex>. */
{"complex", "<complex>", cxx98},
- {"complex_literals", "<complex>", cxx98},
+ {"complex_literals", "<complex>", cxx14},
/* <condition_variable>. */
{"condition_variable", "<condition_variable>", cxx11},
{"condition_variable_any", "<condition_variable>", cxx11},
@@ -5575,9 +5577,17 @@ get_std_name_hint (const char *name)
{"ofstream", "<fstream>", cxx98},
/* <functional>. */
{"bind", "<functional>", cxx11},
+ {"bind_front", "<functional>", cxx2a},
{"function", "<functional>", cxx11},
{"hash", "<functional>", cxx11},
+ {"invoke", "<functional>", cxx17},
{"mem_fn", "<functional>", cxx11},
+ {"not_fn", "<functional>", cxx17},
+ {"reference_wrapper", "<functional>", cxx11},
+ {"unwrap_reference", "<functional>", cxx2a},
+ {"unwrap_reference_t", "<functional>", cxx2a},
+ {"unwrap_ref_decay", "<functional>", cxx2a},
+ {"unwrap_ref_decay_t", "<functional>", cxx2a},
/* <future>. */
{"async", "<future>", cxx11},
{"future", "<future>", cxx11},
@@ -5618,11 +5628,16 @@ get_std_name_hint (const char *name)
{"map", "<map>", cxx98},
{"multimap", "<map>", cxx98},
/* <memory>. */
+ {"allocate_shared", "<memory>", cxx11},
+ {"allocator", "<memory>", cxx98},
+ {"allocator_traits", "<memory>", cxx11},
{"make_shared", "<memory>", cxx11},
- {"make_unique", "<memory>", cxx11},
+ {"make_unique", "<memory>", cxx14},
{"shared_ptr", "<memory>", cxx11},
{"unique_ptr", "<memory>", cxx11},
{"weak_ptr", "<memory>", cxx11},
+ /* <memory_resource>. */
+ {"pmr", "<memory_resource>", cxx17},
/* <mutex>. */
{"mutex", "<mutex>", cxx11},
{"timed_mutex", "<mutex>", cxx11},
@@ -5672,14 +5687,39 @@ get_std_name_hint (const char *name)
{"u16string", "<string>", cxx11},
{"u32string", "<string>", cxx11},
/* <string_view>. */
+ {"basic_string_view", "<string_view>", cxx17},
{"string_view", "<string_view>", cxx17},
/* <thread>. */
{"thread", "<thread>", cxx11},
+ {"this_thread", "<thread>", cxx11},
/* <tuple>. */
+ {"apply", "<tuple>", cxx17},
+ {"forward_as_tuple", "<tuple>", cxx11},
+ {"make_from_tuple", "<tuple>", cxx17},
{"make_tuple", "<tuple>", cxx11},
+ {"tie", "<tuple>", cxx11},
{"tuple", "<tuple>", cxx11},
+ {"tuple_cat", "<tuple>", cxx11},
{"tuple_element", "<tuple>", cxx11},
+ {"tuple_element_t", "<tuple>", cxx14},
{"tuple_size", "<tuple>", cxx11},
+ {"tuple_size_v", "<tuple>", cxx17},
+ /* <type_traits>. */
+ {"enable_if", "<type_traits>", cxx11},
+ {"enable_if_t", "<type_traits>", cxx14},
+ {"invoke_result", "<type_traits>", cxx17},
+ {"invoke_result_t", "<type_traits>", cxx17},
+ {"remove_cvref", "<type_traits>", cxx2a},
+ {"remove_cvref_t", "<type_traits>", cxx2a},
+ {"type_identity", "<type_traits>", cxx2a},
+ {"type_identity_t", "<type_traits>", cxx2a},
+ {"void_t", "<type_traits>", cxx17},
+ {"conjunction", "<type_traits>", cxx17},
+ {"conjunction_v", "<type_traits>", cxx17},
+ {"disjunction", "<type_traits>", cxx17},
+ {"disjunction_v", "<type_traits>", cxx17},
+ {"negation", "<type_traits>", cxx17},
+ {"negation_v", "<type_traits>", cxx17},
/* <unordered_map>. */
{"unordered_map", "<unordered_map>", cxx11},
{"unordered_multimap", "<unordered_map>", cxx11},
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 5c379aa..dbbfe1d 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -2102,7 +2102,7 @@ static cp_expr cp_parser_assignment_expression
static enum tree_code cp_parser_assignment_operator_opt
(cp_parser *);
static cp_expr cp_parser_expression
- (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false);
+ (cp_parser *, cp_id_kind * = NULL, bool = false, bool = false, bool = false);
static cp_expr cp_parser_constant_expression
(cp_parser *, bool = false, bool * = NULL, bool = false);
static cp_expr cp_parser_builtin_offsetof
@@ -7522,7 +7522,9 @@ cp_parser_postfix_open_square_expression (cp_parser *parser,
index = cp_parser_braced_list (parser, &expr_nonconst_p);
}
else
- index = cp_parser_expression (parser);
+ index = cp_parser_expression (parser, NULL, /*cast_p=*/false,
+ /*decltype_p=*/false,
+ /*warn_comma_p=*/warn_comma_subscript);
}
parser->greater_than_is_operator_p = saved_greater_than_is_operator_p;
@@ -9904,12 +9906,13 @@ cp_parser_assignment_operator_opt (cp_parser* parser)
CAST_P is true if this expression is the target of a cast.
DECLTYPE_P is true if this expression is the immediate operand of decltype,
except possibly parenthesized or on the RHS of a comma (N3276).
+ WARN_COMMA_P is true if a comma should be diagnosed.
Returns a representation of the expression. */
static cp_expr
cp_parser_expression (cp_parser* parser, cp_id_kind * pidk,
- bool cast_p, bool decltype_p)
+ bool cast_p, bool decltype_p, bool warn_comma_p)
{
cp_expr expression = NULL_TREE;
location_t loc = UNKNOWN_LOCATION;
@@ -9956,6 +9959,17 @@ cp_parser_expression (cp_parser* parser, cp_id_kind * pidk,
break;
/* Consume the `,'. */
loc = cp_lexer_peek_token (parser->lexer)->location;
+ if (warn_comma_p)
+ {
+ /* [depr.comma.subscript]: A comma expression appearing as
+ the expr-or-braced-init-list of a subscripting expression
+ is deprecated. A parenthesized comma expression is not
+ deprecated. */
+ warning_at (loc, OPT_Wcomma_subscript,
+ "top-level comma expression in array subscript "
+ "is deprecated");
+ warn_comma_p = false;
+ }
cp_lexer_consume_token (parser->lexer);
/* A comma operator cannot appear in a constant-expression. */
if (cp_parser_non_integral_constant_expression (parser, NIC_COMMA))
@@ -10976,7 +10990,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
DECL_ARTIFICIAL (fco) = 1;
/* Give the object parameter a different name. */
DECL_NAME (DECL_ARGUMENTS (fco)) = closure_identifier;
- DECL_LAMBDA_FUNCTION (fco) = 1;
+ DECL_SET_LAMBDA_FUNCTION (fco, true);
}
if (template_param_list)
{
@@ -14816,8 +14830,9 @@ cp_parser_conversion_type_id (cp_parser* parser)
parser->type_definition_forbidden_message
= G_("types may not be defined in a conversion-type-id");
- /* Parse the type-specifiers. */
- cp_parser_type_specifier_seq (parser, CP_PARSER_FLAGS_NONE,
+ /* Parse the type-specifiers. DR 2413 clarifies that `typename' is
+ optional in conversion-type-id. */
+ cp_parser_type_specifier_seq (parser, CP_PARSER_FLAGS_TYPENAME_OPTIONAL,
/*is_declaration=*/false,
/*is_trailing_return=*/false,
&type_specifiers);
@@ -19788,16 +19803,18 @@ cp_parser_asm_definition (cp_parser* parser)
bool invalid_inputs_p = false;
bool invalid_outputs_p = false;
required_token missing = RT_NONE;
+ location_t asm_loc = cp_lexer_peek_token (parser->lexer)->location;
/* Look for the `asm' keyword. */
cp_parser_require_keyword (parser, RID_ASM, RT_ASM);
+ /* In C++2a, unevaluated inline assembly is permitted in constexpr
+ functions. */
if (parser->in_function_body
- && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
- {
- error ("%<asm%> in %<constexpr%> function");
- cp_function_chain->invalid_constexpr = true;
- }
+ && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
+ && (cxx_dialect < cxx2a))
+ pedwarn (asm_loc, 0, "%<asm%> in %<constexpr%> function only available "
+ "with %<-std=c++2a%> or %<-std=gnu++2a%>");
/* Handle the asm-qualifier-list. */
location_t volatile_loc = UNKNOWN_LOCATION;
@@ -20003,7 +20020,7 @@ cp_parser_asm_definition (cp_parser* parser)
/* Create the ASM_EXPR. */
if (parser->in_function_body)
{
- asm_stmt = finish_asm_stmt (volatile_p, string, outputs,
+ asm_stmt = finish_asm_stmt (asm_loc, volatile_p, string, outputs,
inputs, clobbers, labels, inline_p);
/* If the extended syntax was not used, mark the ASM_EXPR. */
if (!extended_p)
@@ -23122,7 +23139,7 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p,
{
if (IDENTIFIER_MARKED (designator))
{
- error_at (cp_expr_loc_or_loc (val, input_location),
+ error_at (cp_expr_loc_or_input_loc (val),
"%<.%s%> designator used multiple times in "
"the same initializer list",
IDENTIFIER_POINTER (designator));
@@ -27790,7 +27807,9 @@ cp_parser_constructor_declarator_p (cp_parser *parser, cp_parser_flags flags,
/* A parameter declaration begins with a decl-specifier,
which is either the "attribute" keyword, a storage class
specifier, or (usually) a type-specifier. */
- && !cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer))
+ && !cp_lexer_next_token_is_decl_specifier_keyword (parser->lexer)
+ /* A parameter declaration can also begin with [[attribute]]. */
+ && !cp_next_tokens_can_be_std_attribute_p (parser))
{
tree type;
tree pushed_scope = NULL_TREE;
@@ -28105,7 +28124,10 @@ cp_parser_template_declaration_after_parameters (cp_parser* parser,
{
tree parm_list = TREE_VEC_ELT (parameter_list, 0);
tree parm = INNERMOST_TEMPLATE_PARMS (parm_list);
- if (CLASS_TYPE_P (TREE_TYPE (parm)))
+ if (TREE_CODE (parm) != PARM_DECL)
+ ok = false;
+ else if (MAYBE_CLASS_TYPE_P (TREE_TYPE (parm))
+ && !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
/* OK, C++20 string literal operator template. We don't need
to warn in lower dialects here because we will have already
warned about the template parameter. */;
@@ -28119,7 +28141,7 @@ cp_parser_template_declaration_after_parameters (cp_parser* parser,
tree type = INNERMOST_TEMPLATE_PARMS (parm_type);
tree parm_list = TREE_VEC_ELT (parameter_list, 1);
tree parm = INNERMOST_TEMPLATE_PARMS (parm_list);
- if (parm == error_mark_node
+ if (TREE_CODE (parm) != PARM_DECL
|| TREE_TYPE (parm) != TREE_TYPE (type)
|| !TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (parm)))
ok = false;
@@ -32438,6 +32460,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
result = PRAGMA_OACC_CLAUSE_DEVICEPTR;
else if (!strcmp ("device_resident", p))
result = PRAGMA_OACC_CLAUSE_DEVICE_RESIDENT;
+ else if (!strcmp ("device_type", p))
+ result = PRAGMA_OMP_CLAUSE_DEVICE_TYPE;
else if (!strcmp ("dist_schedule", p))
result = PRAGMA_OMP_CLAUSE_DIST_SCHEDULE;
break;
@@ -32580,6 +32604,8 @@ cp_parser_omp_clause_name (cp_parser *parser)
result = PRAGMA_OMP_CLAUSE_UNTIED;
else if (!strcmp ("use_device", p))
result = PRAGMA_OACC_CLAUSE_USE_DEVICE;
+ else if (!strcmp ("use_device_addr", p))
+ result = PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR;
else if (!strcmp ("use_device_ptr", p))
result = PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR;
break;
@@ -32610,14 +32636,8 @@ static void
check_no_duplicate_clause (tree clauses, enum omp_clause_code code,
const char *name, location_t location)
{
- tree c;
-
- for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
- if (OMP_CLAUSE_CODE (c) == code)
- {
- error_at (location, "too many %qs clauses", name);
- break;
- }
+ if (omp_find_clause (clauses, code))
+ error_at (location, "too many %qs clauses", name);
}
/* OpenMP 2.5:
@@ -33507,8 +33527,8 @@ cp_parser_omp_clause_if (cp_parser *parser, tree list, location_t location,
case OMP_TARGET_DATA: p = "target data"; break;
case OMP_TARGET: p = "target"; break;
case OMP_TARGET_UPDATE: p = "target update"; break;
- case OMP_TARGET_ENTER_DATA: p = "enter data"; break;
- case OMP_TARGET_EXIT_DATA: p = "exit data"; break;
+ case OMP_TARGET_ENTER_DATA: p = "target enter data"; break;
+ case OMP_TARGET_EXIT_DATA: p = "target exit data"; break;
default: gcc_unreachable ();
}
error_at (location, "too many %<if%> clauses with %qs modifier",
@@ -35184,8 +35204,10 @@ cp_parser_omp_clause_dist_schedule (cp_parser *parser, tree list,
else if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
goto resync_fail;
- check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE, "dist_schedule",
- location);
+ /* check_no_duplicate_clause (list, OMP_CLAUSE_DIST_SCHEDULE,
+ "dist_schedule", location); */
+ if (omp_find_clause (list, OMP_CLAUSE_DIST_SCHEDULE))
+ warning_at (location, 0, "too many %qs clauses", "dist_schedule");
OMP_CLAUSE_CHAIN (c) = list;
return c;
@@ -35251,6 +35273,56 @@ cp_parser_omp_clause_proc_bind (cp_parser *parser, tree list,
return list;
}
+/* OpenMP 5.0:
+ device_type ( host | nohost | any ) */
+
+static tree
+cp_parser_omp_clause_device_type (cp_parser *parser, tree list,
+ location_t location)
+{
+ tree c;
+ enum omp_clause_device_type_kind kind;
+
+ if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
+ return list;
+
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (strcmp ("host", p) == 0)
+ kind = OMP_CLAUSE_DEVICE_TYPE_HOST;
+ else if (strcmp ("nohost", p) == 0)
+ kind = OMP_CLAUSE_DEVICE_TYPE_NOHOST;
+ else if (strcmp ("any", p) == 0)
+ kind = OMP_CLAUSE_DEVICE_TYPE_ANY;
+ else
+ goto invalid_kind;
+ }
+ else
+ goto invalid_kind;
+
+ cp_lexer_consume_token (parser->lexer);
+ if (!cp_parser_require (parser, CPP_CLOSE_PAREN, RT_COMMA_CLOSE_PAREN))
+ goto resync_fail;
+
+ c = build_omp_clause (location, OMP_CLAUSE_DEVICE_TYPE);
+ /* check_no_duplicate_clause (list, OMP_CLAUSE_DEVICE_TYPE, "device_type",
+ location); */
+ OMP_CLAUSE_DEVICE_TYPE_KIND (c) = kind;
+ OMP_CLAUSE_CHAIN (c) = list;
+ return c;
+
+ invalid_kind:
+ cp_parser_error (parser, "invalid depend kind");
+ resync_fail:
+ cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
+ /*or_comma=*/false,
+ /*consume_paren=*/true);
+ return list;
+}
+
/* OpenACC:
async [( int-expr )] */
@@ -35569,6 +35641,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
clauses);
c_name = "use_device_ptr";
break;
+ case PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR:
+ clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_USE_DEVICE_ADDR,
+ clauses);
+ c_name = "use_device_addr";
+ break;
case PRAGMA_OMP_CLAUSE_IS_DEVICE_PTR:
clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_IS_DEVICE_PTR,
clauses);
@@ -35774,6 +35851,11 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
token->location);
c_name = "proc_bind";
break;
+ case PRAGMA_OMP_CLAUSE_DEVICE_TYPE:
+ clauses = cp_parser_omp_clause_device_type (parser, clauses,
+ token->location);
+ c_name = "device_type";
+ break;
case PRAGMA_OMP_CLAUSE_SAFELEN:
clauses = cp_parser_omp_clause_safelen (parser, clauses,
token->location);
@@ -36632,7 +36714,7 @@ cp_parser_omp_for_cond (cp_parser *parser, tree decl, enum tree_code code)
|| CLASS_TYPE_P (TREE_TYPE (decl))))
return cond;
- return build_x_binary_op (cp_expr_loc_or_loc (cond, input_location),
+ return build_x_binary_op (cp_expr_loc_or_input_loc (cond),
TREE_CODE (cond),
TREE_OPERAND (cond, 0), ERROR_MARK,
TREE_OPERAND (cond, 1), ERROR_MARK,
@@ -37390,7 +37472,8 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
real_decl = decl;
if (cclauses != NULL
&& cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL] != NULL
- && real_decl != NULL_TREE)
+ && real_decl != NULL_TREE
+ && code != OMP_LOOP)
{
tree *c;
for (c = &cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL]; *c ; )
@@ -37450,12 +37533,12 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
}
if (c == NULL)
{
- if (code != OMP_SIMD)
+ if ((code == OMP_SIMD && collapse != 1) || code == OMP_LOOP)
+ c = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
+ else if (code != OMP_SIMD)
c = build_omp_clause (loc, OMP_CLAUSE_PRIVATE);
- else if (collapse == 1)
- c = build_omp_clause (loc, OMP_CLAUSE_LINEAR);
else
- c = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
+ c = build_omp_clause (loc, OMP_CLAUSE_LINEAR);
OMP_CLAUSE_DECL (c) = add_private_clause;
c = finish_omp_clauses (c, C_ORT_OMP);
if (c)
@@ -38646,7 +38729,8 @@ cp_parser_omp_teams (cp_parser *parser, cp_token *pragma_tok,
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_MAP) \
| (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_IF) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_PTR) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_USE_DEVICE_ADDR))
static tree
cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
@@ -38682,7 +38766,8 @@ cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
*pc = OMP_CLAUSE_CHAIN (*pc);
continue;
}
- else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR)
+ else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
+ || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
map_seen = 3;
pc = &OMP_CLAUSE_CHAIN (*pc);
}
@@ -38692,7 +38777,8 @@ cp_parser_omp_target_data (cp_parser *parser, cp_token *pragma_tok, bool *if_p)
if (map_seen == 0)
error_at (pragma_tok->location,
"%<#pragma omp target data%> must contain at least "
- "one %<map%> or %<use_device_ptr%> clause");
+ "one %<map%>, %<use_device_ptr%> or %<use_device_addr%> "
+ "clause");
return NULL_TREE;
}
@@ -39752,12 +39838,15 @@ cp_parser_late_parsing_omp_declare_simd (cp_parser *parser, tree attrs)
#define OMP_DECLARE_TARGET_CLAUSE_MASK \
( (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_TO) \
- | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK))
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_LINK) \
+ | (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_DEVICE_TYPE))
static void
cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
{
tree clauses = NULL_TREE;
+ int device_type = 0;
+ bool only_device_type = true;
if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
clauses
= cp_parser_omp_all_clauses (parser, OMP_DECLARE_TARGET_CLAUSE_MASK,
@@ -39775,17 +39864,18 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
scope_chain->omp_declare_target_attribute++;
return;
}
- if (scope_chain->omp_declare_target_attribute)
- error_at (pragma_tok->location,
- "%<#pragma omp declare target%> with clauses in between "
- "%<#pragma omp declare target%> without clauses and "
- "%<#pragma omp end declare target%>");
+ for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+ device_type |= OMP_CLAUSE_DEVICE_TYPE_KIND (c);
for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
{
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_DEVICE_TYPE)
+ continue;
tree t = OMP_CLAUSE_DECL (c), id;
tree at1 = lookup_attribute ("omp declare target", DECL_ATTRIBUTES (t));
tree at2 = lookup_attribute ("omp declare target link",
DECL_ATTRIBUTES (t));
+ only_device_type = false;
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINK)
{
id = get_identifier ("omp declare target link");
@@ -39818,7 +39908,34 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
}
}
}
+ if (TREE_CODE (t) != FUNCTION_DECL)
+ continue;
+ if ((device_type & OMP_CLAUSE_DEVICE_TYPE_HOST) != 0)
+ {
+ tree at3 = lookup_attribute ("omp declare target host",
+ DECL_ATTRIBUTES (t));
+ if (at3 == NULL_TREE)
+ {
+ id = get_identifier ("omp declare target host");
+ DECL_ATTRIBUTES (t)
+ = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+ }
+ }
+ if ((device_type & OMP_CLAUSE_DEVICE_TYPE_NOHOST) != 0)
+ {
+ tree at3 = lookup_attribute ("omp declare target nohost",
+ DECL_ATTRIBUTES (t));
+ if (at3 == NULL_TREE)
+ {
+ id = get_identifier ("omp declare target nohost");
+ DECL_ATTRIBUTES (t)
+ = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+ }
+ }
}
+ if (device_type && only_device_type)
+ warning_at (OMP_CLAUSE_LOCATION (clauses), 0,
+ "directive with only %<device_type%> clauses ignored");
}
static void
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index deaac57..1758511 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3872,7 +3872,7 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data)
}
/* Determines if the expression or type T uses any parameter packs. */
-bool
+tree
uses_parameter_packs (tree t)
{
tree parameter_packs = NULL_TREE;
@@ -3882,7 +3882,7 @@ uses_parameter_packs (tree t)
ppd.type_pack_expansion_p = false;
cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
delete ppd.visited;
- return parameter_packs != NULL_TREE;
+ return parameter_packs;
}
/* Turn ARG, which may be an expression, type, or a TREE_LIST
@@ -4059,7 +4059,7 @@ check_for_bare_parameter_packs (tree t, location_t loc /* = UNKNOWN_LOCATION */)
if (parameter_packs)
{
if (loc == UNKNOWN_LOCATION)
- loc = cp_expr_loc_or_loc (t, input_location);
+ loc = cp_expr_loc_or_input_loc (t);
error_at (loc, "parameter packs not expanded with %<...%>:");
while (parameter_packs)
{
@@ -6306,7 +6306,7 @@ static bool
check_valid_ptrmem_cst_expr (tree type, tree expr,
tsubst_flags_t complain)
{
- location_t loc = cp_expr_loc_or_loc (expr, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (expr);
tree orig_expr = expr;
STRIP_NOPS (expr);
if (null_ptr_cst_p (expr))
@@ -6525,7 +6525,7 @@ unify_arg_conversion (bool explain_p, tree to_type,
tree from_type, tree arg)
{
if (explain_p)
- inform (cp_expr_loc_or_loc (arg, input_location),
+ inform (cp_expr_loc_or_input_loc (arg),
" cannot convert %qE (type %qT) to type %qT",
arg, from_type, to_type);
return unify_invalid (explain_p);
@@ -6765,7 +6765,7 @@ static tree
convert_nontype_argument (tree type, tree expr, tsubst_flags_t complain)
{
tree expr_type;
- location_t loc = cp_expr_loc_or_loc (expr, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (expr);
/* Detect immediately string literals as invalid non-type argument.
This special-case is not needed for correctness (we would easily
@@ -11764,10 +11764,6 @@ gen_elem_of_pack_expansion_instantiation (tree pattern,
ARGUMENT_PACK_SELECT_INDEX (aps) = index;
}
- // Any local specialization bindings arising from this substitution
- // cannot be reused for a different INDEX.
- local_specialization_stack lss (lss_copy);
-
/* Substitute into the PATTERN with the (possibly altered)
arguments. */
if (pattern == in_decl)
@@ -15139,24 +15135,12 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
/*function_p*/false,
/*integral_constant_expression*/false);
- if (DECLTYPE_FOR_INIT_CAPTURE (t))
- {
- if (type == NULL_TREE)
- {
- if (complain & tf_error)
- error ("empty initializer in lambda init-capture");
- type = error_mark_node;
- }
- else if (TREE_CODE (type) == TREE_LIST)
- type = build_x_compound_expr_from_list (type, ELK_INIT, complain);
- }
-
--cp_unevaluated_operand;
--c_inhibit_evaluation_warnings;
if (DECLTYPE_FOR_LAMBDA_CAPTURE (t))
type = lambda_capture_field_type (type,
- DECLTYPE_FOR_INIT_CAPTURE (t),
+ false /*explicit_init*/,
DECLTYPE_FOR_REF_CAPTURE (t));
else if (DECLTYPE_FOR_LAMBDA_PROXY (t))
type = lambda_proxy_type (type);
@@ -16319,6 +16303,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
case OMP_CLAUSE_MAP:
case OMP_CLAUSE_NONTEMPORAL:
case OMP_CLAUSE_USE_DEVICE_PTR:
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
case OMP_CLAUSE_IS_DEVICE_PTR:
case OMP_CLAUSE_INCLUSIVE:
case OMP_CLAUSE_EXCLUSIVE:
@@ -16420,6 +16405,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
case OMP_CLAUSE_SIMD:
case OMP_CLAUSE_DEFAULTMAP:
case OMP_CLAUSE_ORDER:
+ case OMP_CLAUSE_BIND:
case OMP_CLAUSE_INDEPENDENT:
case OMP_CLAUSE_AUTO:
case OMP_CLAUSE_SEQ:
@@ -16442,6 +16428,7 @@ tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
case OMP_CLAUSE_IN_REDUCTION:
case OMP_CLAUSE_TASK_REDUCTION:
case OMP_CLAUSE_USE_DEVICE_PTR:
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
case OMP_CLAUSE_IS_DEVICE_PTR:
case OMP_CLAUSE_INCLUSIVE:
case OMP_CLAUSE_EXCLUSIVE:
@@ -16748,7 +16735,8 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree &orig_declv,
{
tree *pc;
int j;
- for (j = (omp_parallel_combined_clauses == NULL ? 1 : 0); j < 2; j++)
+ for (j = ((omp_parallel_combined_clauses == NULL
+ || TREE_CODE (t) == OMP_LOOP) ? 1 : 0); j < 2; j++)
{
for (pc = j ? clauses : omp_parallel_combined_clauses; *pc; )
{
@@ -16788,7 +16776,10 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree &orig_declv,
}
if (*pc == NULL_TREE)
{
- tree c = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
+ tree c = build_omp_clause (input_location,
+ TREE_CODE (t) == OMP_LOOP
+ ? OMP_CLAUSE_LASTPRIVATE
+ : OMP_CLAUSE_PRIVATE);
OMP_CLAUSE_DECL (c) = decl;
c = finish_omp_clauses (c, C_ORT_OMP);
if (c)
@@ -17405,8 +17396,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
complain, in_decl);
tree labels = tsubst_copy_asm_operands (ASM_LABELS (t), args,
complain, in_decl);
- tmp = finish_asm_stmt (ASM_VOLATILE_P (t), string, outputs, inputs,
- clobbers, labels, ASM_INLINE_P (t));
+ tmp = finish_asm_stmt (EXPR_LOCATION (t), ASM_VOLATILE_P (t), string,
+ outputs, inputs, clobbers, labels,
+ ASM_INLINE_P (t));
tree asm_expr = tmp;
if (TREE_CODE (asm_expr) == CLEANUP_POINT_EXPR)
asm_expr = TREE_OPERAND (asm_expr, 0);
@@ -18023,6 +18015,33 @@ tsubst_non_call_postfix_expression (tree t, tree args,
return t;
}
+/* Subroutine of tsubst_lambda_expr: add the FIELD/INIT capture pair to the
+ LAMBDA_EXPR_CAPTURE_LIST passed in LIST. Do deduction for a previously
+ dependent init-capture. */
+
+static void
+prepend_one_capture (tree field, tree init, tree &list,
+ tsubst_flags_t complain)
+{
+ if (tree auto_node = type_uses_auto (TREE_TYPE (field)))
+ {
+ tree type = NULL_TREE;
+ if (!init)
+ {
+ if (complain & tf_error)
+ error ("empty initializer in lambda init-capture");
+ init = error_mark_node;
+ }
+ else if (TREE_CODE (init) == TREE_LIST)
+ init = build_x_compound_expr_from_list (init, ELK_INIT, complain);
+ if (!type)
+ type = do_auto_deduction (TREE_TYPE (field), init, auto_node, complain);
+ TREE_TYPE (field) = type;
+ cp_apply_type_quals_to_decl (cp_type_quals (type), field);
+ }
+ list = tree_cons (field, init, list);
+}
+
/* T is a LAMBDA_EXPR. Generate a new LAMBDA_EXPR for the current
instantiation context. Instantiating a pack expansion containing a lambda
might result in multiple lambdas all based on the same lambda in the
@@ -18034,17 +18053,8 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
tree oldfn = lambda_function (t);
in_decl = oldfn;
- /* If we have already specialized this lambda expr, reuse it. See
- PR c++/87322. */
- if (local_specializations)
- if (tree r = retrieve_local_specialization (t))
- return r;
-
tree r = build_lambda_expr ();
- if (local_specializations)
- register_local_specialization (r, t);
-
LAMBDA_EXPR_LOCATION (r)
= LAMBDA_EXPR_LOCATION (t);
LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (r)
@@ -18097,15 +18107,15 @@ tsubst_lambda_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl)
gcc_assert (TREE_CODE (init) == TREE_VEC
&& TREE_VEC_LENGTH (init) == len);
for (int i = 0; i < len; ++i)
- LAMBDA_EXPR_CAPTURE_LIST (r)
- = tree_cons (TREE_VEC_ELT (field, i),
- TREE_VEC_ELT (init, i),
- LAMBDA_EXPR_CAPTURE_LIST (r));
+ prepend_one_capture (TREE_VEC_ELT (field, i),
+ TREE_VEC_ELT (init, i),
+ LAMBDA_EXPR_CAPTURE_LIST (r),
+ complain);
}
else
{
- LAMBDA_EXPR_CAPTURE_LIST (r)
- = tree_cons (field, init, LAMBDA_EXPR_CAPTURE_LIST (r));
+ prepend_one_capture (field, init, LAMBDA_EXPR_CAPTURE_LIST (r),
+ complain);
if (id_equal (DECL_NAME (field), "__this"))
LAMBDA_EXPR_THIS_CAPTURE (r) = field;
@@ -18963,10 +18973,10 @@ tsubst_copy_and_build (tree t,
bool diag = true;
if (in_lambda)
- error_at (cp_expr_loc_or_loc (t, input_location),
+ error_at (cp_expr_loc_or_input_loc (t),
msg, function);
else
- diag = permerror (cp_expr_loc_or_loc (t, input_location),
+ diag = permerror (cp_expr_loc_or_input_loc (t),
msg, function);
if (diag)
{
@@ -18981,8 +18991,7 @@ tsubst_copy_and_build (tree t,
/* Can't say anything more. */;
else if (DECL_CLASS_SCOPE_P (fn))
{
- location_t loc = cp_expr_loc_or_loc (t,
- input_location);
+ location_t loc = cp_expr_loc_or_input_loc (t);
inform (loc,
"declarations in dependent base %qT are "
"not found by unqualified lookup",
@@ -19030,14 +19039,13 @@ tsubst_copy_and_build (tree t,
gcc_assert (nargs == 1);
if (vec_safe_length (call_args) != 1)
{
- error_at (cp_expr_loc_or_loc (t, input_location),
+ error_at (cp_expr_loc_or_input_loc (t),
"wrong number of arguments to "
"%<__builtin_launder%>");
ret = error_mark_node;
}
else
- ret = finish_builtin_launder (cp_expr_loc_or_loc (t,
- input_location),
+ ret = finish_builtin_launder (cp_expr_loc_or_input_loc (t),
(*call_args)[0], complain);
break;
@@ -19045,7 +19053,7 @@ tsubst_copy_and_build (tree t,
gcc_assert (nargs == 1);
if (vec_safe_length (call_args) != 1)
{
- error_at (cp_expr_loc_or_loc (t, input_location),
+ error_at (cp_expr_loc_or_input_loc (t),
"wrong number of arguments to "
"%<__builtin_convertvector%>");
ret = error_mark_node;
@@ -24310,12 +24318,11 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
}
else if (push_tinst_level (fn))
{
+ push_to_top_level ();
push_access_scope (fn);
push_deferring_access_checks (dk_no_deferred);
input_location = DECL_SOURCE_LOCATION (fn);
- tree save_ccp = current_class_ptr;
- tree save_ccr = current_class_ref;
/* If needed, set current_class_ptr for the benefit of
tsubst_copy/PARM_DECL. */
tree tdecl = DECL_TEMPLATE_RESULT (DECL_TI_TEMPLATE (fn));
@@ -24341,9 +24348,6 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
/*function_p=*/false,
/*i_c_e_p=*/true);
- current_class_ptr = save_ccp;
- current_class_ref = save_ccr;
-
/* Build up the noexcept-specification. */
spec = build_noexcept_spec (noex, tf_warning_or_error);
@@ -24353,6 +24357,7 @@ maybe_instantiate_noexcept (tree fn, tsubst_flags_t complain)
pop_deferring_access_checks ();
pop_access_scope (fn);
pop_tinst_level ();
+ pop_from_top_level ();
}
else
spec = noexcept_false_spec;
@@ -25551,7 +25556,14 @@ value_dependent_expression_p (tree expression)
if (DECL_HAS_VALUE_EXPR_P (expression))
{
tree value_expr = DECL_VALUE_EXPR (expression);
- if (value_dependent_expression_p (value_expr))
+ if (value_dependent_expression_p (value_expr)
+ /* __PRETTY_FUNCTION__ inside a template function is dependent
+ on the name of the function. */
+ || (DECL_PRETTY_FUNCTION_P (expression)
+ /* It might be used in a template, but not a template
+ function, in which case its DECL_VALUE_EXPR will be
+ "top level". */
+ && value_expr == error_mark_node))
return true;
}
return false;
@@ -26593,7 +26605,7 @@ resolve_typename_type (tree type, bool only_current_p)
[temp.names]: In a qualified-id of a declarator-id, the keyword
template shall not appear at the top level. */
- pedwarn (cp_expr_loc_or_loc (fullname, input_location), OPT_Wpedantic,
+ pedwarn (cp_expr_loc_or_input_loc (fullname), OPT_Wpedantic,
"keyword %<template%> not allowed in declarator-id");
tmpl = decl;
}
@@ -27602,6 +27614,9 @@ do_auto_deduction (tree type, tree init, tree auto_node,
}
else
{
+ if (error_operand_p (init))
+ return error_mark_node;
+
tree parms = build_tree_list (NULL_TREE, type);
tree tparms;
@@ -28316,9 +28331,8 @@ declare_integer_pack (void)
NULL_TREE),
NULL_TREE, ECF_CONST);
DECL_DECLARED_CONSTEXPR_P (ipfn) = true;
- DECL_BUILT_IN_CLASS (ipfn) = BUILT_IN_FRONTEND;
- DECL_FUNCTION_CODE (ipfn)
- = (enum built_in_function) (int) CP_BUILT_IN_INTEGER_PACK;
+ set_decl_built_in_function (ipfn, BUILT_IN_FRONTEND,
+ CP_BUILT_IN_INTEGER_PACK);
}
/* Set up the hash tables for template instantiations. */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 269092d..7ac1ba0 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -658,7 +658,7 @@ maybe_convert_cond (tree cond)
if (TREE_CODE (cond) == MODIFY_EXPR
&& !TREE_NO_WARNING (cond)
&& warn_parentheses
- && warning_at (cp_expr_loc_or_loc (cond, input_location),
+ && warning_at (cp_expr_loc_or_input_loc (cond),
OPT_Wparentheses, "suggest parentheses around "
"assignment used as truth value"))
TREE_NO_WARNING (cond) = 1;
@@ -1484,8 +1484,9 @@ finish_compound_stmt (tree stmt)
considered volatile, and whether it is asm inline. */
tree
-finish_asm_stmt (int volatile_p, tree string, tree output_operands,
- tree input_operands, tree clobbers, tree labels, bool inline_p)
+finish_asm_stmt (location_t loc, int volatile_p, tree string,
+ tree output_operands, tree input_operands, tree clobbers,
+ tree labels, bool inline_p)
{
tree r;
tree t;
@@ -1532,7 +1533,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
effectively const. */
|| (CLASS_TYPE_P (TREE_TYPE (operand))
&& C_TYPE_FIELDS_READONLY (TREE_TYPE (operand)))))
- cxx_readonly_error (input_location, operand, lv_asm);
+ cxx_readonly_error (loc, operand, lv_asm);
tree *op = &operand;
while (TREE_CODE (*op) == COMPOUND_EXPR)
@@ -1585,8 +1586,9 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
resolve the overloading. */
if (TREE_TYPE (operand) == unknown_type_node)
{
- error ("type of %<asm%> operand %qE could not be determined",
- TREE_VALUE (t));
+ error_at (loc,
+ "type of %<asm%> operand %qE could not be determined",
+ TREE_VALUE (t));
operand = error_mark_node;
}
@@ -1634,7 +1636,7 @@ finish_asm_stmt (int volatile_p, tree string, tree output_operands,
}
}
- r = build_stmt (input_location, ASM_EXPR, string,
+ r = build_stmt (loc, ASM_EXPR, string,
output_operands, input_operands,
clobbers, labels);
ASM_VOLATILE_P (r) = volatile_p || noutputs == 0;
@@ -1745,14 +1747,16 @@ force_paren_expr (tree expr)
&& TREE_CODE (expr) != SCOPE_REF)
return expr;
+ location_t loc = cp_expr_location (expr);
+
if (TREE_CODE (expr) == COMPONENT_REF
|| TREE_CODE (expr) == SCOPE_REF)
REF_PARENTHESIZED_P (expr) = true;
else if (processing_template_decl)
- expr = build1 (PAREN_EXPR, TREE_TYPE (expr), expr);
+ expr = build1_loc (loc, PAREN_EXPR, TREE_TYPE (expr), expr);
else
{
- expr = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), expr);
+ expr = build1_loc (loc, VIEW_CONVERT_EXPR, TREE_TYPE (expr), expr);
REF_PARENTHESIZED_P (expr) = true;
}
@@ -2426,7 +2430,7 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
|| any_type_dependent_arguments_p (*args))
{
result = build_min_nt_call_vec (orig_fn, *args);
- SET_EXPR_LOCATION (result, cp_expr_loc_or_loc (fn, input_location));
+ SET_EXPR_LOCATION (result, cp_expr_loc_or_input_loc (fn));
KOENIG_LOOKUP_P (result) = koenig_p;
if (is_overloaded_fn (fn))
fn = get_fns (fn);
@@ -6144,7 +6148,8 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
/* If ort == C_ORT_OMP_DECLARE_SIMD used as uniform_head instead. */
bitmap_initialize (&map_head, &bitmap_default_obstack);
bitmap_initialize (&map_field_head, &bitmap_default_obstack);
- /* If ort == C_ORT_OMP used as nontemporal_head instead. */
+ /* If ort == C_ORT_OMP used as nontemporal_head or use_device_xxx_head
+ instead. */
bitmap_initialize (&oacc_reduction_head, &bitmap_default_obstack);
if (ort & C_ORT_ACC)
@@ -6402,13 +6407,19 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
remove = true;
}
- else if (ort == C_ORT_ACC
- && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
+ else if ((ort == C_ORT_ACC
+ && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION)
+ || (ort == C_ORT_OMP
+ && (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
+ || (OMP_CLAUSE_CODE (c)
+ == OMP_CLAUSE_USE_DEVICE_ADDR))))
{
if (bitmap_bit_p (&oacc_reduction_head, DECL_UID (t)))
{
error_at (OMP_CLAUSE_LOCATION (c),
- "%qD appears more than once in reduction clauses",
+ ort == C_ORT_ACC
+ ? "%qD appears more than once in reduction clauses"
+ : "%qD appears more than once in data clauses",
t);
remove = true;
}
@@ -7522,20 +7533,41 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
{
tree type = TREE_TYPE (t);
if (!TYPE_PTR_P (type)
- && TREE_CODE (type) != ARRAY_TYPE
- && (!TYPE_REF_P (type)
- || (!TYPE_PTR_P (TREE_TYPE (type))
- && TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE)))
+ && (!TYPE_REF_P (type) || !TYPE_PTR_P (TREE_TYPE (type))))
{
- error_at (OMP_CLAUSE_LOCATION (c),
- "%qs variable is neither a pointer, nor an array "
- "nor reference to pointer or array",
- omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
- remove = true;
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR
+ && ort == C_ORT_OMP)
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qs variable is neither a pointer "
+ "nor reference to pointer",
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ }
+ else if (TREE_CODE (type) != ARRAY_TYPE
+ && (!TYPE_REF_P (type)
+ || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE))
+ {
+ error_at (OMP_CLAUSE_LOCATION (c),
+ "%qs variable is neither a pointer, nor an "
+ "array nor reference to pointer or array",
+ omp_clause_code_name[OMP_CLAUSE_CODE (c)]);
+ remove = true;
+ }
}
}
goto check_dup_generic;
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
+ field_ok = true;
+ t = OMP_CLAUSE_DECL (c);
+ if (!processing_template_decl
+ && (VAR_P (t) || TREE_CODE (t) == PARM_DECL)
+ && !TYPE_REF_P (TREE_TYPE (t))
+ && !cxx_mark_addressable (t))
+ remove = true;
+ goto check_dup_generic;
+
case OMP_CLAUSE_NOWAIT:
case OMP_CLAUSE_DEFAULT:
case OMP_CLAUSE_UNTIED:
@@ -7546,6 +7578,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
case OMP_CLAUSE_SECTIONS:
case OMP_CLAUSE_TASKGROUP:
case OMP_CLAUSE_PROC_BIND:
+ case OMP_CLAUSE_DEVICE_TYPE:
case OMP_CLAUSE_NOGROUP:
case OMP_CLAUSE_THREADS:
case OMP_CLAUSE_SIMD:
@@ -8420,24 +8453,25 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
incr = cp_convert (TREE_TYPE (diff), incr, tf_warning_or_error);
incr = cp_fully_fold (incr);
- bool taskloop_iv_seen = false;
+ tree loop_iv_seen = NULL_TREE;
for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
&& OMP_CLAUSE_DECL (c) == iter)
{
- if (code == OMP_TASKLOOP)
+ if (code == OMP_TASKLOOP || code == OMP_LOOP)
{
- taskloop_iv_seen = true;
- OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c) = 1;
+ loop_iv_seen = c;
+ OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) = 1;
}
break;
}
- else if (code == OMP_TASKLOOP
+ else if ((code == OMP_TASKLOOP || code == OMP_LOOP)
&& OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
&& OMP_CLAUSE_DECL (c) == iter)
{
- taskloop_iv_seen = true;
- OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c) = 1;
+ loop_iv_seen = c;
+ if (code == OMP_TASKLOOP)
+ OMP_CLAUSE_PRIVATE_TASKLOOP_IV (c) = 1;
}
decl = create_temporary_var (TREE_TYPE (diff));
@@ -8457,7 +8491,7 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
tree diffvar = NULL_TREE;
if (code == OMP_TASKLOOP)
{
- if (!taskloop_iv_seen)
+ if (!loop_iv_seen)
{
tree ivc = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (ivc) = iter;
@@ -8473,6 +8507,28 @@ handle_omp_for_class_iterator (int i, location_t locus, enum tree_code code,
pushdecl (diffvar);
add_decl_expr (diffvar);
}
+ else if (code == OMP_LOOP)
+ {
+ if (!loop_iv_seen)
+ {
+ /* While iterators on the loop construct are predetermined
+ lastprivate, if the decl is not declared inside of the
+ loop, OMP_CLAUSE_LASTPRIVATE should have been added
+ already. */
+ loop_iv_seen = build_omp_clause (locus, OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (loop_iv_seen) = iter;
+ OMP_CLAUSE_CHAIN (loop_iv_seen) = clauses;
+ clauses = loop_iv_seen;
+ }
+ else if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_PRIVATE)
+ {
+ OMP_CLAUSE_PRIVATE_DEBUG (loop_iv_seen) = 0;
+ OMP_CLAUSE_PRIVATE_OUTER_REF (loop_iv_seen) = 0;
+ OMP_CLAUSE_CODE (loop_iv_seen) = OMP_CLAUSE_FIRSTPRIVATE;
+ }
+ if (OMP_CLAUSE_CODE (loop_iv_seen) == OMP_CLAUSE_FIRSTPRIVATE)
+ cxx_omp_finish_clause (loop_iv_seen, NULL);
+ }
orig_pre_body = *pre_body;
*pre_body = push_stmt_list ();
@@ -8823,9 +8879,7 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
omp_for = NULL_TREE;
if (omp_for == NULL)
- {
- return NULL;
- }
+ return NULL;
add_stmt (omp_for);
@@ -8924,6 +8978,16 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
gcc_unreachable ();
}
}
+ /* Override saved methods on OMP_LOOP's OMP_CLAUSE_LASTPRIVATE_LOOP_IV
+ clauses, we need copy ctor for those rather than default ctor,
+ plus as for other lastprivates assignment op and dtor. */
+ if (code == OMP_LOOP && !processing_template_decl)
+ for (tree c = clauses; c; c = OMP_CLAUSE_CHAIN (c))
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)
+ && cxx_omp_create_clause_info (c, TREE_TYPE (OMP_CLAUSE_DECL (c)),
+ false, true, true, true))
+ CP_OMP_CLAUSE_INFO (c) = NULL_TREE;
return omp_for;
}
@@ -10102,7 +10166,7 @@ cp_build_vec_convert (tree arg, location_t loc, tree type,
tree ret = NULL_TREE;
if (!type_dependent_expression_p (arg) && !dependent_type_p (type))
- ret = c_build_vec_convert (cp_expr_loc_or_loc (arg, input_location), arg,
+ ret = c_build_vec_convert (cp_expr_loc_or_input_loc (arg), arg,
loc, type, (complain & tf_error) != 0);
if (!processing_template_decl)
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 37e24a1..17a4df3 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -236,10 +236,23 @@ lvalue_kind (const_tree ref)
gcc_assert (!type_dependent_expression_p (CONST_CAST_TREE (ref)));
goto default_;
}
- op1_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 1)
- ? TREE_OPERAND (ref, 1)
- : TREE_OPERAND (ref, 0));
- op2_lvalue_kind = lvalue_kind (TREE_OPERAND (ref, 2));
+ {
+ tree op1 = TREE_OPERAND (ref, 1);
+ if (!op1) op1 = TREE_OPERAND (ref, 0);
+ tree op2 = TREE_OPERAND (ref, 2);
+ op1_lvalue_kind = lvalue_kind (op1);
+ op2_lvalue_kind = lvalue_kind (op2);
+ if (!op1_lvalue_kind != !op2_lvalue_kind)
+ {
+ /* The second or the third operand (but not both) is a
+ throw-expression; the result is of the type
+ and value category of the other. */
+ if (op1_lvalue_kind && TREE_CODE (op2) == THROW_EXPR)
+ op2_lvalue_kind = op1_lvalue_kind;
+ else if (op2_lvalue_kind && TREE_CODE (op1) == THROW_EXPR)
+ op1_lvalue_kind = op2_lvalue_kind;
+ }
+ }
break;
case MODOP_EXPR:
@@ -4361,7 +4374,8 @@ handle_nodiscard_attribute (tree *node, tree name, tree /*args*/,
{
if (TREE_CODE (*node) == FUNCTION_DECL)
{
- if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (*node))))
+ if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (*node)))
+ && !DECL_CONSTRUCTOR_P (*node))
warning_at (DECL_SOURCE_LOCATION (*node),
OPT_Wattributes, "%qE attribute applied to %qD with void "
"return type", name, *node);
@@ -5014,6 +5028,31 @@ special_function_p (const_tree decl)
return sfk_none;
}
+/* As above, but only if DECL is a special member function as per 11.3.3
+ [special]: default/copy/move ctor, copy/move assignment, or destructor. */
+
+special_function_kind
+special_memfn_p (const_tree decl)
+{
+ switch (special_function_kind sfk = special_function_p (decl))
+ {
+ case sfk_constructor:
+ if (!default_ctor_p (decl))
+ break;
+ gcc_fallthrough();
+ case sfk_copy_constructor:
+ case sfk_copy_assignment:
+ case sfk_move_assignment:
+ case sfk_move_constructor:
+ case sfk_destructor:
+ return sfk;
+
+ default:
+ break;
+ }
+ return sfk_none;
+}
+
/* Returns nonzero if TYPE is a character type, including wchar_t. */
int
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 7709595..e2a4f28 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -2020,7 +2020,7 @@ decay_conversion (tree exp,
{
tree type;
enum tree_code code;
- location_t loc = cp_expr_loc_or_loc (exp, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (exp);
type = TREE_TYPE (exp);
if (type == error_mark_node)
@@ -2281,7 +2281,7 @@ static tree
rationalize_conditional_expr (enum tree_code code, tree t,
tsubst_flags_t complain)
{
- location_t loc = cp_expr_loc_or_loc (t, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (t);
/* For MIN_EXPR or MAX_EXPR, fold-const.c has arranged things so that
the first operand is always the one to be used if both operands
@@ -2308,13 +2308,15 @@ rationalize_conditional_expr (enum tree_code code, tree t,
complain);
}
+ tree op1 = TREE_OPERAND (t, 1);
+ if (TREE_CODE (op1) != THROW_EXPR)
+ op1 = cp_build_unary_op (code, op1, false, complain);
+ tree op2 = TREE_OPERAND (t, 2);
+ if (TREE_CODE (op2) != THROW_EXPR)
+ op2 = cp_build_unary_op (code, op2, false, complain);
+
return
- build_conditional_expr (loc, TREE_OPERAND (t, 0),
- cp_build_unary_op (code, TREE_OPERAND (t, 1), false,
- complain),
- cp_build_unary_op (code, TREE_OPERAND (t, 2), false,
- complain),
- complain);
+ build_conditional_expr (loc, TREE_OPERAND (t, 0), op1, op2, complain);
}
/* Given the TYPE of an anonymous union field inside T, return the
@@ -5509,9 +5511,9 @@ cp_build_binary_op (const op_location_t &location,
if (! converted)
{
warning_sentinel w (warn_sign_conversion, short_compare);
- if (TREE_TYPE (op0) != result_type)
+ if (!same_type_p (TREE_TYPE (op0), result_type))
op0 = cp_convert_and_check (result_type, op0, complain);
- if (TREE_TYPE (op1) != result_type)
+ if (!same_type_p (TREE_TYPE (op1), result_type))
op1 = cp_convert_and_check (result_type, op1, complain);
if (op0 == error_mark_node || op1 == error_mark_node)
@@ -6206,7 +6208,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, bool noconvert,
{
/* No default_conversion here. It causes trouble for ADDR_EXPR. */
tree arg = xarg;
- location_t location = cp_expr_loc_or_loc (arg, input_location);
+ location_t location = cp_expr_loc_or_input_loc (arg);
tree argtype = 0;
const char *errstring = NULL;
tree val;
@@ -6760,7 +6762,7 @@ build_x_compound_expr_from_list (tree list, expr_list_kind exp,
&& !CONSTRUCTOR_IS_DIRECT_INIT (expr))
{
if (complain & tf_error)
- pedwarn (cp_expr_loc_or_loc (expr, input_location), 0,
+ pedwarn (cp_expr_loc_or_input_loc (expr), 0,
"list-initializer for non-class type must not "
"be parenthesized");
else
@@ -8160,8 +8162,9 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
if (!lvalue_or_else (lhs, lv_assign, complain))
return error_mark_node;
- tree op1 = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 1),
- modifycode, rhs, complain);
+ tree op1 = TREE_OPERAND (lhs, 1);
+ if (TREE_CODE (op1) != THROW_EXPR)
+ op1 = cp_build_modify_expr (loc, op1, modifycode, rhs, complain);
/* When sanitizing undefined behavior, even when rhs doesn't need
stabilization at this point, the sanitization might add extra
SAVE_EXPRs in there and so make sure there is no tree sharing
@@ -8170,8 +8173,9 @@ cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
if (sanitize_flags_p (SANITIZE_UNDEFINED
| SANITIZE_UNDEFINED_NONDEFAULT))
rhs = unshare_expr (rhs);
- tree op2 = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 2),
- modifycode, rhs, complain);
+ tree op2 = TREE_OPERAND (lhs, 2);
+ if (TREE_CODE (op2) != THROW_EXPR)
+ op2 = cp_build_modify_expr (loc, op2, modifycode, rhs, complain);
tree cond = build_conditional_expr (input_location,
TREE_OPERAND (lhs, 0), op1, op2,
complain);
@@ -9210,7 +9214,7 @@ maybe_warn_about_returning_address_of_local (tree retval)
{
tree valtype = TREE_TYPE (DECL_RESULT (current_function_decl));
tree whats_returned = fold_for_warn (retval);
- location_t loc = cp_expr_loc_or_loc (retval, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (retval);
for (;;)
{
@@ -9420,7 +9424,7 @@ maybe_warn_pessimizing_move (tree retval, tree functype)
if (!(warn_pessimizing_move || warn_redundant_move))
return;
- location_t loc = cp_expr_loc_or_loc (retval, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (retval);
/* C++98 doesn't know move. */
if (cxx_dialect < cxx11)
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index e8627dd..02c3ad5 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1006,7 +1006,7 @@ check_narrowing (tree type, tree init, tsubst_flags_t complain, bool const_only)
if (!ok)
{
- location_t loc = cp_expr_loc_or_loc (init, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (init);
if (cxx_dialect == cxx98)
{
if (complain & tf_warning)
@@ -1085,7 +1085,7 @@ digest_init_r (tree type, tree init, int nested, int flags,
complain))
return error_mark_node;
- location_t loc = cp_expr_loc_or_loc (init, input_location);
+ location_t loc = cp_expr_loc_or_input_loc (init);
tree stripped_init = init;
@@ -1402,7 +1402,7 @@ process_init_constructor_array (tree type, tree init, int nested, int flags,
if (nested == 2 && !domain && !vec_safe_is_empty (v))
{
if (complain & tf_error)
- error_at (cp_expr_loc_or_loc (init, input_location),
+ error_at (cp_expr_loc_or_input_loc (init),
"initialization of flexible array member "
"in a nested context");
return PICFLAG_ERRONEOUS;
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index 51d1721..a4db1fa 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,28 @@
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR middle-end/91421
+ * intrinsics.cc (maybe_set_intrinsic): Use set_decl_built_in_function.
+
+2019-08-11 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/90601
+ * d-convert.cc (convert_expr): Don't convert an expression to its
+ original front-end type before converting to its target type.
+
+2019-08-10 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/91238
+ * d-codegen.cc (build_address): If taking the address of a CALL_EXPR,
+ wrap it in a TARGET_EXPR.
+
+2019-08-10 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/90893
+ * runtime.cc (enum libcall_type): Rename to...
+ (enum d_libcall_type): ...this.
+ (get_libcall_type): Use d_libcall_type.
+ (build_libcall_decl): Likewise.
+
2019-06-16 Iain Buclaw <ibuclaw@gdcproject.org>
PR d/90559
@@ -32,18 +57,18 @@
2019-05-16 Martin Sebor <msebor@redhat.com>
- * d-builtins.cc (d_init_builtins): Quote keywords, operators,
- and types in diagnostics.
- * d-codegen.cc (get_array_length): Same. Replace can't with cannot.
- * d-convert.cc (convert_expr): Same.
- * d-frontend.cc (getTypeInfoType): Quote an option name in
- a diagnostic.
- * d-lang.cc (d_handle_option): Same.
- (d_parse_file): Same.
- * decl.cc: Remove a trailing period from a diagnostic.
- * expr.cc: Use a directive for an apostrophe.
- * toir.cc: Quote keywords, operators, and types in diagnostics.
- * typeinfo.cc (build_typeinfo): Quote an option name in a diagnostic.
+ * d-builtins.cc (d_init_builtins): Quote keywords, operators,
+ and types in diagnostics.
+ * d-codegen.cc (get_array_length): Same. Replace can't with cannot.
+ * d-convert.cc (convert_expr): Same.
+ * d-frontend.cc (getTypeInfoType): Quote an option name in
+ a diagnostic.
+ * d-lang.cc (d_handle_option): Same.
+ (d_parse_file): Same.
+ * decl.cc: Remove a trailing period from a diagnostic.
+ * expr.cc: Use a directive for an apostrophe.
+ * toir.cc: Quote keywords, operators, and types in diagnostics.
+ * typeinfo.cc (build_typeinfo): Quote an option name in a diagnostic.
2019-04-25 Johannes Pfau <johannespfau@gmail.com>
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 1971064..cf50693 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -651,9 +651,11 @@ build_address (tree exp)
if (TREE_CODE (exp) == CONST_DECL)
exp = DECL_INITIAL (exp);
- /* Some expression lowering may request an address of a compile-time constant.
- Make sure it is assigned to a location we can reference. */
- if (CONSTANT_CLASS_P (exp) && TREE_CODE (exp) != STRING_CST)
+ /* Some expression lowering may request an address of a compile-time constant,
+ or other non-lvalue expression. Make sure it is assigned to a location we
+ can reference. */
+ if ((CONSTANT_CLASS_P (exp) && TREE_CODE (exp) != STRING_CST)
+ || TREE_CODE (exp) == CALL_EXPR)
exp = force_target_expr (exp);
d_mark_addressable (exp);
diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc
index b020eab..fd4fc3c 100644
--- a/gcc/d/d-convert.cc
+++ b/gcc/d/d-convert.cc
@@ -588,7 +588,6 @@ convert_expr (tree exp, Type *etype, Type *totype)
return compound_expr (exp, build_zero_cst (build_ctype (tbtype)));
}
- exp = fold_convert (build_ctype (etype), exp);
gcc_assert (TREE_CODE (exp) != STRING_CST);
break;
}
diff --git a/gcc/d/intrinsics.cc b/gcc/d/intrinsics.cc
index 4bd321b..56eab52 100644
--- a/gcc/d/intrinsics.cc
+++ b/gcc/d/intrinsics.cc
@@ -134,10 +134,7 @@ maybe_set_intrinsic (FuncDeclaration *decl)
/* If there is no function body, then the implementation is always
provided by the compiler. */
if (!decl->fbody)
- {
- DECL_BUILT_IN_CLASS (decl->csym) = BUILT_IN_FRONTEND;
- DECL_FUNCTION_CODE (decl->csym) = (built_in_function) code;
- }
+ set_decl_built_in_function (decl->csym, BUILT_IN_FRONTEND, code);
/* Infer whether the intrinsic can be used for CTFE, let the
front-end know that it can be evaluated at compile-time. */
diff --git a/gcc/d/runtime.cc b/gcc/d/runtime.cc
index c2a5c55..72659ae 100644
--- a/gcc/d/runtime.cc
+++ b/gcc/d/runtime.cc
@@ -34,7 +34,7 @@ along with GCC; see the file COPYING3. If not see
We represent them in the frontend here, however there's no guarantee that
the compiler implementation actually matches the actual implementation. */
-enum libcall_type
+enum d_libcall_type
{
LCT_VOID, /* void */
LCT_BYTE, /* byte */
@@ -81,7 +81,7 @@ static tree libcall_decls[LIBCALL_LAST];
arrayOf() will return cached types if they have been requested before. */
static Type *
-get_libcall_type (libcall_type type)
+get_libcall_type (d_libcall_type type)
{
if (libcall_types[type])
return libcall_types[type];
@@ -212,7 +212,7 @@ get_libcall_type (libcall_type type)
the number of arguments, the types of which are provided in `...'. */
static tree
-build_libcall_decl (const char *name, libcall_type return_type,
+build_libcall_decl (const char *name, d_libcall_type return_type,
int flags, int nparams, ...)
{
tree *args = XALLOCAVEC (tree, nparams);
@@ -226,7 +226,7 @@ build_libcall_decl (const char *name, libcall_type return_type,
for (int i = 0; i < nparams; i++)
{
- libcall_type ptype = (libcall_type) va_arg (ap, int);
+ d_libcall_type ptype = (d_libcall_type) va_arg (ap, int);
Type *type = get_libcall_type (ptype);
if (type == Type::tvoid)
diff --git a/gcc/data-streamer-in.c b/gcc/data-streamer-in.c
index 11ad084..d9742d5 100644
--- a/gcc/data-streamer-in.c
+++ b/gcc/data-streamer-in.c
@@ -175,6 +175,17 @@ streamer_read_hwi (class lto_input_block *ib)
}
}
+/* Read a poly_uint64 from IB. */
+
+poly_uint64
+streamer_read_poly_uint64 (class lto_input_block *ib)
+{
+ poly_uint64 res;
+ for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
+ res.coeffs[i] = streamer_read_uhwi (ib);
+ return res;
+}
+
/* Read gcov_type value from IB. */
gcov_type
diff --git a/gcc/data-streamer-out.c b/gcc/data-streamer-out.c
index d058efd..54d080e 100644
--- a/gcc/data-streamer-out.c
+++ b/gcc/data-streamer-out.c
@@ -220,6 +220,15 @@ streamer_write_hwi (struct output_block *ob, HOST_WIDE_INT work)
streamer_write_hwi_stream (ob->main_stream, work);
}
+/* Write a poly_uint64 value WORK to OB->main_stream. */
+
+void
+streamer_write_poly_uint64 (struct output_block *ob, poly_uint64 work)
+{
+ for (int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
+ streamer_write_uhwi_stream (ob->main_stream, work.coeffs[i]);
+}
+
/* Write a gcov counter value WORK to OB->main_stream. */
void
diff --git a/gcc/data-streamer.h b/gcc/data-streamer.h
index c8bfd9a..c1b1501 100644
--- a/gcc/data-streamer.h
+++ b/gcc/data-streamer.h
@@ -53,6 +53,7 @@ HOST_WIDE_INT bp_unpack_var_len_int (struct bitpack_d *);
void streamer_write_zero (struct output_block *);
void streamer_write_uhwi (struct output_block *, unsigned HOST_WIDE_INT);
void streamer_write_hwi (struct output_block *, HOST_WIDE_INT);
+void streamer_write_poly_uint64 (struct output_block *, poly_uint64);
void streamer_write_gcov_count (struct output_block *, gcov_type);
void streamer_write_string (struct output_block *, struct lto_output_stream *,
const char *, bool);
@@ -82,6 +83,7 @@ const char *bp_unpack_indexed_string (class data_in *, struct bitpack_d *,
const char *bp_unpack_string (class data_in *, struct bitpack_d *);
unsigned HOST_WIDE_INT streamer_read_uhwi (class lto_input_block *);
HOST_WIDE_INT streamer_read_hwi (class lto_input_block *);
+poly_uint64 streamer_read_poly_uint64 (class lto_input_block *);
gcov_type streamer_read_gcov_count (class lto_input_block *);
wide_int streamer_read_wide_int (class lto_input_block *);
widest_int streamer_read_widest_int (class lto_input_block *);
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 4761b43..96b6fa3 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see
#include "edit-context.h"
#include "selftest.h"
#include "selftest-diagnostic.h"
+#include "opts.h"
#ifdef HAVE_TERMIOS_H
# include <termios.h>
@@ -696,6 +697,7 @@ diagnostic_classify_diagnostic (diagnostic_context *context,
if (old_kind == DK_UNSPECIFIED)
{
old_kind = !context->option_enabled (option_index,
+ context->lang_mask,
context->option_state)
? DK_IGNORED : (context->warning_as_error_requested
? DK_ERROR : DK_WARNING);
@@ -957,6 +959,7 @@ diagnostic_report_diagnostic (diagnostic_context *context,
/* This tests if the user provided the appropriate -Wfoo or
-Wno-foo option. */
if (! context->option_enabled (diagnostic->option_index,
+ context->lang_mask,
context->option_state))
return false;
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 46c3b50..530acb4 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -180,7 +180,7 @@ struct diagnostic_context
/* Client hook to say whether the option controlling a diagnostic is
enabled. Returns nonzero if enabled, zero if disabled. */
- int (*option_enabled) (int, void *);
+ int (*option_enabled) (int, unsigned, void *);
/* Client information to pass as second argument to
option_enabled. */
@@ -206,6 +206,9 @@ struct diagnostic_context
int lock;
+ /* A copy of lang_hooks.option_lang_mask (). */
+ unsigned lang_mask;
+
bool inhibit_notes_p;
/* When printing source code, should the characters at carets and ranges
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 14b232b..2ba9b74 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -6719,6 +6719,33 @@ attributes.
The following attributes are supported on most targets.
@table @code
+
+@item alias ("@var{target}")
+@cindex @code{alias} variable attribute
+The @code{alias} variable attribute causes the declaration to be emitted
+as an alias for another symbol known as an @dfn{alias target}. Except
+for top-level qualifiers the alias target must have the same type as
+the alias. For instance, the following
+
+@smallexample
+int var_target;
+extern int __attribute__ ((alias ("var_target"))) var_alias;
+@end smallexample
+
+@noindent
+defines @code{var_alias} to be an alias for the @code{var_target} variable.
+
+It is an error if the alias target is not defined in the same translation
+unit as the alias.
+
+Note that in the absence of the attribute GCC assumes that distinct
+declarations with external linkage denote distinct objects. Using both
+the alias and the alias target to access the same object is undefined
+in a translation unit without a declaration of the alias with the attribute.
+
+This attribute requires assembler and object file support, and may not be
+available on all targets.
+
@cindex @code{aligned} variable attribute
@item aligned
@itemx aligned (@var{alignment})
@@ -7129,6 +7156,14 @@ The @code{visibility} attribute is described in
The @code{weak} attribute is described in
@ref{Common Function Attributes}.
+@item noinit
+@cindex @code{noinit} variable attribute
+Any data with the @code{noinit} attribute will not be initialized by
+the C runtime startup code, or the program loader. Not initializing
+data in this way can reduce program startup times. This attribute is
+specific to ELF targets and relies on the linker to place such data in
+the right location
+
@end table
@node ARC Variable Attributes
@@ -16245,10 +16280,10 @@ v8i16 __builtin_msa_insve_h (v8i16, imm0_7, v8i16);
v4i32 __builtin_msa_insve_w (v4i32, imm0_3, v4i32);
v2i64 __builtin_msa_insve_d (v2i64, imm0_1, v2i64);
-v16i8 __builtin_msa_ld_b (void *, imm_n512_511);
-v8i16 __builtin_msa_ld_h (void *, imm_n1024_1022);
-v4i32 __builtin_msa_ld_w (void *, imm_n2048_2044);
-v2i64 __builtin_msa_ld_d (void *, imm_n4096_4088);
+v16i8 __builtin_msa_ld_b (const void *, imm_n512_511);
+v8i16 __builtin_msa_ld_h (const void *, imm_n1024_1022);
+v4i32 __builtin_msa_ld_w (const void *, imm_n2048_2044);
+v2i64 __builtin_msa_ld_d (const void *, imm_n4096_4088);
v16i8 __builtin_msa_ldi_b (imm_n512_511);
v8i16 __builtin_msa_ldi_h (imm_n512_511);
diff --git a/gcc/doc/include/gpl_v3.texi b/gcc/doc/include/gpl_v3.texi
index 3180677..86d8190 100644
--- a/gcc/doc/include/gpl_v3.texi
+++ b/gcc/doc/include/gpl_v3.texi
@@ -729,5 +729,5 @@ program into proprietary programs. If your program is a subroutine
library, you may consider it more useful to permit linking proprietary
applications with the library. If this is what you want to do, use
the GNU Lesser General Public License instead of this License. But
-first, please read @url{http://www.gnu.org/philosophy/why-not-lgpl.html}.
+first, please read @url{https://www.gnu.org/licenses/why-not-lgpl.html}.
@c man end
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 2598713..df6fefd 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -442,10 +442,7 @@ Necessary when modifying @command{gperf} input files, e.g.@:
@itemx Tcl
Necessary to run the GCC testsuite; see the section on testing for
-details. Tcl 8.6 has a known regression in RE pattern handling that
-make parts of the testsuite fail. See
-@uref{http://core.tcl.tk/tcl/tktview/267b7e2334ee2e9de34c4b00d6e72e2f1997085f}
-for more information. This bug has been fixed in 8.6.1.
+details.
@item autogen version 5.5.4 (or later) and
@itemx guile version 1.4.1 (or later)
@@ -3587,7 +3584,7 @@ See ``Blackfin Options'' in the main manual
@end ifhtml
More information, and a version of binutils with support for this processor,
-is available at @uref{https://blackfin.uclinux.org}
+are available at @uref{https://sourceforge.net/projects/adi-toolchain/}.
@html
<hr />
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 77a2d56..ca11179 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -230,7 +230,8 @@ in the following sections.
-fvisibility-inlines-hidden @gol
-fvisibility-ms-compat @gol
-fext-numeric-literals @gol
--Wabi=@var{n} -Wabi-tag -Wconversion-null -Wctor-dtor-privacy @gol
+-Wabi=@var{n} -Wabi-tag -Wcomma-subscript -Wconversion-null @gol
+-Wctor-dtor-privacy @gol
-Wdelete-non-virtual-dtor -Wdeprecated-copy -Wdeprecated-copy-dtor @gol
-Wliteral-suffix @gol
-Wmultiple-inheritance -Wno-init-list-lifetime @gol
@@ -3037,6 +3038,24 @@ Warn when a type with an ABI tag is used in a context that does not
have that ABI tag. See @ref{C++ Attributes} for more information
about ABI tags.
+@item -Wcomma-subscript @r{(C++ and Objective-C++ only)}
+@opindex Wcomma-subscript
+@opindex Wno-comma-subscript
+Warn about uses of a comma expression within a subscripting expression.
+This usage was deprecated in C++2a. However, a comma expression wrapped
+in @code{( )} is not deprecated. Example:
+
+@smallexample
+@group
+void f(int *a, int b, int c) @{
+ a[b,c]; // deprecated
+ a[(b,c)]; // OK
+@}
+@end group
+@end smallexample
+
+Enabled by default with @option{-std=c++2a}.
+
@item -Wctor-dtor-privacy @r{(C++ and Objective-C++ only)}
@opindex Wctor-dtor-privacy
@opindex Wno-ctor-dtor-privacy
@@ -8423,10 +8442,10 @@ no effect. Otherwise @option{-Og} enables all @option{-O1}
optimization flags except for those that may interfere with debugging:
@gccoptlist{-fbranch-count-reg -fdelayed-branch @gol
--fif-conversion -fif-conversion2 @gol
+-fdse -fif-conversion -fif-conversion2 @gol
-finline-functions-called-once @gol
-fmove-loop-invariants -fssa-phiopt @gol
--ftree-bit-ccp -ftree-pta -ftree-sra}
+-ftree-bit-ccp -ftree-dse -ftree-pta -ftree-sra}
@end table
@@ -10396,14 +10415,19 @@ If you specify the optional @var{n}, the optimization and code
generation done at link time is executed in parallel using @var{n}
parallel jobs by utilizing an installed @command{make} program. The
environment variable @env{MAKE} may be used to override the program
-used. The default value for @var{n} is 1.
+used.
You can also specify @option{-flto=jobserver} to use GNU make's
job server mode to determine the number of parallel jobs. This
is useful when the Makefile calling GCC is already executing in parallel.
You must prepend a @samp{+} to the command recipe in the parent Makefile
for this to work. This option likely only works if @env{MAKE} is
-GNU make.
+GNU make. Even without the option value, GCC tries to automatically
+detect a running GNU make's job server.
+
+Use @option{-flto=auto} to use GNU make's job server, if available,
+or otherwise fall back to autodetection of the number of CPU threads
+present in your system.
@item -flto-partition=@var{alg}
@opindex flto-partition
@@ -11442,13 +11466,38 @@ for vectorizer. Value -1 means no limit.
The maximum number of iterations of a loop the brute-force algorithm
for analysis of the number of iterations of the loop tries to evaluate.
+@item hot-bb-count-fraction
+The denominator n of fraction 1/n of the maximal execution count of a
+basic block in the entire program that a basic block needs to at least
+have in order to be considered hot. The default is 10000, which means
+that a basic block is considered hot if its execution count is greater
+than 1/10000 of the maximal execution count. 0 means that it is never
+considered hot. Used in non-LTO mode.
+
@item hot-bb-count-ws-permille
-A basic block profile count is considered hot if it contributes to
-the given permillage (i.e.@: 0...1000) of the entire profiled execution.
+The number of most executed permilles, ranging from 0 to 1000, of the
+profiled execution of the entire program to which the execution count
+of a basic block must be part of in order to be considered hot. The
+default is 990, which means that a basic block is considered hot if
+its execution count contributes to the upper 990 permilles, or 99.0%,
+of the profiled execution of the entire program. 0 means that it is
+never considered hot. Used in LTO mode.
@item hot-bb-frequency-fraction
-Select fraction of the entry block frequency of executions of basic block in
-function given basic block needs to have to be considered hot.
+The denominator n of fraction 1/n of the execution frequency of the
+entry block of a function that a basic block of this function needs
+to at least have in order to be considered hot. The default is 1000,
+which means that a basic block is considered hot in a function if it
+is executed more frequently than 1/1000 of the frequency of the entry
+block of the function. 0 means that it is never considered hot.
+
+@item unlikely-bb-count-fraction
+The denominator n of fraction 1/n of the number of profiled runs of
+the entire program below which the execution count of a basic block
+must be in order for the basic block to be considered unlikely executed.
+The default is 20, which means that a basic block is considered unlikely
+executed if it is executed in fewer than 1/20, or 5%, of the runs of
+the program. 0 means that it is always considered unlikely executed.
@item max-predicted-iterations
The maximum number of loop iterations we predict statically. This is useful
@@ -12129,11 +12178,6 @@ A threshold on the average loop count considered by the swing modulo scheduler.
The number of cycles the swing modulo scheduler considers when checking
conflicts using DFA.
-@item hot-bb-count-fraction
-Select fraction of the maximal count of repetitions of basic block
-in program given basic block needs
-to have to be considered hot (used in non-LTO mode)
-
@item max-inline-insns-recursive-auto
The maximum number of instructions non-inline function
can grow to via recursive inlining.
@@ -12171,10 +12215,6 @@ Maximum number of arrays per scop.
@item max-vartrack-reverse-op-size
Max. size of loc list for which reverse ops should be added.
-@item unlikely-bb-count-fraction
-The minimum fraction of profile runs a given basic block execution count
-must be not to be considered unlikely.
-
@item tracer-dynamic-coverage-feedback
The percentage of function, weighted by execution frequency,
that must be covered by trace formation.
@@ -16094,6 +16134,8 @@ Enable SVE2 aes instructions. This also enables SVE2 instructions.
@item sve2-sha3
Enable SVE2 sha3 instructions. This also enables SVE2 instructions.
@option{-march=armv8.5-a}.
+@item tme
+Enable the Transactional Memory Extension.
@end table
@@ -23002,7 +23044,12 @@ command line. The script's name is the name of the MCU with
command line defines the C preprocessor symbol @code{__XXX__} and
cause the linker to search for a script called @file{xxx.ld}.
-This option is also passed on to the assembler.
+The ISA and hardware multiply supported for the different MCUs is hard-coded
+into GCC. However, an external @samp{devices.csv} file can be used to
+extend device support beyond those that have been hard-coded.
+
+GCC searches for the @samp{devices.csv} file on the paths specified
+with the @code{-I} and @code{-L} options.
@item -mwarn-mcu
@itemx -mno-warn-mcu
@@ -23091,6 +23138,13 @@ the named silicon errata.
This option passes on a request to the assembler to enable warning
messages when a silicon errata might need to be applied.
+@item -mwarn-devices-csv
+@itemx -mno-warn-devices-csv
+@opindex mwarn-devices-csv
+@opindex mno-warn-devices-csv
+Warn if @samp{devices.csv} is not found or there are problem parsing it
+(default: on).
+
@end table
@node NDS32 Options
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index af216da..7751984 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -1748,6 +1748,12 @@ The stack pointer register (@code{SP})
@item w
Floating point register, Advanced SIMD vector register or SVE vector register
+@item x
+Like @code{w}, but restricted to registers 0 to 15 inclusive.
+
+@item y
+Like @code{w}, but restricted to registers 0 to 7 inclusive.
+
@item Upl
One of the low eight SVE predicate registers (@code{P0} to @code{P7})
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 6a66515..f9fcd09 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -2302,6 +2302,9 @@ Target uses natural alignment (aligned to type size) for types of
Target uses natural alignment (aligned to type size) for types of
64 bits or less.
+@item noinit
+Target supports the @code{noinit} variable attribute.
+
@item nonpic
Target does not generate PIC by default.
@@ -2669,6 +2672,91 @@ assembly output.
@item scan-not-hidden @var{symbol} [@{ target/xfail @var{selector} @}]
Passes if @var{symbol} is not defined as a hidden symbol in the test's
assembly output.
+
+@item check-function-bodies @var{prefix} @var{terminator} [@var{option}]
+Looks through the source file for comments that give the expected assembly
+output for selected functions. Each line of expected output starts with the
+prefix string @var{prefix} and the expected output for a function as a whole
+is followed by a line that starts with the string @var{terminator}.
+Specifying an empty terminator is equivalent to specifying @samp{"*/"}.
+
+If @var{option} is specified, the test only applies to command lines
+that contain @var{option}. This can be useful if a source file is compiled
+both with and without optimization, since it is rarely useful to check the
+assembly output for unoptimized code.
+
+The first line of the expected output for a function @var{fn} has the form:
+
+@smallexample
+@var{prefix} @var{fn}: [@{ target/xfail @var{selector} @}]
+@end smallexample
+
+Subsequent lines of the expected output also start with @var{prefix}.
+In both cases, whitespace after @var{prefix} is not significant.
+
+The test discards assembly directives such as @code{.cfi_startproc}
+and local label definitions such as @code{.LFB0} from the compiler's
+assembly output. It then matches the result against the expected
+output for a function as a single regular expression. This means that
+later lines can use backslashes to refer back to @samp{(@dots{})}
+captures on earlier lines. For example:
+
+@smallexample
+/* @{ dg-final @{ check-function-bodies "**" "" "-DCHECK_ASM" @} @} */
+@dots{}
+/*
+** add_w0_s8_m:
+** mov (z[0-9]+\.b), w0
+** add z0\.b, p0/m, z0\.b, \1
+** ret
+*/
+svint8_t add_w0_s8_m (@dots{}) @{ @dots{} @}
+@dots{}
+/*
+** add_b0_s8_m:
+** mov (z[0-9]+\.b), b0
+** add z1\.b, p0/m, z1\.b, \1
+** ret
+*/
+svint8_t add_b0_s8_m (@dots{}) @{ @dots{} @}
+@end smallexample
+
+checks whether the implementations of @code{add_w0_s8_m} and
+@code{add_b0_s8_m} match the regular expressions given. The test only
+runs when @samp{-DCHECK_ASM} is passed on the command line.
+
+It is possible to create non-capturing multi-line regular expression
+groups of the form @samp{(@var{a}|@var{b}|@dots{})} by putting the
+@samp{(}, @samp{|} and @samp{)} on separate lines (each still using
+@var{prefix}). For example:
+
+@smallexample
+/*
+** cmple_f16_tied:
+** (
+** fcmge p0\.h, p0/z, z1\.h, z0\.h
+** |
+** fcmle p0\.h, p0/z, z0\.h, z1\.h
+** )
+** ret
+*/
+svbool_t cmple_f16_tied (@dots{}) @{ @dots{} @}
+@end smallexample
+
+checks whether @code{cmple_f16_tied} is implemented by the
+@code{fcmge} instruction followed by @code{ret} or by the
+@code{fcmle} instruction followed by @code{ret}. The test is
+still a single regular rexpression.
+
+A line containing just:
+
+@smallexample
+@var{prefix} ...
+@end smallexample
+
+stands for zero or more unmatched lines; the whitespace after
+@var{prefix} is again not significant.
+
@end table
@subsubsection Scan optimization dump files
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 8e5b01c..f05b311 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -5314,12 +5314,6 @@ This hook is used by expand pass to emit insn to store @var{bounds}
returned by function call into @var{slot}.
@end deftypefn
-@deftypefn {Target Hook} void TARGET_SETUP_INCOMING_VARARG_BOUNDS (cumulative_args_t @var{args_so_far}, machine_mode @var{mode}, tree @var{type}, int *@var{pretend_args_size}, int @var{second_time})
-Use it to store bounds for anonymous register arguments stored
-into the stack. Arguments meaning is similar to
-@code{TARGET_SETUP_INCOMING_VARARGS}.
-@end deftypefn
-
@node Trampolines
@section Support for Nested Functions
@cindex support for nested functions
@@ -5591,12 +5585,12 @@ macro, a reasonable default is used.
@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FUNCTION (enum function_class @var{fn_class})
This hook determines whether a function from a class of functions
-@var{fn_class} is present at the runtime.
+@var{fn_class} is present in the target C library.
@end deftypefn
@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FAST_FUNCTION (int @var{fcode})
This hook determines whether a function from a class of functions
-@var{fn_class} has a fast implementation.
+@code{(enum function_class)}@var{fcode} has a fast implementation.
@end deftypefn
@defmac NEXT_OBJC_RUNTIME
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index b4d57b8..98e7100 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3785,8 +3785,6 @@ These machine description macros help implement varargs:
@hook TARGET_STORE_RETURNED_BOUNDS
-@hook TARGET_SETUP_INCOMING_VARARG_BOUNDS
-
@node Trampolines
@section Support for Nested Functions
@cindex support for nested functions
diff --git a/gcc/doc/ux.texi b/gcc/doc/ux.texi
index 1f695ea..caa690b 100644
--- a/gcc/doc/ux.texi
+++ b/gcc/doc/ux.texi
@@ -9,7 +9,7 @@
@cindex guidelines, user experience
To borrow a slogan from
- @uref{https://elm-lang.org/blog/compilers-as-assistants, Elm},
+@uref{https://elm-lang.org/news/compilers-as-assistants, Elm},
@quotation
@strong{Compilers should be assistants, not adversaries.} A compiler should
diff --git a/gcc/domwalk.c b/gcc/domwalk.c
index 8c0fdec..42c5127 100644
--- a/gcc/domwalk.c
+++ b/gcc/domwalk.c
@@ -128,14 +128,12 @@ along with GCC; see the file COPYING3. If not see
which is currently an abstraction over walking tree statements. Thus
the dominator walker is currently only useful for trees. */
-/* Reverse postorder index of each basic block. */
-static int *bb_postorder;
-
static int
-cmp_bb_postorder (const void *a, const void *b)
+cmp_bb_postorder (const void *a, const void *b, void *data)
{
basic_block bb1 = *(const basic_block *)(a);
basic_block bb2 = *(const basic_block *)(b);
+ int *bb_postorder = (int *)data;
/* Place higher completion number first (pop off lower number first). */
return bb_postorder[bb2->index] - bb_postorder[bb1->index];
}
@@ -144,7 +142,7 @@ cmp_bb_postorder (const void *a, const void *b)
i.e. by descending number in BB_POSTORDER array. */
static void
-sort_bbs_postorder (basic_block *bbs, int n)
+sort_bbs_postorder (basic_block *bbs, int n, int *bb_postorder)
{
if (__builtin_expect (n == 2, true))
{
@@ -166,7 +164,7 @@ sort_bbs_postorder (basic_block *bbs, int n)
bbs[0] = bb0, bbs[1] = bb1, bbs[2] = bb2;
}
else
- qsort (bbs, n, sizeof *bbs, cmp_bb_postorder);
+ gcc_sort_r (bbs, n, sizeof *bbs, cmp_bb_postorder, bb_postorder);
}
/* Set EDGE_EXECUTABLE on every edge within FN's CFG. */
@@ -294,7 +292,6 @@ dom_walker::walk (basic_block bb)
basic_block *worklist = XNEWVEC (basic_block,
n_basic_blocks_for_fn (cfun) * 2);
int sp = 0;
- bb_postorder = m_bb_to_rpo;
while (true)
{
@@ -339,7 +336,8 @@ dom_walker::walk (basic_block bb)
if (sp - saved_sp > 1
&& m_dom_direction == CDI_DOMINATORS
&& m_bb_to_rpo)
- sort_bbs_postorder (&worklist[saved_sp], sp - saved_sp);
+ sort_bbs_postorder (&worklist[saved_sp], sp - saved_sp,
+ m_bb_to_rpo);
}
}
/* NULL is used to mark pop operations in the recursion stack. */
@@ -360,6 +358,5 @@ dom_walker::walk (basic_block bb)
else
break;
}
- bb_postorder = NULL;
free (worklist);
}
diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index d6aed35..95ba0f7 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -2445,6 +2445,13 @@ create_trace_edges (rtx_insn *insn)
rtx_insn *lab = as_a <rtx_insn *> (XEXP (RTVEC_ELT (vec, i), 0));
maybe_record_trace_start (lab, insn);
}
+
+ /* Handle casesi dispatch insns. */
+ if ((tmp = tablejump_casesi_pattern (insn)) != NULL_RTX)
+ {
+ rtx_insn * lab = label_ref_label (XEXP (SET_SRC (tmp), 2));
+ maybe_record_trace_start (lab, insn);
+ }
}
else if (computed_jump_p (insn))
{
diff --git a/gcc/fold-const-call.c b/gcc/fold-const-call.c
index 702c8b4..e21d8e11 100644
--- a/gcc/fold-const-call.c
+++ b/gcc/fold-const-call.c
@@ -691,6 +691,36 @@ fold_const_vec_convert (tree ret_type, tree arg)
/* Try to evaluate:
+ IFN_WHILE_ULT (ARG0, ARG1, (TYPE) { ... })
+
+ Return the value on success and null on failure. */
+
+static tree
+fold_while_ult (tree type, poly_uint64 arg0, poly_uint64 arg1)
+{
+ if (known_ge (arg0, arg1))
+ return build_zero_cst (type);
+
+ if (maybe_ge (arg0, arg1))
+ return NULL_TREE;
+
+ poly_uint64 diff = arg1 - arg0;
+ poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (type);
+ if (known_ge (diff, nelts))
+ return build_all_ones_cst (type);
+
+ unsigned HOST_WIDE_INT const_diff;
+ if (known_le (diff, nelts) && diff.is_constant (&const_diff))
+ {
+ tree minus_one = build_minus_one_cst (TREE_TYPE (type));
+ tree zero = build_zero_cst (TREE_TYPE (type));
+ return build_vector_a_then_b (type, const_diff, minus_one, zero);
+ }
+ return NULL_TREE;
+}
+
+/* Try to evaluate:
+
*RESULT = FN (*ARG)
in format FORMAT. Return true on success. */
@@ -1782,6 +1812,14 @@ fold_const_call (combined_fn fn, tree type, tree arg0, tree arg1, tree arg2)
}
return NULL_TREE;
+ case CFN_WHILE_ULT:
+ {
+ poly_uint64 parg0, parg1;
+ if (poly_int_tree_p (arg0, &parg0) && poly_int_tree_p (arg1, &parg1))
+ return fold_while_ult (type, parg0, parg1);
+ return NULL_TREE;
+ }
+
default:
return fold_const_call_1 (fn, type, arg0, arg1, arg2);
}
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 74544bf..8c711aba 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -115,11 +115,11 @@ static tree negate_expr (tree);
static tree associate_trees (location_t, tree, tree, enum tree_code, tree);
static enum comparison_code comparison_to_compcode (enum tree_code);
static enum tree_code compcode_to_comparison (enum comparison_code);
-static int twoval_comparison_p (tree, tree *, tree *);
+static bool twoval_comparison_p (tree, tree *, tree *);
static tree eval_subst (location_t, tree, tree, tree, tree, tree);
static tree optimize_bit_field_compare (location_t, enum tree_code,
tree, tree, tree);
-static int simple_operand_p (const_tree);
+static bool simple_operand_p (const_tree);
static bool simple_operand_p_2 (tree);
static tree range_binop (enum tree_code, tree, tree, int, tree, int);
static tree range_predecessor (tree);
@@ -2939,7 +2939,7 @@ combine_comparisons (location_t loc,
addresses with TREE_CONSTANT flag set so we know that &var == &var
even if var is volatile. */
-int
+bool
operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
{
/* When checking, verify at the outermost operand_equal_p call that
@@ -2958,10 +2958,10 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
hashval_t h1 = hstate1.end ();
gcc_assert (h0 == h1);
}
- return 1;
+ return true;
}
else
- return 0;
+ return false;
}
STRIP_ANY_LOCATION_WRAPPER (arg0);
@@ -2971,19 +2971,19 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
if (TREE_CODE (arg0) == ERROR_MARK || TREE_CODE (arg1) == ERROR_MARK
|| TREE_TYPE (arg0) == error_mark_node
|| TREE_TYPE (arg1) == error_mark_node)
- return 0;
+ return false;
/* Similar, if either does not have a type (like a template id),
they aren't equal. */
if (!TREE_TYPE (arg0) || !TREE_TYPE (arg1))
- return 0;
+ return false;
/* We cannot consider pointers to different address space equal. */
if (POINTER_TYPE_P (TREE_TYPE (arg0))
&& POINTER_TYPE_P (TREE_TYPE (arg1))
&& (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg0)))
!= TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg1)))))
- return 0;
+ return false;
/* Check equality of integer constants before bailing out due to
precision differences. */
@@ -3005,13 +3005,13 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
if (TYPE_UNSIGNED (TREE_TYPE (arg0)) != TYPE_UNSIGNED (TREE_TYPE (arg1))
|| POINTER_TYPE_P (TREE_TYPE (arg0))
!= POINTER_TYPE_P (TREE_TYPE (arg1)))
- return 0;
+ return false;
/* If both types don't have the same precision, then it is not safe
to strip NOPs. */
if (element_precision (TREE_TYPE (arg0))
!= element_precision (TREE_TYPE (arg1)))
- return 0;
+ return false;
STRIP_NOPS (arg0);
STRIP_NOPS (arg1);
@@ -3058,17 +3058,17 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
&& TREE_CODE (TREE_OPERAND (arg0, 0)) == ADDR_EXPR
&& TREE_OPERAND (TREE_OPERAND (arg0, 0), 0) == arg1
&& integer_zerop (TREE_OPERAND (arg0, 1)))
- return 1;
+ return true;
else if (TREE_CODE (arg1) == MEM_REF
&& DECL_P (arg0)
&& TREE_CODE (TREE_OPERAND (arg1, 0)) == ADDR_EXPR
&& TREE_OPERAND (TREE_OPERAND (arg1, 0), 0) == arg0
&& integer_zerop (TREE_OPERAND (arg1, 1)))
- return 1;
- return 0;
+ return true;
+ return false;
}
else
- return 0;
+ return false;
}
/* When not checking adddresses, this is needed for conversions and for
@@ -3077,7 +3077,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
|| TREE_CODE (TREE_TYPE (arg1)) == ERROR_MARK
|| (TYPE_MODE (TREE_TYPE (arg0)) != TYPE_MODE (TREE_TYPE (arg1))
&& !(flags & OEP_ADDRESS_OF)))
- return 0;
+ return false;
/* If ARG0 and ARG1 are the same SAVE_EXPR, they are necessarily equal.
We don't care about side effects in that case because the SAVE_EXPR
@@ -3092,7 +3092,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
&& (TREE_CODE (arg0) == SAVE_EXPR
|| (flags & OEP_MATCH_SIDE_EFFECTS)
|| (! TREE_SIDE_EFFECTS (arg0) && ! TREE_SIDE_EFFECTS (arg1))))
- return 1;
+ return true;
/* Next handle constant cases, those for which we can return 1 even
if ONLY_CONST is set. */
@@ -3108,7 +3108,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
case REAL_CST:
if (real_identical (&TREE_REAL_CST (arg0), &TREE_REAL_CST (arg1)))
- return 1;
+ return true;
if (!HONOR_SIGNED_ZEROS (arg0))
@@ -3116,26 +3116,26 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
/* If we do not distinguish between signed and unsigned zero,
consider them equal. */
if (real_zerop (arg0) && real_zerop (arg1))
- return 1;
+ return true;
}
- return 0;
+ return false;
case VECTOR_CST:
{
if (VECTOR_CST_LOG2_NPATTERNS (arg0)
!= VECTOR_CST_LOG2_NPATTERNS (arg1))
- return 0;
+ return false;
if (VECTOR_CST_NELTS_PER_PATTERN (arg0)
!= VECTOR_CST_NELTS_PER_PATTERN (arg1))
- return 0;
+ return false;
unsigned int count = vector_cst_encoded_nelts (arg0);
for (unsigned int i = 0; i < count; ++i)
if (!operand_equal_p (VECTOR_CST_ENCODED_ELT (arg0, i),
VECTOR_CST_ENCODED_ELT (arg1, i), flags))
- return 0;
- return 1;
+ return false;
+ return true;
}
case COMPLEX_CST:
@@ -3164,7 +3164,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
}
if (flags & OEP_ONLY_CONST)
- return 0;
+ return false;
/* Define macros to test an operand from arg0 and arg1 for equality and a
variant that allows null and views null as being different from any
@@ -3187,7 +3187,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
case FIX_TRUNC_EXPR:
if (TYPE_UNSIGNED (TREE_TYPE (arg0))
!= TYPE_UNSIGNED (TREE_TYPE (arg1)))
- return 0;
+ return false;
break;
default:
break;
@@ -3199,7 +3199,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
case tcc_comparison:
case tcc_binary:
if (OP_SAME (0) && OP_SAME (1))
- return 1;
+ return true;
/* For commutative ops, allow the other order. */
return (commutative_tree_code (TREE_CODE (arg0))
@@ -3215,7 +3215,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
if ((flags & OEP_MATCH_SIDE_EFFECTS) == 0
&& (TREE_SIDE_EFFECTS (arg0)
|| TREE_SIDE_EFFECTS (arg1)))
- return 0;
+ return false;
switch (TREE_CODE (arg0))
{
@@ -3224,11 +3224,11 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
{
if (TYPE_ALIGN (TREE_TYPE (arg0))
!= TYPE_ALIGN (TREE_TYPE (arg1)))
- return 0;
+ return false;
/* Verify that the access types are compatible. */
if (TYPE_MAIN_VARIANT (TREE_TYPE (arg0))
!= TYPE_MAIN_VARIANT (TREE_TYPE (arg1)))
- return 0;
+ return false;
}
flags &= ~OEP_ADDRESS_OF;
return OP_SAME (0);
@@ -3238,7 +3238,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
if (!operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)),
TYPE_SIZE (TREE_TYPE (arg1)),
flags & ~OEP_ADDRESS_OF))
- return 0;
+ return false;
/* Fallthru. */
case REALPART_EXPR:
@@ -3256,10 +3256,10 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
|| !operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)),
TYPE_SIZE (TREE_TYPE (arg1)),
flags)))
- return 0;
+ return false;
/* Verify that access happens in similar types. */
if (!types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1)))
- return 0;
+ return false;
/* Verify that accesses are TBAA compatible. */
if (!alias_ptr_types_compatible_p
(TREE_TYPE (TREE_OPERAND (arg0, 1)),
@@ -3268,11 +3268,11 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
!= MR_DEPENDENCE_CLIQUE (arg1))
|| (MR_DEPENDENCE_BASE (arg0)
!= MR_DEPENDENCE_BASE (arg1)))
- return 0;
+ return false;
/* Verify that alignment is compatible. */
if (TYPE_ALIGN (TREE_TYPE (arg0))
!= TYPE_ALIGN (TREE_TYPE (arg1)))
- return 0;
+ return false;
}
flags &= ~OEP_ADDRESS_OF;
return (OP_SAME (0) && OP_SAME (1)
@@ -3285,7 +3285,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
case ARRAY_REF:
case ARRAY_RANGE_REF:
if (!OP_SAME (0))
- return 0;
+ return false;
flags &= ~OEP_ADDRESS_OF;
/* Compare the array index by value if it is constant first as we
may have different types but same value here. */
@@ -3313,18 +3313,18 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
may be NULL when we're called to compare MEM_EXPRs. */
if (!OP_SAME_WITH_NULL (0)
|| !OP_SAME (1))
- return 0;
+ return false;
flags &= ~OEP_ADDRESS_OF;
return OP_SAME_WITH_NULL (2);
case BIT_FIELD_REF:
if (!OP_SAME (0))
- return 0;
+ return false;
flags &= ~OEP_ADDRESS_OF;
return OP_SAME (1) && OP_SAME (2);
default:
- return 0;
+ return false;
}
case tcc_expression:
@@ -3347,7 +3347,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
case WIDEN_MULT_PLUS_EXPR:
case WIDEN_MULT_MINUS_EXPR:
if (!OP_SAME (2))
- return 0;
+ return false;
/* The multiplcation operands are commutative. */
/* FALLTHRU */
@@ -3355,7 +3355,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR:
if (OP_SAME (0) && OP_SAME (1))
- return 1;
+ return true;
/* Otherwise take into account this is a commutative operation. */
return (operand_equal_p (TREE_OPERAND (arg0, 0),
@@ -3365,7 +3365,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
case COND_EXPR:
if (! OP_SAME (1) || ! OP_SAME_WITH_NULL (2))
- return 0;
+ return false;
flags &= ~OEP_ADDRESS_OF;
return OP_SAME (0);
@@ -3392,17 +3392,17 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
case POSTINCREMENT_EXPR:
if (flags & OEP_LEXICOGRAPHIC)
return OP_SAME (0) && OP_SAME (1);
- return 0;
+ return false;
case CLEANUP_POINT_EXPR:
case EXPR_STMT:
case SAVE_EXPR:
if (flags & OEP_LEXICOGRAPHIC)
return OP_SAME (0);
- return 0;
+ return false;
default:
- return 0;
+ return false;
}
case tcc_vl_exp:
@@ -3413,13 +3413,13 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
!= (CALL_EXPR_FN (arg1) == NULL_TREE))
/* If not both CALL_EXPRs are either internal or normal function
functions, then they are not equal. */
- return 0;
+ return false;
else if (CALL_EXPR_FN (arg0) == NULL_TREE)
{
/* If the CALL_EXPRs call different internal functions, then they
are not equal. */
if (CALL_EXPR_IFN (arg0) != CALL_EXPR_IFN (arg1))
- return 0;
+ return false;
}
else
{
@@ -3427,7 +3427,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
equal. */
if (! operand_equal_p (CALL_EXPR_FN (arg0), CALL_EXPR_FN (arg1),
flags))
- return 0;
+ return false;
}
/* FIXME: We could skip this test for OEP_MATCH_SIDE_EFFECTS. */
@@ -3438,7 +3438,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
else
cef &= ECF_CONST;
if (!cef && !(flags & OEP_LEXICOGRAPHIC))
- return 0;
+ return false;
}
/* Now see if all the arguments are the same. */
@@ -3451,14 +3451,14 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
a0 = next_const_call_expr_arg (&iter0),
a1 = next_const_call_expr_arg (&iter1))
if (! operand_equal_p (a0, a1, flags))
- return 0;
+ return false;
/* If we get here and both argument lists are exhausted
then the CALL_EXPRs are equal. */
return ! (a0 || a1);
}
default:
- return 0;
+ return false;
}
case tcc_declaration:
@@ -3466,7 +3466,8 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
return (TREE_CODE (arg0) == FUNCTION_DECL
&& fndecl_built_in_p (arg0) && fndecl_built_in_p (arg1)
&& DECL_BUILT_IN_CLASS (arg0) == DECL_BUILT_IN_CLASS (arg1)
- && DECL_FUNCTION_CODE (arg0) == DECL_FUNCTION_CODE (arg1));
+ && (DECL_UNCHECKED_FUNCTION_CODE (arg0)
+ == DECL_UNCHECKED_FUNCTION_CODE (arg1)));
case tcc_exceptional:
if (TREE_CODE (arg0) == CONSTRUCTOR)
@@ -3480,7 +3481,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
constants). */
if (!VECTOR_TYPE_P (TREE_TYPE (arg0))
|| !VECTOR_TYPE_P (TREE_TYPE (arg1)))
- return 0;
+ return false;
/* Be sure that vectors constructed have the same representation.
We only tested element precision and modes to match.
@@ -3488,14 +3489,14 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
parts match. */
if (maybe_ne (TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg0)),
TYPE_VECTOR_SUBPARTS (TREE_TYPE (arg1))))
- return 0;
+ return false;
vec<constructor_elt, va_gc> *v0 = CONSTRUCTOR_ELTS (arg0);
vec<constructor_elt, va_gc> *v1 = CONSTRUCTOR_ELTS (arg1);
unsigned int len = vec_safe_length (v0);
if (len != vec_safe_length (v1))
- return 0;
+ return false;
for (unsigned int i = 0; i < len; i++)
{
@@ -3512,9 +3513,9 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
|| (c1->index
&& (TREE_CODE (c1->index) != INTEGER_CST
|| compare_tree_int (c1->index, i))))
- return 0;
+ return false;
}
- return 1;
+ return true;
}
else if (TREE_CODE (arg0) == STATEMENT_LIST
&& (flags & OEP_LEXICOGRAPHIC))
@@ -3528,16 +3529,16 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
{
/* The lists don't have the same number of statements. */
if (tsi_end_p (tsi1) ^ tsi_end_p (tsi2))
- return 0;
+ return false;
if (tsi_end_p (tsi1) && tsi_end_p (tsi2))
- return 1;
+ return true;
if (!operand_equal_p (tsi_stmt (tsi1), tsi_stmt (tsi2),
flags & (OEP_LEXICOGRAPHIC
| OEP_NO_HASH_CHECK)))
- return 0;
+ return false;
}
}
- return 0;
+ return false;
case tcc_statement:
switch (TREE_CODE (arg0))
@@ -3545,17 +3546,17 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
case RETURN_EXPR:
if (flags & OEP_LEXICOGRAPHIC)
return OP_SAME_WITH_NULL (0);
- return 0;
+ return false;
case DEBUG_BEGIN_STMT:
if (flags & OEP_LEXICOGRAPHIC)
- return 1;
- return 0;
+ return true;
+ return false;
default:
- return 0;
+ return false;
}
default:
- return 0;
+ return false;
}
#undef OP_SAME
@@ -3606,7 +3607,7 @@ operand_equal_for_comparison_p (tree arg0, tree arg1)
If this is true, return 1. Otherwise, return zero. */
-static int
+static bool
twoval_comparison_p (tree arg, tree *cval1, tree *cval2)
{
enum tree_code code = TREE_CODE (arg);
@@ -3630,14 +3631,14 @@ twoval_comparison_p (tree arg, tree *cval1, tree *cval2)
&& twoval_comparison_p (TREE_OPERAND (arg, 1), cval1, cval2));
case tcc_constant:
- return 1;
+ return true;
case tcc_expression:
if (code == COND_EXPR)
return (twoval_comparison_p (TREE_OPERAND (arg, 0), cval1, cval2)
&& twoval_comparison_p (TREE_OPERAND (arg, 1), cval1, cval2)
&& twoval_comparison_p (TREE_OPERAND (arg, 2), cval1, cval2));
- return 0;
+ return false;
case tcc_comparison:
/* First see if we can handle the first operand, then the second. For
@@ -3648,7 +3649,7 @@ twoval_comparison_p (tree arg, tree *cval1, tree *cval2)
if (operand_equal_p (TREE_OPERAND (arg, 0),
TREE_OPERAND (arg, 1), 0))
- return 0;
+ return false;
if (*cval1 == 0)
*cval1 = TREE_OPERAND (arg, 0);
@@ -3659,7 +3660,7 @@ twoval_comparison_p (tree arg, tree *cval1, tree *cval2)
else if (operand_equal_p (*cval2, TREE_OPERAND (arg, 0), 0))
;
else
- return 0;
+ return false;
if (operand_equal_p (*cval1, TREE_OPERAND (arg, 1), 0))
;
@@ -3668,12 +3669,12 @@ twoval_comparison_p (tree arg, tree *cval1, tree *cval2)
else if (operand_equal_p (*cval2, TREE_OPERAND (arg, 1), 0))
;
else
- return 0;
+ return false;
- return 1;
+ return true;
default:
- return 0;
+ return false;
}
}
@@ -4353,7 +4354,7 @@ decode_field_reference (location_t loc, tree *exp_, HOST_WIDE_INT *pbitsize,
/* Return nonzero if MASK represents a mask of SIZE ones in the low-order
bit positions and MASK is SIGNED. */
-static int
+static bool
all_ones_mask_p (const_tree mask, unsigned int size)
{
tree type = TREE_TYPE (mask);
@@ -4408,7 +4409,7 @@ sign_bit_p (tree exp, const_tree val)
/* Subroutine for fold_truth_andor_1: determine if an operand is simple enough
to be evaluated unconditionally. */
-static int
+static bool
simple_operand_p (const_tree exp)
{
/* Strip any conversions that don't change the machine mode. */
@@ -9250,7 +9251,7 @@ tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
tree fndecl = get_callee_fndecl (t);
if (!fndecl) return false;
if (flag_delete_null_pointer_checks && !flag_check_new
- && DECL_IS_OPERATOR_NEW (fndecl)
+ && DECL_IS_OPERATOR_NEW_P (fndecl)
&& !TREE_NOTHROW (fndecl))
return true;
if (flag_delete_null_pointer_checks
@@ -11850,6 +11851,7 @@ get_array_ctor_element_at_index (tree ctor, offset_int access_index,
unsigned *ctor_idx)
{
tree index_type = NULL_TREE;
+ signop index_sgn = UNSIGNED;
offset_int low_bound = 0;
if (TREE_CODE (TREE_TYPE (ctor)) == ARRAY_TYPE)
@@ -11860,22 +11862,37 @@ get_array_ctor_element_at_index (tree ctor, offset_int access_index,
/* Static constructors for variably sized objects makes no sense. */
gcc_assert (TREE_CODE (TYPE_MIN_VALUE (domain_type)) == INTEGER_CST);
index_type = TREE_TYPE (TYPE_MIN_VALUE (domain_type));
- low_bound = wi::to_offset (TYPE_MIN_VALUE (domain_type));
+ /* ??? When it is obvious that the range is signed, treat it so. */
+ if (TYPE_UNSIGNED (index_type)
+ && TYPE_MAX_VALUE (domain_type)
+ && tree_int_cst_lt (TYPE_MAX_VALUE (domain_type),
+ TYPE_MIN_VALUE (domain_type)))
+ {
+ index_sgn = SIGNED;
+ low_bound
+ = offset_int::from (wi::to_wide (TYPE_MIN_VALUE (domain_type)),
+ SIGNED);
+ }
+ else
+ {
+ index_sgn = TYPE_SIGN (index_type);
+ low_bound = wi::to_offset (TYPE_MIN_VALUE (domain_type));
+ }
}
}
if (index_type)
access_index = wi::ext (access_index, TYPE_PRECISION (index_type),
- TYPE_SIGN (index_type));
+ index_sgn);
- offset_int index = low_bound - 1;
+ offset_int index = low_bound;
if (index_type)
- index = wi::ext (index, TYPE_PRECISION (index_type),
- TYPE_SIGN (index_type));
+ index = wi::ext (index, TYPE_PRECISION (index_type), index_sgn);
- offset_int max_index;
+ offset_int max_index = index;
unsigned cnt;
tree cfield, cval;
+ bool first_p = true;
FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
{
@@ -11885,27 +11902,34 @@ get_array_ctor_element_at_index (tree ctor, offset_int access_index,
if (cfield)
{
if (TREE_CODE (cfield) == INTEGER_CST)
- max_index = index = wi::to_offset (cfield);
+ max_index = index
+ = offset_int::from (wi::to_wide (cfield), index_sgn);
else
{
gcc_assert (TREE_CODE (cfield) == RANGE_EXPR);
- index = wi::to_offset (TREE_OPERAND (cfield, 0));
- max_index = wi::to_offset (TREE_OPERAND (cfield, 1));
+ index = offset_int::from (wi::to_wide (TREE_OPERAND (cfield, 0)),
+ index_sgn);
+ max_index
+ = offset_int::from (wi::to_wide (TREE_OPERAND (cfield, 1)),
+ index_sgn);
+ gcc_checking_assert (wi::le_p (index, max_index, index_sgn));
}
}
- else
+ else if (!first_p)
{
- index += 1;
+ index = max_index + 1;
if (index_type)
- index = wi::ext (index, TYPE_PRECISION (index_type),
- TYPE_SIGN (index_type));
+ index = wi::ext (index, TYPE_PRECISION (index_type), index_sgn);
+ gcc_checking_assert (wi::gt_p (index, max_index, index_sgn));
max_index = index;
}
+ else
+ first_p = false;
/* Do we have match? */
- if (wi::cmpu (access_index, index) >= 0)
+ if (wi::cmp (access_index, index, index_sgn) >= 0)
{
- if (wi::cmpu (access_index, max_index) <= 0)
+ if (wi::cmp (access_index, max_index, index_sgn) <= 0)
{
if (ctor_idx)
*ctor_idx = cnt;
diff --git a/gcc/fold-const.h b/gcc/fold-const.h
index eab2b47..54c850a 100644
--- a/gcc/fold-const.h
+++ b/gcc/fold-const.h
@@ -84,7 +84,7 @@ extern bool fold_deferring_overflow_warnings_p (void);
extern void fold_overflow_warning (const char*, enum warn_strict_overflow_code);
extern enum tree_code fold_div_compare (enum tree_code, tree, tree,
tree *, tree *, bool *);
-extern int operand_equal_p (const_tree, const_tree, unsigned int);
+extern bool operand_equal_p (const_tree, const_tree, unsigned int);
extern int multiple_of_p (tree, const_tree, const_tree);
#define omit_one_operand(T1,T2,T3)\
omit_one_operand_loc (UNKNOWN_LOCATION, T1, T2, T3)
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index c4c35ad..1f44776 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,337 @@
+2019-08-19 Mark Eggleston <mark.eggleston@codethink.com>
+
+ * gfortran.texi: Delete paragraph about integer overload errors
+ when initialising integer variables with BOZ constants as these
+ no longer occur.
+
+2019-08-18 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/91485
+ module.c (gfc_match_use): User defined operator cannot conflict with
+ a rename symbol.
+
+2019-08-17 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/82992
+ * module.c (gfc_match_use): When renaming a module entity, search
+ current namespace for conflicting symbol.
+
+2019-08-17 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/78739
+ * match.c (gfc_match_st_function): When matching a statement function,
+ need to check if the statement function name shadows the function
+ name.
+
+2019-08-17 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/78719
+ * decl.c (get_proc_name): Check for a CLASS entity when trying to
+ add attributes to an entity that already has an explicit interface.
+
+2019-08-17 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/91471
+ * primary.c (gfc_variable_attr): Remove a gfc_internal_error(),
+ which cannot be reached by conforming Fortran code, but seems to
+ be reachable from nonconforming Fortran code. Treat the AR_UNKNOWN
+ case as a no-op.
+
+2019-08-17 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR fortran/68401
+ * trans-decl.c (gfc_build_builtin_function_decls): Replace
+ os_error with os_error_at decl.
+ * trans.c (trans_runtime_error_vararg): Modify so the error
+ function decl is passed directly.
+ (gfc_trans_runtime_error): Pass correct error function decl.
+ (gfc_trans_runtime_check): Likewise.
+ (trans_os_error_at): New function.
+ (gfc_call_malloc): Use trans_os_error_at.
+ (gfc_allocate_using_malloc): Likewise.
+ (gfc_call_realloc): Likewise.
+ * trans.h (gfor_fndecl_os_error): Replace with gfor_fndecl_os_error_at.
+
+2019-08-16 Jeff Law <law@redhat.com>
+ Mark Eggleston <mark.eggleston@codethink.com>
+
+ * gfortran.h: Add gfc_check_conflict declaration.
+ * symbol.c (check_conflict): Rename cfg_check_conflict and remove
+ static.
+ * symbol.c (cfg_check_conflict): Remove automatic in equivalence
+ conflict check.
+ * symbol.c (save_symbol): Add check for in equivalence to stop the
+ the save attribute being added.
+ * trans-common.c (build_equiv_decl): Add is_auto parameter and
+ add !is_auto to condition where TREE_STATIC (decl) is set.
+ * trans-common.c (build_equiv_decl): Add local variable is_auto,
+ set it true if an atomatic attribute is encountered in the variable
+ list. Call build_equiv_decl with is_auto as an additional parameter.
+ flag_dec_format_defaults is enabled.
+ * trans-common.c (accumulate_equivalence_attributes) : New subroutine.
+ * trans-common.c (find_equivalence) : New local variable dummy_symbol,
+ accumulated equivalence attributes from each symbol then check for
+ conflicts.
+
+2019-08-16 Richard Biener <rguenther@suse.de>
+
+ * trans-intrinsic.c (gfc_conv_intrinsic_findloc): Initialize
+ forward_branch to avoid bogus uninitialized warning.
+
+2019-08-15 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/91443
+ * frontend-passes.c (check_externals_expr): New function.
+ (check_externals_code): New function.
+ (gfc_check_externals): New function.
+ * gfortran.h (debug): Add prototypes for gfc_symbol * and
+ gfc_expr *.
+ (gfc_check_externals): Add prototype.
+ * interface.c (compare_actual_formal): Do not complain about
+ alternate returns if the formal argument is optional.
+ (gfc_procedure_use): Handle cases when an error has been issued
+ previously. Break long line.
+ * parse.c (gfc_parse_file): Call gfc_check_externals for all
+ external procedures.
+ * resolve.c (resolve_global_procedure): Remove checking of
+ argument list.
+
+2019-08-13 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/87991
+ * resolve.c (check_data_variable): data-stmt-object with pointer
+ attribute requires a data-stmt-value with the target attribute.
+
+2019-08-13 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/88072
+ * misc.c (gfc_typename): Do not point to something that ought not to
+ be pointed at.
+
+2013-08-13 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/90563
+ * frontend-passes.c (insert_index): Suppress errors while
+ simplifying the resulting expression.
+
+2019-08-13 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/89647
+ resolve.c (resolve_typebound_procedure): Allow host associated
+ procedure to be a binding target. While here, wrap long line.
+
+2019-08-13 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/87993
+ * expr.c (gfc_simplify_expr): Simplifcation of an array with a kind
+ type inquiry suffix yields a constant expression.
+
+2019-08-13 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR fortran/91414
+ * check.c (gfc_check_random_seed): Reduce seed_size.
+ * intrinsic.texi (RANDOM_NUMBER): Update to match new PRNG.
+
+2019-08-12 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/91424
+ * frontend-passes.c (do_subscript): Do not warn for an
+ expression a second time. Do not warn about a zero-trip loop.
+ (doloop_warn): Also look at contained namespaces.
+
+2019-08-11 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR fortran/91413
+ * invoke.texi (-fmax-stack-var-size): Document increased default.
+ * options.c (gfc_post_options): Increase default stack var size to
+ 65536 bytes.
+ * trans-decl.c (gfc_finish_var_decl): Generate warning when local
+ array moved to static storage.
+
+2019-08-10 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ * decl.c (match_old_style_init): Use a clearer error message.
+ * expr.c (gfc_check_assign): Update BOZ checking to provide a stricter
+ adherence to the Fortran standard. Use gfc_invalid_boz () to
+ relax errors into warnings.
+ * gfortran.h (gfc_isym_id): Add new ids GFC_ISYM_DFLOAT,
+ GFC_ISYM_FLOAT, GFC_ISYM_REALPART, and GFC_ISYM_SNGL
+ * intrinsic.c (add_functions): Use new ids to split REAL generic into
+ REAL, FLOAT, DFLOAT, SNGL, and REALPART generics.
+ (gfc_intrinsic_func_interface): Allow new intrinsics in an
+ initialization expression
+ * resolve.c (resolve_operator): Deal with BOZ as operands.
+ Use gfc_invalid_boz to allow for errors or warnings via the
+ -fallow-invalid-boz option. A BOZ cannot be an operand to an
+ unary operator. Both operands of a binary operator cannot be BOZ.
+ For binary operators, convert a BOZ operand into the type and
+ kind of the other operand for REAL or INTEGER operand.
+ * trans-intrinsic.c: Use new ids to cause conversions to happen.
+
+2019-08-06 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/91359
+ * trans-decl.c (gfc_generate_return): Ensure something is returned
+ from a function.
+
+2019-08-06 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/42546
+ * check.c(gfc_check_allocated): Add comment pointing to ...
+ * intrinsic.c(sort_actual): ... the checking done here.
+
+2019-08-05 Steven g. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/91372
+ * decl.c (gfc_match_data): Allow an implied do-loop to nestle against
+ DATA.
+
+2019-08-04 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/88227
+ * check.c (oct2bin): New function. Convert octal string to binary.
+ (hex2bin): New function. Convert hexidecimal string to binary.
+ (bin2real): New function. Convert binary string to REAL. Use
+ oct2bin and hex2bin.
+ (gfc_boz2real): Use fallback conversion bin2real.
+
+2019-08-02 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/90985
+ * decl.c (gfc_match_data): In free-form code, DATA be followed by
+ whitespace.
+
+2019-08-02 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/90986
+ * match.c (gfc_match_equivalence): Check that EQUIVALENCE is followed
+ by '('.
+
+2019-07-30 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/91296
+ * interface.c (compare_actual_expr): When checking for aliasing, add
+ a case to handle REF_INQUIRY (e.g., foo(x%re, x%im) do not alias).
+
+2019-07-29 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/90813
+ * dump-parse-tree.c (show_global_symbol): New function.
+ (gfc_dump_global_symbols): New function.
+ * gfortran.h (gfc_traverse_gsymbol): Add prototype.
+ (gfc_dump_global_symbols): Likewise.
+ * invoke.texi: Document -fdump-fortran-global.
+ * lang.opt: Add -fdump-fortran-global.
+ * parse.c (gfc_parse_file): Handle flag_dump_fortran_global.
+ * symbol.c (gfc_traverse_gsymbol): New function.
+ * trans-decl.c (sym_identifier): New function.
+ (mangled_identifier): New function, doing most of the work
+ of gfc_sym_mangled_identifier.
+ (gfc_sym_mangled_identifier): Use mangled_identifier. Add mangled
+ identifier to global symbol table.
+ (get_proc_pointer_decl): Use backend decl from global identifier
+ if present.
+
+2019-07-25 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/65819
+ * dependency.h (gfc_dep_resovler): Add optional argument identical.
+ * dependency.c (gfc_check_dependency): Do not alway return 1 if
+ the symbol is the same. Pass on identical to gfc_dep_resolver.
+ (gfc_check_element_vs_element): Whitespace fix.
+ (gfc_dep_resolver): Adjust comment for function. If identical is
+ true, return 1 if any overlap has been found.
+
+2019-07-23 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/54072
+ * check.c (gfc_invalid_boz): Fix comment.
+ (illegal_boz_arg): New function.
+ (gfc_check_transfer): Use to arguments.
+ (gfc_check_storage_size): Ditto.
+ (gfc_check_complex): Remove leftover comment from BOZ patch.
+ * primary.c (match_boz_constant): Remove leftover comment.
+
+2019-07-23 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ * arith.c (gfc_convert_integer, gfc_convert_real, gfc_convert_complex):
+ Move to ...
+ * primary.c (convert_integer, convert_real, convert_complex): ... here.
+ Rename and make static functions.
+ (match_integer_constant): Use convert_integer
+ (match_real_constant): Use convert_real.
+ (match_complex_constant: Use convert_complex.
+ * arith.h (gfc_convert_integer, gfc_convert_real, gfc_convert_complex):
+ Remove prototypes.
+ * array.c (match_array_cons_element): A BOZ cannot be a data
+ statement value. Jump to a common exit point.
+ * check.c (gfc_invalid_boz): New function. Emit error or warning
+ for a BOZ in an invalid context.
+ (boz_args_check): Move to top of file to prevent need of forward
+ declaration.
+ (is_boz_constant): New function. Check that BOZ expr is constant.
+ (gfc_boz2real): New function. In-place conversion of BOZ literal
+ constant to REAL in accordance to F2018.
+ (gfc_boz2int): New function. In-place conversion of BOZ literal
+ constant to INTEGER in accordance to F2018.
+ (gfc_check_achar, gfc_check_char, gfc_check_float): Use gfc_invalid_boz. Convert BOZ
+ as needed.
+ (gfc_check_bge_bgt_ble_blt): Enforce F2018 requirements on BGE,
+ BGT, BLE, and BLT intrinsic functions.
+ (gfc_check_cmplx): Re-organize to check kind, if present, first.
+ Convert BOZ real and/or imaginary parts as needed in accordance to
+ F2018.
+ (gfc_check_complex): Use gfc_invalid_boz. Convert BOZ as needed.
+ (gfc_check_dcmplx, gfc_check_dble ): Convert BOZ as needed.
+ (gfc_check_dshift): Make dshift[lr] conform to F2018 standard.
+ gfc_check_float (gfc_expr *a)
+ (gfc_check_iand_ieor_ior): Make IAND, IEOR, and IOR conform to
+ F2018 standard.
+ (gfc_check_int): Conform to F2018 standard.
+ (gfc_check_intconv): Deprecate SHORT and LONG aliases for INT2 and
+ INT. Simply return for a BOZ argument. See gfc_simplify_intconv.
+ (gfc_check_merge_bits): Make MERGE_BITS conform to Fortran 2018
+ standard.
+ (gfc_check_real): Remove incorrect comment. Check kind, if present,
+ first. Simply return for a BOZ argument. See gfc_simplify_real.
+ (gfc_check_and): Re-do error handling for BOZ arguments. Remove
+ special casing ts.type != BT_INTEGER or BT_LOGICAL.
+ * decl.c (match_old_style_init): Check for BOZ in old-style
+ initialization. Issue error or warning depending on
+ -fallow-invalid-boz option. Issue error if variable is not an
+ INTEGER or REAL and the value is BOZ.
+ * expr.c (gfc_copy_expr): Copy a BT_BOZ gfc_expr.
+ (gfc_check_assign): Re-do error handling for a BOZ in an assignment
+ statement. Do in-place conversion of RHS based on LHS type of
+ INTEGER or REAL.
+ * gfortran.h (gfc_expr): Add a boz component. Remove is_boz component.
+ (gfc_boz2int, gfc_boz2real, gfc_invalid_boz): New prototypes.
+ * interface.c (gfc_extend_assign): Guard against replacing an
+ intrinsic involving a BOZ literal constant on RHS.
+ * invoke.texi: Doument -fallow-invalid-boz.
+ * lang.opt: New option. -fallow-invalid-boz.
+ * libgfortran.h (bt): Elevate BOZ to a basic type.
+ * misc.c (gfc_basic_typename, gfc_typename): Translate BT_BOZ to BOZ.
+ * primary.c (convert_integer, convert_real, convert_complex): to here.
+ Rename and make static functions.
+ * primary.c(match_boz_constant): Rewrite parsing of a BOZ. Re-do
+ error handling. Deprecate 'X' for hexidecimal and postfix notation.
+ Use -fallow-invalid-boz and gfc_invalid_boz to accept deprecated code.
+ * resolve.c (resolve_ordinary_assign): Rework a RHS that is a
+ BOZ literal constant. Use gfc_invalid_boz to allow previous
+ nonstandard behavior. Remove range checking of BOZ conversion.
+ * simplify.c (convert_boz): Remove function.
+ (simplify_cmplx): Remove conversion of BOZ constants, because
+ conversion is done in gfc_check_cmplx.
+ (gfc_simplify_float): Remove conversion of BOZ constant, because
+ conversion is done in gfc_check_float.
+ (simplify_intconv): Use gfc_boz2int to convert BOZ to INTEGER.
+ Remove range checking for BOZ conversion.
+ (gfc_simplify_real): Use k, if present, to determine kind. Convert
+ BOZ to REAL. Remove range checking for BOZ conversion.
+ target-memory.c (gfc_convert_boz): Rewrite to deal with convert of
+ a BOZ to a REAL value.
+
2019-07-21 Thomas König <tkoenig@gcc.gnu.org>
PR libfortran/91030
@@ -124,7 +458,7 @@
2019-06-19 Steven G. Kargl <kargl@gcc.gnu.org>
PR fortran/69499
- * match.c (gfc_match_select_type): SELECT TYPE is an executable
+ * match.c (gfc_match_select_type): SELECT TYPE is an executable
statement, and cannot appear in MODULE or SUBMODULE scope.
2019-06-19 Steven G. Kargl <kargl@gcc.gnu.org>
@@ -241,7 +575,7 @@
only checking the reference chain.
2019-06-08 Thomas Koenig <tkoenig@gcc.gnu.org>
- Tomáš Trnka <trnka@scm.com>
+ Tomáš Trnka <trnka@scm.com>
PR fortran/90744
* trans-types.c (get_formal_from_actual_arglist): Unset typespec
@@ -446,7 +780,7 @@
* module.c (write_module): Initialize module_column before writing
module to ensure line break occurs at correct column.
-2019-05-01 Dominique d'Humieres <dominiq@gcc.gnu.org>
+2019-05-01 Dominique d'Humieres <dominiq@gcc.gnu.org>
PR fortran/60144
* match.c (gfc_match_parens): Change the location for missing ')'.
@@ -566,7 +900,7 @@
2019-03-31 Thomas Koenig <tkoenig@gcc.gnu.org>
- * dump-parse-tree.c (debug): Add for symbol_attribute *,
+ * dump-parse-tree.c (debug): Add for symbol_attribute *,
symbol_attribute and gfc_ref * arguments.
2019-03-30 Paul Thomas <pault@gcc.gnu.org>
@@ -827,7 +1161,7 @@
2019-03-09 Thomas König <tkoenig@gcc.gnu.org>
PR fortran/71203
- * decl.c (add_init_expr_to_sym): Add shape if init has none. Add
+ * decl.c (add_init_expr_to_sym): Add shape if init has none. Add
asserts that it has to be an EXPR_ARRAY in this case.
2019-03-08 Jakub Jelinek <jakub@redhat.com>
@@ -890,6 +1224,10 @@
the actual arglist has no expression, the corresponding
formal arglist is an alternate return.
+2019-02-26 Uroš Bizjak <ubizjak@gmail.com>
+
+ * invoke.texi (-ffpe-trap): Use @var for every item in the list.
+
2019-02-26 Jakub Jelinek <jakub@redhat.com>
PR fortran/43210
@@ -922,7 +1260,7 @@
* class.c (find_intrinsic_vtab): Likewise.
* simplify.c (gfc_simplify_sizeof): Likewise.
-2019-02-23 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+2019-02-23 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/84387
* trans-io.c (transfer_expr): Do not return if there are no
@@ -1072,7 +1410,7 @@
2019-02-17 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/71066
- * trans-decl.c (generate_coarray_sym_init): For an array
+ * trans-decl.c (generate_coarray_sym_init): For an array
constructor in a DATA statement of a coarray variable, set the
rank to 1 to avoid confusion later on. If the constructor
contains only one value, use that for initiailizig.
@@ -1258,7 +1596,7 @@
* io.c (match_io_element): input-item cannot be an external function.
2018-01-19 Thomas Koenig <tkoenig@gcc.gnu.org>
- Paul Thomas <pault@gcc.gnu.org>
+ Paul Thomas <pault@gcc.gnu.org>
PR fortran/56789
* trans-expr.c (gfc_conv_procedure_call): Call
@@ -1414,8 +1752,8 @@
directly build the expected GENERIC tree.
2019-01-07 Thomas Koenig <tkoenig@gcc.gnu.org>
- Harald Anlauf <anlauf@gmx.de>
- Tobias Burnus <burnus@gcc.gnu.org>
+ Harald Anlauf <anlauf@gmx.de>
+ Tobias Burnus <burnus@gcc.gnu.org>
PR fortran/45424
* check.c (gfc_check_is_contiguous): New function.
diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c
index a4f8795..ff279db 100644
--- a/gcc/fortran/arith.c
+++ b/gcc/fortran/arith.c
@@ -1892,56 +1892,6 @@ gfc_le (gfc_expr *op1, gfc_expr *op2, gfc_intrinsic_op op)
}
-/* Convert an integer string to an expression node. */
-
-gfc_expr *
-gfc_convert_integer (const char *buffer, int kind, int radix, locus *where)
-{
- gfc_expr *e;
- const char *t;
-
- e = gfc_get_constant_expr (BT_INTEGER, kind, where);
- /* A leading plus is allowed, but not by mpz_set_str. */
- if (buffer[0] == '+')
- t = buffer + 1;
- else
- t = buffer;
- mpz_set_str (e->value.integer, t, radix);
-
- return e;
-}
-
-
-/* Convert a real string to an expression node. */
-
-gfc_expr *
-gfc_convert_real (const char *buffer, int kind, locus *where)
-{
- gfc_expr *e;
-
- e = gfc_get_constant_expr (BT_REAL, kind, where);
- mpfr_set_str (e->value.real, buffer, 10, GFC_RND_MODE);
-
- return e;
-}
-
-
-/* Convert a pair of real, constant expression nodes to a single
- complex expression node. */
-
-gfc_expr *
-gfc_convert_complex (gfc_expr *real, gfc_expr *imag, int kind)
-{
- gfc_expr *e;
-
- e = gfc_get_constant_expr (BT_COMPLEX, kind, &real->where);
- mpc_set_fr_fr (e->value.complex, real->value.real, imag->value.real,
- GFC_MPC_RND_MODE);
-
- return e;
-}
-
-
/******* Simplification of intrinsic functions with constant arguments *****/
diff --git a/gcc/fortran/arith.h b/gcc/fortran/arith.h
index e06c705..39366ca 100644
--- a/gcc/fortran/arith.h
+++ b/gcc/fortran/arith.h
@@ -59,11 +59,6 @@ gfc_expr *gfc_ge (gfc_expr *, gfc_expr *, gfc_intrinsic_op);
gfc_expr *gfc_lt (gfc_expr *, gfc_expr *, gfc_intrinsic_op);
gfc_expr *gfc_le (gfc_expr *, gfc_expr *, gfc_intrinsic_op);
-/* Convert strings to literal constants. */
-gfc_expr *gfc_convert_integer (const char *, int, int, locus *);
-gfc_expr *gfc_convert_real (const char *, int, locus *);
-gfc_expr *gfc_convert_complex (gfc_expr *, gfc_expr *, int);
-
/* Convert a constant of one kind to another kind. */
gfc_expr *gfc_int2int (gfc_expr *, int);
gfc_expr *gfc_int2real (gfc_expr *, int);
diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c
index 0aee220..396dd97 100644
--- a/gcc/fortran/array.c
+++ b/gcc/fortran/array.c
@@ -1110,17 +1110,27 @@ match_array_cons_element (gfc_constructor_base *result)
if (m != MATCH_YES)
return m;
+ if (expr->ts.type == BT_BOZ)
+ {
+ gfc_error ("BOZ literal constant at %L cannot appear in an "
+ "array constructor", &expr->where);
+ goto done;
+ }
+
if (expr->expr_type == EXPR_FUNCTION
&& expr->ts.type == BT_UNKNOWN
&& strcmp(expr->symtree->name, "null") == 0)
- {
+ {
gfc_error ("NULL() at %C cannot appear in an array constructor");
- gfc_free_expr (expr);
- return MATCH_ERROR;
- }
+ goto done;
+ }
gfc_constructor_append_expr (result, expr, &gfc_current_locus);
return MATCH_YES;
+
+done:
+ gfc_free_expr (expr);
+ return MATCH_ERROR;
}
diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
index 9580180..2bd8bc3 100644
--- a/gcc/fortran/check.c
+++ b/gcc/fortran/check.c
@@ -34,6 +34,411 @@ along with GCC; see the file COPYING3. If not see
#include "constructor.h"
#include "target-memory.h"
+/* A BOZ literal constant can appear in a limited number of contexts.
+ gfc_invalid_boz() is a helper function to simplify error/warning
+ generation. gfortran accepts the nonstandard 'X' for 'Z', and gfortran
+ allows the BOZ indicator to appear as a suffix. If -fallow-invalid-boz
+ is used, then issue a warning; otherwise issue an error. */
+
+bool
+gfc_invalid_boz (const char *msg, locus *loc)
+{
+ if (flag_allow_invalid_boz)
+ {
+ gfc_warning (0, msg, loc);
+ return false;
+ }
+
+ gfc_error (msg, loc);
+ return true;
+}
+
+
+/* Issue an error for an illegal BOZ argument. */
+
+static bool
+illegal_boz_arg (gfc_expr *x)
+{
+ if (x->ts.type == BT_BOZ)
+ {
+ gfc_error ("BOZ literal constant at %L cannot be an actual argument "
+ "to %qs", &x->where, gfc_current_intrinsic);
+ return true;
+ }
+
+ return false;
+}
+
+/* Some precedures take two arguments such that both cannot be BOZ. */
+
+static bool
+boz_args_check(gfc_expr *i, gfc_expr *j)
+{
+ if (i->ts.type == BT_BOZ && j->ts.type == BT_BOZ)
+ {
+ gfc_error ("Arguments of %qs at %L and %L cannot both be BOZ "
+ "literal constants", gfc_current_intrinsic, &i->where,
+ &j->where);
+ return false;
+
+ }
+
+ return true;
+}
+
+
+/* Check that a BOZ is a constant. */
+
+static bool
+is_boz_constant (gfc_expr *a)
+{
+ if (a->expr_type != EXPR_CONSTANT)
+ {
+ gfc_error ("Invalid use of BOZ literal constant at %L", &a->where);
+ return false;
+ }
+
+ return true;
+}
+
+
+/* Convert a octal string into a binary string. This is used in the
+ fallback conversion of an octal string to a REAL. */
+
+static char *
+oct2bin(int nbits, char *oct)
+{
+ const char bits[8][5] = {
+ "000", "001", "010", "011", "100", "101", "110", "111"};
+
+ char *buf, *bufp;
+ int i, j, n;
+
+ j = nbits + 1;
+ if (nbits == 64) j++;
+
+ bufp = buf = XCNEWVEC (char, j + 1);
+ memset (bufp, 0, j + 1);
+
+ n = strlen (oct);
+ for (i = 0; i < n; i++, oct++)
+ {
+ j = *oct - 48;
+ strcpy (bufp, &bits[j][0]);
+ bufp += 3;
+ }
+
+ bufp = XCNEWVEC (char, nbits + 1);
+ if (nbits == 64)
+ strcpy (bufp, buf + 2);
+ else
+ strcpy (bufp, buf + 1);
+
+ free (buf);
+
+ return bufp;
+}
+
+
+/* Convert a hexidecimal string into a binary string. This is used in the
+ fallback conversion of a hexidecimal string to a REAL. */
+
+static char *
+hex2bin(int nbits, char *hex)
+{
+ const char bits[16][5] = {
+ "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111",
+ "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
+
+ char *buf, *bufp;
+ int i, j, n;
+
+ bufp = buf = XCNEWVEC (char, nbits + 1);
+ memset (bufp, 0, nbits + 1);
+
+ n = strlen (hex);
+ for (i = 0; i < n; i++, hex++)
+ {
+ j = *hex;
+ if (j > 47 && j < 58)
+ j -= 48;
+ else if (j > 64 && j < 71)
+ j -= 55;
+ else if (j > 96 && j < 103)
+ j -= 87;
+ else
+ gcc_unreachable ();
+
+ strcpy (bufp, &bits[j][0]);
+ bufp += 4;
+ }
+
+ return buf;
+}
+
+
+/* Fallback conversion of a BOZ string to REAL. */
+
+static void
+bin2real (gfc_expr *x, int kind)
+{
+ char buf[114], *sp;
+ int b, i, ie, t, w;
+ bool sgn;
+ mpz_t em;
+
+ i = gfc_validate_kind (BT_REAL, kind, false);
+ t = gfc_real_kinds[i].digits - 1;
+
+ /* Number of bits in the exponent. */
+ if (gfc_real_kinds[i].max_exponent == 16384)
+ w = 15;
+ else if (gfc_real_kinds[i].max_exponent == 1024)
+ w = 11;
+ else
+ w = 8;
+
+ if (x->boz.rdx == 16)
+ sp = hex2bin (gfc_real_kinds[i].mode_precision, x->boz.str);
+ else if (x->boz.rdx == 8)
+ sp = oct2bin (gfc_real_kinds[i].mode_precision, x->boz.str);
+ else
+ sp = x->boz.str;
+
+ /* Extract sign bit. */
+ sgn = *sp != '0';
+
+ /* Extract biased exponent. */
+ memset (buf, 0, 114);
+ strncpy (buf, ++sp, w);
+ mpz_init (em);
+ mpz_set_str (em, buf, 2);
+ ie = mpz_get_si (em);
+
+ mpfr_init2 (x->value.real, t + 1);
+ x->ts.type = BT_REAL;
+ x->ts.kind = kind;
+
+ sp += w; /* Set to first digit in significand. */
+ b = (1 << w) - 1;
+ if ((i == 0 && ie == b) || (i == 1 && ie == b)
+ || ((i == 2 || i == 3) && ie == b))
+ {
+ bool zeros = true;
+ if (i == 2) sp++;
+ for (; *sp; sp++)
+ {
+ if (*sp != '0')
+ {
+ zeros = false;
+ break;
+ }
+ }
+
+ if (zeros)
+ mpfr_set_inf (x->value.real, 1);
+ else
+ mpfr_set_nan (x->value.real);
+ }
+ else
+ {
+ if (i == 2)
+ strncpy (buf, sp, t + 1);
+ else
+ {
+ /* Significand with hidden bit. */
+ buf[0] = '1';
+ strncpy (&buf[1], sp, t);
+ }
+
+ /* Convert to significand to integer. */
+ mpz_set_str (em, buf, 2);
+ ie -= ((1 << (w - 1)) - 1); /* Unbiased exponent. */
+ mpfr_set_z_2exp (x->value.real, em, ie - t, GFC_RND_MODE);
+ }
+
+ if (sgn) mpfr_neg (x->value.real, x->value.real, GFC_RND_MODE);
+
+ mpz_clear (em);
+}
+
+
+/* Fortran 2018 treats a BOZ as simply a string of bits. gfc_boz2real ()
+ converts the string into a REAL of the appropriate kind. The treatment
+ of the sign bit is processor dependent. */
+
+bool
+gfc_boz2real (gfc_expr *x, int kind)
+{
+ extern int gfc_max_integer_kind;
+ gfc_typespec ts;
+ int len;
+ char *buf, *str;
+
+ if (!is_boz_constant (x))
+ return false;
+
+ /* Determine the length of the required string. */
+ len = 8 * kind;
+ if (x->boz.rdx == 16) len /= 4;
+ if (x->boz.rdx == 8) len = len / 3 + 1;
+ buf = (char *) alloca (len + 1); /* +1 for NULL terminator. */
+
+ if (x->boz.len >= len) /* Truncate if necessary. */
+ {
+ str = x->boz.str + (x->boz.len - len);
+ strcpy(buf, str);
+ }
+ else /* Copy and pad. */
+ {
+ memset (buf, 48, len);
+ str = buf + (len - x->boz.len);
+ strcpy (str, x->boz.str);
+ }
+
+ /* Need to adjust leading bits in an octal string. */
+ if (x->boz.rdx == 8)
+ {
+ /* Clear first bit. */
+ if (kind == 4 || kind == 10 || kind == 16)
+ {
+ if (buf[0] == '4')
+ buf[0] = '0';
+ else if (buf[0] == '5')
+ buf[0] = '1';
+ else if (buf[0] == '6')
+ buf[0] = '2';
+ else if (buf[0] == '7')
+ buf[0] = '3';
+ }
+ /* Clear first two bits. */
+ else
+ {
+ if (buf[0] == '4' || buf[0] == '6')
+ buf[0] = '0';
+ else if (buf[0] == '5' || buf[0] == '7')
+ buf[0] = '1';
+ }
+ }
+
+ /* Reset BOZ string to the truncated or padded version. */
+ free (x->boz.str);
+ x->boz.len = len;
+ x->boz.str = XCNEWVEC (char, len + 1);
+ strncpy (x->boz.str, buf, len);
+
+ /* For some targets, the largest INTEGER in terms of bits is smaller than
+ the bits needed to hold the REAL. Fortunately, the kind type parameter
+ indicates the number of bytes required to an INTEGER and a REAL. */
+ if (gfc_max_integer_kind < kind)
+ {
+ bin2real (x, kind);
+ }
+ else
+ {
+ /* Convert to widest possible integer. */
+ gfc_boz2int (x, gfc_max_integer_kind);
+ ts.type = BT_REAL;
+ ts.kind = kind;
+ if (!gfc_convert_boz (x, &ts))
+ {
+ gfc_error ("Failure in conversion of BOZ to REAL at %L", &x->where);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+/* Fortran 2018 treats a BOZ as simply a string of bits. gfc_boz2int ()
+ converts the string into an INTEGER of the appropriate kind. The
+ treatment of the sign bit is processor dependent. If the converted
+ value exceeds the range of the type, then wrap-around semantics are
+ applied. */
+
+bool
+gfc_boz2int (gfc_expr *x, int kind)
+{
+ int i, len;
+ char *buf, *str;
+ mpz_t tmp1;
+
+ if (!is_boz_constant (x))
+ return false;
+
+ i = gfc_validate_kind (BT_INTEGER, kind, false);
+ len = gfc_integer_kinds[i].bit_size;
+ if (x->boz.rdx == 16) len /= 4;
+ if (x->boz.rdx == 8) len = len / 3 + 1;
+ buf = (char *) alloca (len + 1); /* +1 for NULL terminator. */
+
+ if (x->boz.len >= len) /* Truncate if necessary. */
+ {
+ str = x->boz.str + (x->boz.len - len);
+ strcpy(buf, str);
+ }
+ else /* Copy and pad. */
+ {
+ memset (buf, 48, len);
+ str = buf + (len - x->boz.len);
+ strcpy (str, x->boz.str);
+ }
+
+ /* Need to adjust leading bits in an octal string. */
+ if (x->boz.rdx == 8)
+ {
+ /* Clear first bit. */
+ if (kind == 1 || kind == 4 || kind == 16)
+ {
+ if (buf[0] == '4')
+ buf[0] = '0';
+ else if (buf[0] == '5')
+ buf[0] = '1';
+ else if (buf[0] == '6')
+ buf[0] = '2';
+ else if (buf[0] == '7')
+ buf[0] = '3';
+ }
+ /* Clear first two bits. */
+ else
+ {
+ if (buf[0] == '4' || buf[0] == '6')
+ buf[0] = '0';
+ else if (buf[0] == '5' || buf[0] == '7')
+ buf[0] = '1';
+ }
+ }
+
+ /* Convert as-if unsigned integer. */
+ mpz_init (tmp1);
+ mpz_set_str (tmp1, buf, x->boz.rdx);
+
+ /* Check for wrap-around. */
+ if (mpz_cmp (tmp1, gfc_integer_kinds[i].huge) > 0)
+ {
+ mpz_t tmp2;
+ mpz_init (tmp2);
+ mpz_add_ui (tmp2, gfc_integer_kinds[i].huge, 1);
+ mpz_mod (tmp1, tmp1, tmp2);
+ mpz_sub (tmp1, tmp1, tmp2);
+ mpz_clear (tmp2);
+ }
+
+ /* Clear boz info. */
+ x->boz.rdx = 0;
+ x->boz.len = 0;
+ free (x->boz.str);
+
+ mpz_init (x->value.integer);
+ mpz_set (x->value.integer, tmp1);
+ x->ts.type = BT_INTEGER;
+ x->ts.kind = kind;
+ mpz_clear (tmp1);
+
+ return true;
+}
+
/* Make sure an expression is a scalar. */
@@ -880,8 +1285,19 @@ gfc_check_abs (gfc_expr *a)
bool
gfc_check_achar (gfc_expr *a, gfc_expr *kind)
{
+ if (a->ts.type == BT_BOZ)
+ {
+ if (gfc_invalid_boz ("BOZ literal constant at %L cannot appear in "
+ "ACHAR intrinsic subprogram", &a->where))
+ return false;
+
+ if (!gfc_boz2int (a, gfc_default_integer_kind))
+ return false;
+ }
+
if (!type_check (a, 0, BT_INTEGER))
return false;
+
if (!kind_check (kind, 1, BT_CHARACTER))
return false;
@@ -924,6 +1340,10 @@ gfc_check_all_any (gfc_expr *mask, gfc_expr *dim)
}
+/* Limited checking for ALLOCATED intrinsic. Additional checking
+ is performed in intrinsic.c(sort_actual), because ALLOCATED
+ has two mutually exclusive non-optional arguments. */
+
bool
gfc_check_allocated (gfc_expr *array)
{
@@ -1471,6 +1891,27 @@ gfc_check_bessel_n2 (gfc_expr *n1, gfc_expr *n2, gfc_expr *x)
bool
gfc_check_bge_bgt_ble_blt (gfc_expr *i, gfc_expr *j)
{
+ extern int gfc_max_integer_kind;
+
+ /* If i and j are both BOZ, convert to widest INTEGER. */
+ if (i->ts.type == BT_BOZ && j->ts.type == BT_BOZ)
+ {
+ if (!gfc_boz2int (i, gfc_max_integer_kind))
+ return false;
+ if (!gfc_boz2int (j, gfc_max_integer_kind))
+ return false;
+ }
+
+ /* If i is BOZ and j is integer, convert i to type of j. */
+ if (i->ts.type == BT_BOZ && j->ts.type == BT_INTEGER
+ && !gfc_boz2int (i, j->ts.kind))
+ return false;
+
+ /* If j is BOZ and i is integer, convert j to type of i. */
+ if (j->ts.type == BT_BOZ && i->ts.type == BT_INTEGER
+ && !gfc_boz2int (j, i->ts.kind))
+ return false;
+
if (!type_check (i, 0, BT_INTEGER))
return false;
@@ -1503,8 +1944,19 @@ gfc_check_bitfcn (gfc_expr *i, gfc_expr *pos)
bool
gfc_check_char (gfc_expr *i, gfc_expr *kind)
{
+ if (i->ts.type == BT_BOZ)
+ {
+ if (gfc_invalid_boz ("BOZ literal constant at %L cannot appear in "
+ "CHAR intrinsic subprogram", &i->where))
+ return false;
+
+ if (!gfc_boz2int (i, gfc_default_integer_kind))
+ return false;
+ }
+
if (!type_check (i, 0, BT_INTEGER))
return false;
+
if (!kind_check (kind, 1, BT_CHARACTER))
return false;
@@ -1590,11 +2042,29 @@ gfc_check_chmod_sub (gfc_expr *name, gfc_expr *mode, gfc_expr *status)
bool
gfc_check_cmplx (gfc_expr *x, gfc_expr *y, gfc_expr *kind)
{
+ int k;
+
+ /* Check kind first, because it may be needed in conversion of a BOZ. */
+ if (kind)
+ {
+ if (!kind_check (kind, 2, BT_COMPLEX))
+ return false;
+ gfc_extract_int (kind, &k);
+ }
+ else
+ k = gfc_default_complex_kind;
+
+ if (x->ts.type == BT_BOZ && !gfc_boz2real (x, k))
+ return false;
+
if (!numeric_check (x, 0))
return false;
if (y != NULL)
{
+ if (y->ts.type == BT_BOZ && !gfc_boz2real (y, k))
+ return false;
+
if (!numeric_check (y, 1))
return false;
@@ -1615,12 +2085,8 @@ gfc_check_cmplx (gfc_expr *x, gfc_expr *y, gfc_expr *kind)
&y->where);
return false;
}
-
}
- if (!kind_check (kind, 2, BT_COMPLEX))
- return false;
-
if (!kind && warn_conversion
&& x->ts.type == BT_REAL && x->ts.kind > gfc_default_real_kind)
gfc_warning_now (OPT_Wconversion, "Conversion from %s to default-kind "
@@ -1926,6 +2392,31 @@ gfc_check_co_sum (gfc_expr *a, gfc_expr *result_image, gfc_expr *stat,
bool
gfc_check_complex (gfc_expr *x, gfc_expr *y)
{
+ if (!boz_args_check (x, y))
+ return false;
+
+ if (x->ts.type == BT_BOZ)
+ {
+ if (gfc_invalid_boz ("BOZ constant at %L cannot appear in the COMPLEX "
+ "intrinsic subprogram", &x->where))
+ return false;
+ if (y->ts.type == BT_INTEGER && !gfc_boz2int (x, y->ts.kind))
+ return false;
+ if (y->ts.type == BT_REAL && !gfc_boz2real (x, y->ts.kind))
+ return false;
+ }
+
+ if (y->ts.type == BT_BOZ)
+ {
+ if (gfc_invalid_boz ("BOZ constant at %L cannot appear in the COMPLEX "
+ "intrinsic subprogram", &y->where))
+ return false;
+ if (x->ts.type == BT_INTEGER && !gfc_boz2int (y, x->ts.kind))
+ return false;
+ if (x->ts.type == BT_REAL && !gfc_boz2real (y, x->ts.kind))
+ return false;
+ }
+
if (!int_or_real_check (x, 0))
return false;
if (!scalar_check (x, 0))
@@ -2047,11 +2538,17 @@ bool gfc_check_datan2 (gfc_expr *y, gfc_expr *x)
bool
gfc_check_dcmplx (gfc_expr *x, gfc_expr *y)
{
+ if (x->ts.type == BT_BOZ && !gfc_boz2real (x, gfc_default_double_kind))
+ return false;
+
if (!numeric_check (x, 0))
return false;
if (y != NULL)
{
+ if (y->ts.type == BT_BOZ && !gfc_boz2real (y, gfc_default_double_kind))
+ return false;
+
if (!numeric_check (y, 1))
return false;
@@ -2081,6 +2578,9 @@ gfc_check_dcmplx (gfc_expr *x, gfc_expr *y)
bool
gfc_check_dble (gfc_expr *x)
{
+ if (x->ts.type == BT_BOZ && !gfc_boz2real (x, gfc_default_double_kind))
+ return false;
+
if (!numeric_check (x, 0))
return false;
@@ -2167,35 +2667,30 @@ gfc_check_dprod (gfc_expr *x, gfc_expr *y)
return true;
}
-
-static bool
-boz_args_check(gfc_expr *i, gfc_expr *j)
+bool
+gfc_check_dshift (gfc_expr *i, gfc_expr *j, gfc_expr *shift)
{
- if (i->is_boz && j->is_boz)
- {
- gfc_error ("Arguments of %qs at %L and %L cannot both be BOZ "
- "literal constants", gfc_current_intrinsic, &i->where,
- &j->where);
- return false;
+ /* i and j cannot both be BOZ literal constants. */
+ if (!boz_args_check (i, j))
+ return false;
- }
- return true;
-}
+ /* If i is BOZ and j is integer, convert i to type of j. */
+ if (i->ts.type == BT_BOZ && j->ts.type == BT_INTEGER
+ && !gfc_boz2int (i, j->ts.kind))
+ return false;
+ /* If j is BOZ and i is integer, convert j to type of i. */
+ if (j->ts.type == BT_BOZ && i->ts.type == BT_INTEGER
+ && !gfc_boz2int (j, i->ts.kind))
+ return false;
-bool
-gfc_check_dshift (gfc_expr *i, gfc_expr *j, gfc_expr *shift)
-{
if (!type_check (i, 0, BT_INTEGER))
return false;
if (!type_check (j, 1, BT_INTEGER))
return false;
- if (!boz_args_check (i, j))
- return false;
-
- if (!i->is_boz && !j->is_boz && !same_type_check (i, 0, j, 1))
+ if (!same_type_check (i, 0, j, 1))
return false;
if (!type_check (shift, 2, BT_INTEGER))
@@ -2204,18 +2699,8 @@ gfc_check_dshift (gfc_expr *i, gfc_expr *j, gfc_expr *shift)
if (!nonnegative_check ("SHIFT", shift))
return false;
- if (i->is_boz)
- {
- if (!less_than_bitsize1 ("J", j, "SHIFT", shift, true))
- return false;
- i->ts.kind = j->ts.kind;
- }
- else
- {
- if (!less_than_bitsize1 ("I", i, "SHIFT", shift, true))
- return false;
- j->ts.kind = i->ts.kind;
- }
+ if (!less_than_bitsize1 ("I", i, "SHIFT", shift, true))
+ return false;
return true;
}
@@ -2367,9 +2852,19 @@ gfc_check_eoshift (gfc_expr *array, gfc_expr *shift, gfc_expr *boundary,
return true;
}
+
bool
gfc_check_float (gfc_expr *a)
{
+ if (a->ts.type == BT_BOZ)
+ {
+ if (gfc_invalid_boz ("BOZ literal constant at %L cannot appear in the "
+ "FLOAT intrinsic subprogram", &a->where))
+ return false;
+ if (!gfc_boz2int (a, gfc_default_integer_kind))
+ return false;
+ }
+
if (!type_check (a, 0, BT_INTEGER))
return false;
@@ -2495,17 +2990,25 @@ gfc_check_i (gfc_expr *i)
bool
gfc_check_iand_ieor_ior (gfc_expr *i, gfc_expr *j)
{
- if (!type_check (i, 0, BT_INTEGER))
+ /* i and j cannot both be BOZ literal constants. */
+ if (!boz_args_check (i, j))
return false;
- if (!type_check (j, 1, BT_INTEGER))
+ /* If i is BOZ and j is integer, convert i to type of j. */
+ if (i->ts.type == BT_BOZ && j->ts.type == BT_INTEGER
+ && !gfc_boz2int (i, j->ts.kind))
return false;
- if (!boz_args_check (i, j))
+ /* If j is BOZ and i is integer, convert j to type of i. */
+ if (j->ts.type == BT_BOZ && i->ts.type == BT_INTEGER
+ && !gfc_boz2int (j, i->ts.kind))
return false;
- if (i->is_boz) i->ts.kind = j->ts.kind;
- if (j->is_boz) j->ts.kind = i->ts.kind;
+ if (!type_check (i, 0, BT_INTEGER))
+ return false;
+
+ if (!type_check (j, 1, BT_INTEGER))
+ return false;
if (i->ts.kind != j->ts.kind)
{
@@ -2658,6 +3161,10 @@ gfc_check_index (gfc_expr *string, gfc_expr *substring, gfc_expr *back,
bool
gfc_check_int (gfc_expr *x, gfc_expr *kind)
{
+ /* BOZ is dealt within simplify_int*. */
+ if (x->ts.type == BT_BOZ)
+ return true;
+
if (!numeric_check (x, 0))
return false;
@@ -2671,6 +3178,19 @@ gfc_check_int (gfc_expr *x, gfc_expr *kind)
bool
gfc_check_intconv (gfc_expr *x)
{
+ if (strcmp (gfc_current_intrinsic, "short") == 0
+ || strcmp (gfc_current_intrinsic, "long") == 0)
+ {
+ gfc_error ("%qs intrinsic subprogram at %L has been deprecated. "
+ "Use INT intrinsic subprogram.", gfc_current_intrinsic,
+ &x->where);
+ return false;
+ }
+
+ /* BOZ is dealt within simplify_int*. */
+ if (x->ts.type == BT_BOZ)
+ return true;
+
if (!numeric_check (x, 0))
return false;
@@ -3554,28 +4074,37 @@ gfc_check_merge (gfc_expr *tsource, gfc_expr *fsource, gfc_expr *mask)
bool
gfc_check_merge_bits (gfc_expr *i, gfc_expr *j, gfc_expr *mask)
{
- if (!type_check (i, 0, BT_INTEGER))
+ /* i and j cannot both be BOZ literal constants. */
+ if (!boz_args_check (i, j))
return false;
- if (!type_check (j, 1, BT_INTEGER))
+ /* If i is BOZ and j is integer, convert i to type of j. */
+ if (i->ts.type == BT_BOZ && j->ts.type == BT_INTEGER
+ && !gfc_boz2int (i, j->ts.kind))
return false;
- if (!boz_args_check (i, j))
+ /* If j is BOZ and i is integer, convert j to type of i. */
+ if (j->ts.type == BT_BOZ && i->ts.type == BT_INTEGER
+ && !gfc_boz2int (j, i->ts.kind))
return false;
- if (i->is_boz) i->ts.kind = j->ts.kind;
- if (j->is_boz) j->ts.kind = i->ts.kind;
+ if (!type_check (i, 0, BT_INTEGER))
+ return false;
- if (!type_check (mask, 2, BT_INTEGER))
+ if (!type_check (j, 1, BT_INTEGER))
return false;
if (!same_type_check (i, 0, j, 1))
return false;
- if (!same_type_check (i, 0, mask, 2))
+ if (mask->ts.type == BT_BOZ && !gfc_boz2int(mask, i->ts.kind))
return false;
- if (mask->is_boz) mask->ts.kind = i->ts.kind;
+ if (!type_check (mask, 2, BT_INTEGER))
+ return false;
+
+ if (!same_type_check (i, 0, mask, 2))
+ return false;
return true;
}
@@ -3977,14 +4506,17 @@ gfc_check_rank (gfc_expr *a)
}
-/* real, float, sngl. */
bool
gfc_check_real (gfc_expr *a, gfc_expr *kind)
{
- if (!numeric_check (a, 0))
+ if (!kind_check (kind, 1, BT_REAL))
return false;
- if (!kind_check (kind, 1, BT_REAL))
+ /* BOZ is dealt with in gfc_simplify_real. */
+ if (a->ts.type == BT_BOZ)
+ return true;
+
+ if (!numeric_check (a, 0))
return false;
return true;
@@ -5550,6 +6082,12 @@ gfc_check_transfer (gfc_expr *source, gfc_expr *mold, gfc_expr *size)
return false;
}
+ if (source->ts.type == BT_BOZ && illegal_boz_arg (source))
+ return false;
+
+ if (mold->ts.type == BT_BOZ && illegal_boz_arg (mold))
+ return false;
+
/* MOLD shall be a scalar or array of any type. */
if (mold->ts.type == BT_PROCEDURE
&& mold->symtree->n.sym->attr.subroutine == 1)
@@ -5946,9 +6484,8 @@ gfc_check_random_seed (gfc_expr *size, gfc_expr *put, gfc_expr *get)
mpz_t put_size, get_size;
/* Keep the number of bytes in sync with master_state in
- libgfortran/intrinsics/random.c. +1 due to the integer p which is
- part of the state too. */
- seed_size = 128 / gfc_default_integer_kind + 1;
+ libgfortran/intrinsics/random.c. */
+ seed_size = 32 / gfc_default_integer_kind;
if (size != NULL)
{
@@ -6726,42 +7263,28 @@ gfc_check_system_sub (gfc_expr *cmd, gfc_expr *status)
bool
gfc_check_and (gfc_expr *i, gfc_expr *j)
{
- if (i->ts.type != BT_INTEGER && i->ts.type != BT_LOGICAL)
- {
- gfc_error ("%qs argument of %qs intrinsic at %L must be INTEGER "
- "or LOGICAL", gfc_current_intrinsic_arg[0]->name,
- gfc_current_intrinsic, &i->where);
- return false;
- }
-
- if (j->ts.type != BT_INTEGER && j->ts.type != BT_LOGICAL)
- {
- gfc_error ("%qs argument of %qs intrinsic at %L must be INTEGER "
- "or LOGICAL", gfc_current_intrinsic_arg[1]->name,
- gfc_current_intrinsic, &j->where);
- return false;
- }
+ /* i and j cannot both be BOZ literal constants. */
+ if (!boz_args_check (i, j))
+ return false;
- if (i->ts.type != j->ts.type)
- {
- gfc_error ("%qs and %qs arguments of %qs intrinsic at %L must "
- "have the same type", gfc_current_intrinsic_arg[0]->name,
- gfc_current_intrinsic_arg[1]->name, gfc_current_intrinsic,
- &j->where);
- return false;
- }
+ /* If i is BOZ and j is integer, convert i to type of j. */
+ if (i->ts.type == BT_BOZ && j->ts.type == BT_INTEGER
+ && !gfc_boz2int (i, j->ts.kind))
+ return false;
- if (!scalar_check (i, 0))
+ /* If j is BOZ and i is integer, convert j to type of i. */
+ if (j->ts.type == BT_BOZ && i->ts.type == BT_INTEGER
+ && !gfc_boz2int (j, i->ts.kind))
return false;
- if (!scalar_check (j, 1))
+ if (!same_type_check (i, 0, j, 1, false))
return false;
- if (!boz_args_check (i, j))
+ if (!scalar_check (i, 0))
return false;
- if (i->is_boz) i->ts.kind = j->ts.kind;
- if (j->is_boz) j->ts.kind = i->ts.kind;
+ if (!scalar_check (j, 1))
+ return false;
return true;
}
@@ -6795,6 +7318,9 @@ gfc_check_storage_size (gfc_expr *a, gfc_expr *kind)
return false;
}
+ if (a->ts.type == BT_BOZ && illegal_boz_arg (a))
+ return false;
+
if (kind == NULL)
return true;
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 3d29091..5f12fe1 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -547,7 +547,7 @@ match_old_style_init (const char *name)
match m;
gfc_symtree *st;
gfc_symbol *sym;
- gfc_data *newdata;
+ gfc_data *newdata, *nd;
/* Set up data structure to hold initializers. */
gfc_find_sym_tree (name, NULL, 0, &st);
@@ -567,6 +567,26 @@ match_old_style_init (const char *name)
return m;
}
+ /* Check that a BOZ did not creep into an old-style initialization. */
+ for (nd = newdata; nd; nd = nd->next)
+ {
+ if (nd->value->expr->ts.type == BT_BOZ
+ && gfc_invalid_boz ("BOZ at %L cannot appear in an old-style "
+ "initialization", &nd->value->expr->where))
+ return MATCH_ERROR;
+
+ if (nd->var->expr->ts.type != BT_INTEGER
+ && nd->var->expr->ts.type != BT_REAL
+ && nd->value->expr->ts.type == BT_BOZ)
+ {
+ gfc_error ("BOZ literal constant near %L cannot be assigned to "
+ "a %qs variable in an old-style initialization",
+ &nd->value->expr->where,
+ gfc_typename (&nd->value->expr->ts));
+ return MATCH_ERROR;
+ }
+ }
+
if (gfc_pure (NULL))
{
gfc_error ("Initialization at %C is not allowed in a PURE procedure");
@@ -602,6 +622,14 @@ gfc_match_data (void)
gfc_expr *e;
gfc_ref *ref;
match m;
+ char c;
+
+ /* DATA has been matched. In free form source code, the next character
+ needs to be whitespace or '(' from an implied do-loop. Check that
+ here. */
+ c = gfc_peek_ascii_char ();
+ if (gfc_current_form == FORM_FREE && !gfc_is_whitespace (c) && c != '(')
+ return MATCH_NO;
/* Before parsing the rest of a DATA statement, check F2008:c1206. */
if ((gfc_current_state () == COMP_FUNCTION
@@ -1335,9 +1363,9 @@ get_proc_name (const char *name, gfc_symbol **result, bool module_fcn_entry)
}
/* Trap declarations of attributes in encompassing scope. The
- signature for this is that ts.kind is set. Legitimate
- references only set ts.type. */
- if (sym->ts.kind != 0
+ signature for this is that ts.kind is nonzero for no-CLASS
+ entity. For a CLASS entity, ts.kind is zero. */
+ if ((sym->ts.kind != 0 || sym->ts.type == BT_CLASS)
&& !sym->attr.implicit_type
&& sym->attr.proc == 0
&& gfc_current_ns->parent != NULL
diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c
index be330e2..da4a37c 100644
--- a/gcc/fortran/dependency.c
+++ b/gcc/fortran/dependency.c
@@ -1351,13 +1351,10 @@ gfc_check_dependency (gfc_expr *expr1, gfc_expr *expr2, bool identical)
return 0;
}
- if (identical)
- return 1;
-
/* Identical and disjoint ranges return 0,
overlapping ranges return 1. */
if (expr1->ref && expr2->ref)
- return gfc_dep_resolver (expr1->ref, expr2->ref, NULL);
+ return gfc_dep_resolver (expr1->ref, expr2->ref, NULL, identical);
return 1;
@@ -1884,6 +1881,7 @@ gfc_check_element_vs_element (gfc_ref *lref, gfc_ref *rref, int n)
if (i > -2)
return GFC_DEP_NODEP;
+
return GFC_DEP_EQUAL;
}
@@ -2084,13 +2082,15 @@ ref_same_as_full_array (gfc_ref *full_ref, gfc_ref *ref)
/* Finds if two array references are overlapping or not.
Return value
- 2 : array references are overlapping but reversal of one or
+ 2 : array references are overlapping but reversal of one or
more dimensions will clear the dependency.
- 1 : array references are overlapping.
- 0 : array references are identical or not overlapping. */
+ 1 : array references are overlapping, or identical is true and
+ there is some kind of overlap.
+ 0 : array references are identical or not overlapping. */
int
-gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
+gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse,
+ bool identical)
{
int n;
int m;
@@ -2124,11 +2124,15 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
case REF_ARRAY:
+ /* For now, treat all coarrays as dangerous. */
+ if (lref->u.ar.codimen || rref->u.ar.codimen)
+ return 1;
+
if (ref_same_as_full_array (lref, rref))
- return 0;
+ return identical;
if (ref_same_as_full_array (rref, lref))
- return 0;
+ return identical;
if (lref->u.ar.dimen != rref->u.ar.dimen)
{
@@ -2180,6 +2184,8 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
gcc_assert (rref->u.ar.dimen_type[n] == DIMEN_ELEMENT
&& lref->u.ar.dimen_type[n] == DIMEN_ELEMENT);
this_dep = gfc_check_element_vs_element (rref, lref, n);
+ if (identical && this_dep == GFC_DEP_EQUAL)
+ this_dep = GFC_DEP_OVERLAP;
}
/* If any dimension doesn't overlap, we have no dependency. */
@@ -2240,6 +2246,9 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
know the worst one.*/
update_fin_dep:
+ if (identical && this_dep == GFC_DEP_EQUAL)
+ this_dep = GFC_DEP_OVERLAP;
+
if (this_dep > fin_dep)
fin_dep = this_dep;
}
@@ -2253,7 +2262,7 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
/* Exactly matching and forward overlapping ranges don't cause a
dependency. */
- if (fin_dep < GFC_DEP_BACKWARD)
+ if (fin_dep < GFC_DEP_BACKWARD && !identical)
return 0;
/* Keep checking. We only have a dependency if
@@ -2267,11 +2276,14 @@ gfc_dep_resolver (gfc_ref *lref, gfc_ref *rref, gfc_reverse *reverse)
rref = rref->next;
}
+ /* Assume the worst if we nest to different depths. */
+ if (lref || rref)
+ return 1;
+
/* If we haven't seen any array refs then something went wrong. */
gcc_assert (fin_dep != GFC_DEP_ERROR);
- /* Assume the worst if we nest to different depths. */
- if (lref || rref)
+ if (identical && fin_dep != GFC_DEP_NODEP)
return 1;
return fin_dep == GFC_DEP_OVERLAP;
diff --git a/gcc/fortran/dependency.h b/gcc/fortran/dependency.h
index dd30887..eca60f7 100644
--- a/gcc/fortran/dependency.h
+++ b/gcc/fortran/dependency.h
@@ -37,7 +37,8 @@ int gfc_check_fncall_dependency (gfc_expr *, sym_intent, gfc_symbol *,
int gfc_check_dependency (gfc_expr *, gfc_expr *, bool);
int gfc_expr_is_one (gfc_expr *, int);
-int gfc_dep_resolver(gfc_ref *, gfc_ref *, gfc_reverse *);
+int gfc_dep_resolver (gfc_ref *, gfc_ref *, gfc_reverse *,
+ bool identical = false);
int gfc_are_equivalenced_arrays (gfc_expr *, gfc_expr *);
gfc_expr * gfc_discard_nops (gfc_expr *);
diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c
index 4cff805..798519f 100644
--- a/gcc/fortran/dump-parse-tree.c
+++ b/gcc/fortran/dump-parse-tree.c
@@ -3462,3 +3462,36 @@ write_interop_decl (gfc_symbol *sym)
else if (sym->attr.flavor == FL_PROCEDURE)
write_proc (sym, true);
}
+
+/* This section deals with dumping the global symbol tree. */
+
+/* Callback function for printing out the contents of the tree. */
+
+static void
+show_global_symbol (gfc_gsymbol *gsym, void *f_data)
+{
+ FILE *out;
+ out = (FILE *) f_data;
+
+ if (gsym->name)
+ fprintf (out, "name=%s", gsym->name);
+
+ if (gsym->sym_name)
+ fprintf (out, ", sym_name=%s", gsym->sym_name);
+
+ if (gsym->mod_name)
+ fprintf (out, ", mod_name=%s", gsym->mod_name);
+
+ if (gsym->binding_label)
+ fprintf (out, ", binding_label=%s", gsym->binding_label);
+
+ fputc ('\n', out);
+}
+
+/* Show all global symbols. */
+
+void
+gfc_dump_global_symbols (FILE *f)
+{
+ gfc_traverse_gsymbol (gfc_gsym_root, show_global_symbol, (void *) f);
+}
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index a164370..4516094 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -342,6 +342,13 @@ gfc_copy_expr (gfc_expr *p)
case BT_ASSUMED:
break; /* Already done. */
+ case BT_BOZ:
+ q->boz.len = p->boz.len;
+ q->boz.rdx = p->boz.rdx;
+ q->boz.str = XCNEWVEC (char, q->boz.len + 1);
+ strncpy (q->boz.str, p->boz.str, p->boz.len);
+ break;
+
case BT_PROCEDURE:
case BT_VOID:
/* Should never be reached. */
@@ -2220,6 +2227,11 @@ gfc_simplify_expr (gfc_expr *p, int type)
if (!simplify_ref_chain (p->ref, type, &p))
return false;
+ /* If the following conditions hold, we found something like kind type
+ inquiry of the form a(2)%kind while simplify the ref chain. */
+ if (p->expr_type == EXPR_CONSTANT && !p->ref && !p->rank && !p->shape)
+ return true;
+
if (!simplify_constructor (p->value.constructor, type))
return false;
@@ -3634,45 +3646,45 @@ gfc_check_assign (gfc_expr *lvalue, gfc_expr *rvalue, int conform,
&& !gfc_check_conformance (lvalue, rvalue, "array assignment"))
return false;
- if (rvalue->is_boz && lvalue->ts.type != BT_INTEGER
- && lvalue->symtree->n.sym->attr.data
- && !gfc_notify_std (GFC_STD_GNU, "BOZ literal at %L used to "
- "initialize non-integer variable %qs",
- &rvalue->where, lvalue->symtree->n.sym->name))
- return false;
- else if (rvalue->is_boz && !lvalue->symtree->n.sym->attr.data
- && !gfc_notify_std (GFC_STD_GNU, "BOZ literal at %L outside "
- "a DATA statement and outside INT/REAL/DBLE/CMPLX",
- &rvalue->where))
- return false;
-
/* Handle the case of a BOZ literal on the RHS. */
- if (rvalue->is_boz && lvalue->ts.type != BT_INTEGER)
- {
- int rc;
- if (warn_surprising)
- gfc_warning (OPT_Wsurprising,
- "BOZ literal at %L is bitwise transferred "
- "non-integer symbol %qs", &rvalue->where,
- lvalue->symtree->n.sym->name);
- if (!gfc_convert_boz (rvalue, &lvalue->ts))
- return false;
- if ((rc = gfc_range_check (rvalue)) != ARITH_OK)
+ if (rvalue->ts.type == BT_BOZ)
+ {
+ if (lvalue->symtree->n.sym->attr.data)
{
- if (rc == ARITH_UNDERFLOW)
- gfc_error ("Arithmetic underflow of bit-wise transferred BOZ at %L"
- ". This check can be disabled with the option "
- "%<-fno-range-check%>", &rvalue->where);
- else if (rc == ARITH_OVERFLOW)
- gfc_error ("Arithmetic overflow of bit-wise transferred BOZ at %L"
- ". This check can be disabled with the option "
- "%<-fno-range-check%>", &rvalue->where);
- else if (rc == ARITH_NAN)
- gfc_error ("Arithmetic NaN of bit-wise transferred BOZ at %L"
- ". This check can be disabled with the option "
- "%<-fno-range-check%>", &rvalue->where);
- return false;
+ if (lvalue->ts.type == BT_INTEGER
+ && gfc_boz2int (rvalue, lvalue->ts.kind))
+ return true;
+
+ if (lvalue->ts.type == BT_REAL
+ && gfc_boz2real (rvalue, lvalue->ts.kind))
+ {
+ if (gfc_invalid_boz ("BOZ literal constant near %L cannot "
+ "be assigned to a REAL variable",
+ &rvalue->where))
+ return false;
+ return true;
+ }
}
+
+ if (!lvalue->symtree->n.sym->attr.data
+ && gfc_invalid_boz ("BOZ literal constant at %L is neither a "
+ "data-stmt-constant nor an actual argument to "
+ "INT, REAL, DBLE, or CMPLX intrinsic function",
+ &rvalue->where))
+ return false;
+
+ if (lvalue->ts.type == BT_INTEGER
+ && gfc_boz2int (rvalue, lvalue->ts.kind))
+ return true;
+
+ if (lvalue->ts.type == BT_REAL
+ && gfc_boz2real (rvalue, lvalue->ts.kind))
+ return true;
+
+ gfc_error ("BOZ literal constant near %L cannot be assigned to a "
+ "%qs variable", &rvalue->where, gfc_typename (&lvalue->ts));
+
+ return false;
}
if (gfc_expr_attr (lvalue).pdt_kind || gfc_expr_attr (lvalue).pdt_len)
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c
index 87df504..dd82089 100644
--- a/gcc/fortran/frontend-passes.c
+++ b/gcc/fortran/frontend-passes.c
@@ -56,7 +56,6 @@ static gfc_expr* check_conjg_transpose_variable (gfc_expr *, bool *,
static int call_external_blas (gfc_code **, int *, void *);
static int matmul_temp_args (gfc_code **, int *,void *data);
static int index_interchange (gfc_code **, int*, void *);
-
static bool is_fe_temp (gfc_expr *e);
#ifdef CHECKING_P
@@ -2518,7 +2517,12 @@ insert_index (gfc_expr *e, gfc_symbol *sym, mpz_t val, mpz_t ret)
data.sym = sym;
mpz_init_set (data.val, val);
gfc_expr_walker (&n, callback_insert_index, (void *) &data);
+
+ /* Suppress errors here - we could get errors here such as an
+ out of bounds access for arrays, see PR 90563. */
+ gfc_push_suppress_errors ();
gfc_simplify_expr (n, 0);
+ gfc_pop_suppress_errors ();
if (n->expr_type == EXPR_CONSTANT)
{
@@ -2556,6 +2560,12 @@ do_subscript (gfc_expr **e)
if (in_assoc_list)
return 0;
+ /* We already warned about this. */
+ if (v->do_not_warn)
+ return 0;
+
+ v->do_not_warn = 1;
+
for (ref = v->ref; ref; ref = ref->next)
{
if (ref->type == REF_ARRAY && ref->u.ar.type == AR_ELEMENT)
@@ -2608,7 +2618,6 @@ do_subscript (gfc_expr **e)
else
have_do_start = false;
-
if (dl->ext.iterator->end->expr_type == EXPR_CONSTANT)
{
have_do_end = true;
@@ -2620,6 +2629,17 @@ do_subscript (gfc_expr **e)
if (!have_do_start && !have_do_end)
return 0;
+ /* No warning inside a zero-trip loop. */
+ if (have_do_start && have_do_end)
+ {
+ int sgn, cmp;
+
+ sgn = mpz_cmp_ui (do_step, 0);
+ cmp = mpz_cmp (do_end, do_start);
+ if ((sgn > 0 && cmp < 0) || (sgn < 0 && cmp > 0))
+ break;
+ }
+
/* May have to correct the end value if the step does not equal
one. */
if (have_do_start && have_do_end && mpz_cmp_ui (do_step, 1) != 0)
@@ -2761,6 +2781,12 @@ static void
doloop_warn (gfc_namespace *ns)
{
gfc_code_walker (&ns->code, doloop_code, do_function, NULL);
+
+ for (ns = ns->contained; ns; ns = ns->sibling)
+ {
+ if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
+ doloop_warn (ns);
+ }
}
/* This selction deals with inlining calls to MATMUL. */
@@ -5337,3 +5363,100 @@ gfc_code_walker (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn,
}
return 0;
}
+
+/* As a post-resolution step, check that all global symbols which are
+ not declared in the source file match in their call signatures.
+ We do this by looping over the code (and expressions). The first call
+ we happen to find is assumed to be canonical. */
+
+/* Callback for external functions. */
+
+static int
+check_externals_expr (gfc_expr **ep, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
+{
+ gfc_expr *e = *ep;
+ gfc_symbol *sym, *def_sym;
+ gfc_gsymbol *gsym;
+
+ if (e->expr_type != EXPR_FUNCTION)
+ return 0;
+
+ sym = e->value.function.esym;
+
+ if (sym == NULL || sym->attr.is_bind_c)
+ return 0;
+
+ if (sym->attr.proc != PROC_EXTERNAL && sym->attr.proc != PROC_UNKNOWN)
+ return 0;
+
+ gsym = gfc_find_gsymbol (gfc_gsym_root, sym->name);
+ if (gsym == NULL)
+ return 0;
+
+ gfc_find_symbol (sym->name, gsym->ns, 0, &def_sym);
+
+ if (sym && def_sym)
+ gfc_procedure_use (def_sym, &e->value.function.actual, &e->where);
+
+ return 0;
+}
+
+/* Callback for external code. */
+
+static int
+check_externals_code (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED)
+{
+ gfc_code *co = *c;
+ gfc_symbol *sym, *def_sym;
+ gfc_gsymbol *gsym;
+
+ if (co->op != EXEC_CALL)
+ return 0;
+
+ sym = co->resolved_sym;
+ if (sym == NULL || sym->attr.is_bind_c)
+ return 0;
+
+ if (sym->attr.proc != PROC_EXTERNAL && sym->attr.proc != PROC_UNKNOWN)
+ return 0;
+
+ if (sym->attr.if_source == IFSRC_IFBODY || sym->attr.if_source == IFSRC_DECL)
+ return 0;
+
+ gsym = gfc_find_gsymbol (gfc_gsym_root, sym->name);
+ if (gsym == NULL)
+ return 0;
+
+ gfc_find_symbol (sym->name, gsym->ns, 0, &def_sym);
+
+ if (sym && def_sym)
+ gfc_procedure_use (def_sym, &co->ext.actual, &co->loc);
+
+ return 0;
+}
+
+/* Called routine. */
+
+void
+gfc_check_externals (gfc_namespace *ns)
+{
+
+ gfc_clear_error ();
+
+ /* Turn errors into warnings if -std=legacy is given by the user. */
+
+ if (!pedantic && !(gfc_option.warn_std & GFC_STD_LEGACY))
+ gfc_errors_to_warnings (true);
+
+ gfc_code_walker (&ns->code, check_externals_code, check_externals_expr, NULL);
+
+ for (ns = ns->contained; ns; ns = ns->sibling)
+ {
+ if (ns->code == NULL || ns->code->op != EXEC_BLOCK)
+ gfc_check_externals (ns);
+ }
+
+ gfc_errors_to_warnings (false);
+}
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index b1f7bd0..6a491ab 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -423,6 +423,7 @@ enum gfc_isym_id
GFC_ISYM_C_SIZEOF,
GFC_ISYM_DATE_AND_TIME,
GFC_ISYM_DBLE,
+ GFC_ISYM_DFLOAT,
GFC_ISYM_DIGITS,
GFC_ISYM_DIM,
GFC_ISYM_DOT_PRODUCT,
@@ -448,6 +449,7 @@ enum gfc_isym_id
GFC_ISYM_FGET,
GFC_ISYM_FGETC,
GFC_ISYM_FINDLOC,
+ GFC_ISYM_FLOAT,
GFC_ISYM_FLOOR,
GFC_ISYM_FLUSH,
GFC_ISYM_FNUM,
@@ -573,6 +575,7 @@ enum gfc_isym_id
GFC_ISYM_RANGE,
GFC_ISYM_RANK,
GFC_ISYM_REAL,
+ GFC_ISYM_REALPART,
GFC_ISYM_RENAME,
GFC_ISYM_REPEAT,
GFC_ISYM_RESHAPE,
@@ -598,6 +601,7 @@ enum gfc_isym_id
GFC_ISYM_SIZE,
GFC_ISYM_SLEEP,
GFC_ISYM_SIZEOF,
+ GFC_ISYM_SNGL,
GFC_ISYM_SPACING,
GFC_ISYM_SPREAD,
GFC_ISYM_SQRT,
@@ -2152,9 +2156,8 @@ typedef struct gfc_expr
is not a variable. */
struct gfc_expr *base_expr;
- /* is_boz is true if the integer is regarded as BOZ bit pattern and is_snan
- denotes a signalling not-a-number. */
- unsigned int is_boz : 1, is_snan : 1;
+ /* is_snan denotes a signalling not-a-number. */
+ unsigned int is_snan : 1;
/* Sometimes, when an error has been emitted, it is necessary to prevent
it from recurring. */
@@ -2198,6 +2201,14 @@ typedef struct gfc_expr
}
representation;
+ struct
+ {
+ int len; /* Length of BOZ string without terminating NULL. */
+ int rdx; /* Radix of BOZ. */
+ char *str; /* BOZ string with NULL terminating character. */
+ }
+ boz;
+
union
{
int logical;
@@ -2996,6 +3007,7 @@ bool gfc_merge_new_implicit (gfc_typespec *);
void gfc_set_implicit_none (bool, bool, locus *);
void gfc_check_function_type (gfc_namespace *);
bool gfc_is_intrinsic_typename (const char *);
+bool gfc_check_conflict (symbol_attribute *, const char *, locus *);
gfc_typespec *gfc_get_default_type (const char *, gfc_namespace *);
bool gfc_set_default_type (gfc_symbol *, int, gfc_namespace *);
@@ -3121,6 +3133,7 @@ void gfc_enforce_clean_symbol_state (void);
gfc_gsymbol *gfc_get_gsymbol (const char *, bool bind_c);
gfc_gsymbol *gfc_find_gsymbol (gfc_gsymbol *, const char *);
gfc_gsymbol *gfc_find_case_gsymbol (gfc_gsymbol *, const char *);
+void gfc_traverse_gsymbol (gfc_gsymbol *, void (*)(gfc_gsymbol *, void *), void *);
gfc_typebound_proc* gfc_get_typebound_proc (gfc_typebound_proc*);
gfc_symbol* gfc_get_derived_super_type (gfc_symbol*);
@@ -3464,6 +3477,9 @@ void gfc_delete_bbt (void *, void *, compare_fn);
void gfc_dump_parse_tree (gfc_namespace *, FILE *);
void gfc_dump_c_prototypes (gfc_namespace *, FILE *);
void gfc_dump_external_c_prototypes (FILE *);
+void gfc_dump_global_symbols (FILE *);
+void debug (gfc_symbol *);
+void debug (gfc_expr *);
/* parse.c */
bool gfc_parse_file (void);
@@ -3479,6 +3495,10 @@ bool gfc_dep_difference (gfc_expr *, gfc_expr *, mpz_t *);
bool gfc_check_same_strlen (const gfc_expr*, const gfc_expr*, const char*);
bool gfc_calculate_transfer_sizes (gfc_expr*, gfc_expr*, gfc_expr*,
size_t*, size_t*, size_t*);
+bool gfc_boz2int (gfc_expr *, int);
+bool gfc_boz2real (gfc_expr *, int);
+bool gfc_invalid_boz (const char *, locus *);
+
/* class.c */
void gfc_fix_class_refs (gfc_expr *e);
@@ -3534,6 +3554,7 @@ int gfc_dummy_code_callback (gfc_code **, int *, void *);
int gfc_expr_walker (gfc_expr **, walk_expr_fn_t, void *);
int gfc_code_walker (gfc_code **, walk_code_fn_t, walk_expr_fn_t, void *);
bool gfc_has_dimen_vector_ref (gfc_expr *e);
+void gfc_check_externals (gfc_namespace *);
/* simplify.c */
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 16be9e0..4515b9d 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -1882,13 +1882,6 @@ with @code{2.0}.) As different compilers implement the extension
differently, one should be careful when doing bitwise initialization
of non-integer variables.
-Note that initializing an @code{INTEGER} variable with a statement such
-as @code{DATA i/Z'FFFFFFFF'/} will give an integer overflow error rather
-than the desired result of @math{-1} when @code{i} is a 32-bit integer
-on a system that supports 64-bit integers. The @samp{-fno-range-check}
-option can be used as a workaround for legacy code that initializes
-integers in this manner.
-
@node Real array indices
@subsection Real array indices
@cindex array, indices of type real
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 3f91f6b..d6f6cce 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -2979,10 +2979,15 @@ compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
if (a->expr == NULL)
{
- if (where)
- gfc_error_now ("Unexpected alternate return specifier in "
- "subroutine call at %L", where);
- return false;
+ if (f->sym->attr.optional)
+ continue;
+ else
+ {
+ if (where)
+ gfc_error_now ("Unexpected alternate return specifier in "
+ "subroutine call at %L", where);
+ return false;
+ }
}
/* Make sure that intrinsic vtables exist for calls to unlimited
@@ -3489,6 +3494,13 @@ compare_actual_expr (gfc_expr *e1, gfc_expr *e2)
case REF_SUBSTRING:
return false;
+ case REF_INQUIRY:
+ if (e1->symtree->n.sym->ts.type == BT_COMPLEX
+ && e1->ts.type == BT_REAL && e2->ts.type == BT_REAL
+ && r1->u.i != r2->u.i)
+ return false;
+ break;
+
default:
gfc_internal_error ("compare_actual_expr(): Bad component code");
}
@@ -3716,6 +3728,9 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where)
for (a = *ap; a; a = a->next)
{
+ if (a->expr && a->expr->error)
+ return false;
+
/* Skip g77 keyword extensions like %VAL, %REF, %LOC. */
if (a->name != NULL && a->name[0] != '%')
{
@@ -3731,6 +3746,7 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where)
gfc_error ("Assumed-type argument %s at %L requires an explicit "
"interface", a->expr->symtree->n.sym->name,
&a->expr->where);
+ a->expr->error = 1;
break;
}
@@ -3744,6 +3760,7 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where)
gfc_error ("Actual argument of LOCK_TYPE or with LOCK_TYPE "
"component at %L requires an explicit interface for "
"procedure %qs", &a->expr->where, sym->name);
+ a->expr->error = 1;
break;
}
@@ -3757,13 +3774,16 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where)
gfc_error ("Actual argument of EVENT_TYPE or with EVENT_TYPE "
"component at %L requires an explicit interface for "
"procedure %qs", &a->expr->where, sym->name);
+ a->expr->error = 1;
break;
}
if (a->expr && a->expr->expr_type == EXPR_NULL
&& a->expr->ts.type == BT_UNKNOWN)
{
- gfc_error ("MOLD argument to NULL required at %L", &a->expr->where);
+ gfc_error ("MOLD argument to NULL required at %L",
+ &a->expr->where);
+ a->expr->error = 1;
return false;
}
@@ -3773,6 +3793,7 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where)
{
gfc_error ("Assumed-rank argument requires an explicit interface "
"at %L", &a->expr->where);
+ a->expr->error = 1;
return false;
}
}
@@ -4274,6 +4295,12 @@ gfc_extend_assign (gfc_code *c, gfc_namespace *ns)
lhs = c->expr1;
rhs = c->expr2;
+ /* Don't allow an intrinsic assignment with a BOZ rhs to be replaced. */
+ if (c->op == EXEC_ASSIGN
+ && c->expr1->expr_type == EXPR_VARIABLE
+ && c->expr2->expr_type == EXPR_CONSTANT && c->expr2->ts.type == BT_BOZ)
+ return false;
+
/* Don't allow an intrinsic assignment to be replaced. */
if (lhs->ts.type != BT_DERIVED && lhs->ts.type != BT_CLASS
&& (rhs->rank == 0 || rhs->rank == lhs->rank)
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index c21fbdd..c35ea73 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -2786,12 +2786,16 @@ add_functions (void)
gfc_check_real, gfc_simplify_real, gfc_resolve_real,
a, BT_UNKNOWN, dr, REQUIRED, kind, BT_INTEGER, di, OPTIONAL);
+ make_generic ("real", GFC_ISYM_REAL, GFC_STD_F77);
+
/* This provides compatibility with g77. */
- add_sym_1 ("realpart", GFC_ISYM_REAL, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_GNU,
+ add_sym_1 ("realpart", GFC_ISYM_REALPART, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_GNU,
gfc_check_fn_c, gfc_simplify_realpart, gfc_resolve_realpart,
a, BT_UNKNOWN, dr, REQUIRED);
- add_sym_1 ("float", GFC_ISYM_REAL, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F77,
+ make_generic ("realpart", GFC_ISYM_REALPART, GFC_STD_F77);
+
+ add_sym_1 ("float", GFC_ISYM_FLOAT, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F77,
gfc_check_float, gfc_simplify_float, NULL,
a, BT_INTEGER, di, REQUIRED);
@@ -2802,15 +2806,19 @@ add_functions (void)
make_alias ("floatk", GFC_STD_GNU);
}
- add_sym_1 ("dfloat", GFC_ISYM_REAL, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dd, GFC_STD_GNU,
+ make_generic ("float", GFC_ISYM_FLOAT, GFC_STD_F77);
+
+ add_sym_1 ("dfloat", GFC_ISYM_DFLOAT, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dd, GFC_STD_GNU,
gfc_check_float, gfc_simplify_dble, gfc_resolve_dble,
a, BT_REAL, dr, REQUIRED);
- add_sym_1 ("sngl", GFC_ISYM_REAL, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F77,
+ make_generic ("dfloat", GFC_ISYM_DFLOAT, GFC_STD_F77);
+
+ add_sym_1 ("sngl", GFC_ISYM_SNGL, CLASS_ELEMENTAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F77,
gfc_check_sngl, gfc_simplify_sngl, NULL,
a, BT_REAL, dd, REQUIRED);
- make_generic ("real", GFC_ISYM_REAL, GFC_STD_F77);
+ make_generic ("sngl", GFC_ISYM_SNGL, GFC_STD_F77);
add_sym_2 ("rename", GFC_ISYM_RENAME, CLASS_IMPURE, ACTUAL_NO, BT_INTEGER, di,
GFC_STD_GNU, gfc_check_rename, NULL, gfc_resolve_rename,
@@ -4180,6 +4188,40 @@ sort_actual (const char *name, gfc_actual_arglist **ap,
if (f == NULL && a == NULL) /* No arguments */
return true;
+ /* ALLOCATED has two mutually exclusive keywords, but only one
+ can be present at time and neither is optional. */
+ if (strcmp (name, "allocated") == 0 && a->name)
+ {
+ if (strcmp (a->name, "scalar") == 0)
+ {
+ if (a->next)
+ goto whoops;
+ if (a->expr->rank != 0)
+ {
+ gfc_error ("Scalar entity required at %L", &a->expr->where);
+ return false;
+ }
+ return true;
+ }
+ else if (strcmp (a->name, "array") == 0)
+ {
+ if (a->next)
+ goto whoops;
+ if (a->expr->rank == 0)
+ {
+ gfc_error ("Array entity required at %L", &a->expr->where);
+ return false;
+ }
+ return true;
+ }
+ else
+ {
+ gfc_error ("Invalid keyword %qs in %qs intrinsic function at %L",
+ a->name, name, &a->expr->where);
+ return false;
+ }
+ }
+
for (;;)
{ /* Put the nonkeyword arguments in a 1:1 correspondence */
if (f == NULL)
@@ -4199,6 +4241,7 @@ sort_actual (const char *name, gfc_actual_arglist **ap,
if (a == NULL)
goto do_sort;
+whoops:
gfc_error ("Too many arguments in call to %qs at %L", name, where);
return false;
@@ -4798,7 +4841,8 @@ gfc_intrinsic_func_interface (gfc_expr *expr, int error_flag)
}
if ((isym->id == GFC_ISYM_REAL || isym->id == GFC_ISYM_DBLE
- || isym->id == GFC_ISYM_CMPLX)
+ || isym->id == GFC_ISYM_CMPLX || isym->id == GFC_ISYM_FLOAT
+ || isym->id == GFC_ISYM_SNGL || isym->id == GFC_ISYM_DFLOAT)
&& gfc_init_expr_flag
&& !gfc_notify_std (GFC_STD_F2003, "Function %qs as initialization "
"expression at %L", name, &expr->where))
diff --git a/gcc/fortran/intrinsic.texi b/gcc/fortran/intrinsic.texi
index f390761..3aa068d 100644
--- a/gcc/fortran/intrinsic.texi
+++ b/gcc/fortran/intrinsic.texi
@@ -11792,10 +11792,10 @@ end program test_random_seed
Returns a single pseudorandom number or an array of pseudorandom numbers
from the uniform distribution over the range @math{ 0 \leq x < 1}.
-The runtime-library implements the xorshift1024* random number
-generator (RNG). This generator has a period of @math{2^{1024} - 1},
-and when using multiple threads up to @math{2^{512}} threads can each
-generate @math{2^{512}} random numbers before any aliasing occurs.
+The runtime-library implements the xoshiro256** pseudorandom number
+generator (PRNG). This generator has a period of @math{2^{256} - 1},
+and when using multiple threads up to @math{2^{128}} threads can each
+generate @math{2^{128}} random numbers before any aliasing occurs.
Note that in a multi-threaded program (e.g. using OpenMP directives),
each thread will have its own random number state. For details of the
@@ -11852,7 +11852,7 @@ called either without arguments or with the @var{PUT} argument, the
given seed is copied into a master seed as well as the seed of the
current thread. When a new thread uses @code{RANDOM_NUMBER} for the
first time, the seed is copied from the master seed, and forwarded
-@math{N * 2^{512}} steps to guarantee that the random stream does not
+@math{N * 2^{128}} steps to guarantee that the random stream does not
alias any other stream in the system, where @var{N} is the number of
threads that have used @code{RANDOM_NUMBER} so far during the program
execution.
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index f8efcd8..1039c608 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -116,13 +116,13 @@ by type. Explanations are in the following sections.
@table @emph
@item Fortran Language Options
@xref{Fortran Dialect Options,,Options controlling Fortran dialect}.
-@gccoptlist{-fall-intrinsics -fbackslash -fcray-pointer -fd-lines-as-code @gol
--fd-lines-as-comments -fdec -fdec-structure -fdec-intrinsic-ints @gol
--fdec-static -fdec-math -fdec-include -fdec-format-defaults @gol
--fdec-blank-format-item -fdefault-double-8 -fdefault-integer-8 @gol
--fdefault-real-8 -fdefault-real-10 -fdefault-real-16 -fdollar-ok @gol
--ffixed-line-length-@var{n} -ffixed-line-length-none -fpad-source @gol
--ffree-form -ffree-line-length-@var{n} -ffree-line-length-none @gol
+@gccoptlist{-fall-intrinsics -fallow-invalid-boz -fbackslash -fcray-pointer @gol
+-fd-lines-as-code -fd-lines-as-comments -fdec -fdec-structure @gol
+-fdec-intrinsic-ints -fdec-static -fdec-math -fdec-include @gol
+-fdec-format-defaults -fdec-blank-format-item -fdefault-double-8 @gol
+-fdefault-integer-8 -fdefault-real-8 -fdefault-real-10 -fdefault-real-16 @gol
+-fdollar-ok @gol -ffixed-line-length-@var{n} -ffixed-line-length-none @gol
+-fpad-source -ffree-form -ffree-line-length-@var{n} -ffree-line-length-none @gol
-fimplicit-none -finteger-4-integer-8 -fmax-identifier-length @gol
-fmodule-private -ffixed-form -fno-range-check -fopenacc -fopenmp @gol
-freal-4-real-10 -freal-4-real-16 -freal-4-real-8 -freal-8-real-10 @gol
@@ -157,7 +157,8 @@ and warnings}.
@item Debugging Options
@xref{Debugging Options,,Options for debugging your program or GNU Fortran}.
@gccoptlist{-fbacktrace -fdump-fortran-optimized -fdump-fortran-original @gol
--fdump-parse-tree -ffpe-trap=@var{list} -ffpe-summary=@var{list}
+-fdump-fortran-global -fdump-parse-tree -ffpe-trap=@var{list} @gol
+-ffpe-summary=@var{list}
}
@item Directory Options
@@ -231,6 +232,13 @@ available with @command{gfortran}. As a consequence, @option{-Wintrinsics-std}
will be ignored and no user-defined procedure with the same name as any
intrinsic will be called except when it is explicitly declared @code{EXTERNAL}.
+@item -fallow-invalid-boz
+@opindex @code{allow-invalid-boz}
+A BOZ literal constant can occur in a limited number of context in
+standard conforming Fortran. This option degrades an error condition
+to a warning, and allows a BOZ literal constant to appear where the
+Fortran standard would otherwise prohibits it.
+
@item -fd-lines-as-code
@itemx -fd-lines-as-comments
@opindex @code{fd-lines-as-code}
@@ -1192,6 +1200,14 @@ change between releases. This option may also generate internal
compiler errors for features which have only recently been added. This
option is deprecated; use @code{-fdump-fortran-original} instead.
+@item -fdump-fortran-global
+@opindex @code{fdump-fortran-global}
+Output a list of the global identifiers after translating into
+middle-end representation. Mostly useful for debugging the GNU Fortran
+compiler itself. The output generated by this option might change
+between releases. This option may also generate internal compiler
+errors for features which have only recently been added.
+
@item -ffpe-trap=@var{list}
@opindex @code{ffpe-trap=}@var{list}
Specify a list of floating point exception traps to enable. On most
@@ -1704,7 +1720,7 @@ This option currently only affects local arrays declared with constant
bounds, and may not apply to all character variables.
Future versions of GNU Fortran may improve this behavior.
-The default value for @var{n} is 32768.
+The default value for @var{n} is 65536.
@item -fstack-arrays
@opindex @code{fstack-arrays}
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index 88674cb..85113a7 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -377,6 +377,10 @@ fall-intrinsics
Fortran RejectNegative Var(flag_all_intrinsics)
All intrinsics procedures are available regardless of selected standard.
+fallow-invalid-boz
+Fortran RejectNegative Var(flag_allow_invalid_boz)
+Allow a BOZ literal constant to appear in an invalid context.
+
fallow-leading-underscore
Fortran Undocumented Var(flag_allow_leading_underscore)
; For internal use only: allow the first character of symbol names to be an underscore
@@ -508,6 +512,10 @@ fdump-fortran-optimized
Fortran Var(flag_dump_fortran_optimized)
Display the code tree after front end optimization.
+fdump-fortran-global
+Fortran Var(flag_dump_fortran_global)
+Display the global symbol table after parsing.
+
fdump-parse-tree
Fortran Alias(fdump-fortran-original)
Display the code tree after parsing; deprecated option.
diff --git a/gcc/fortran/libgfortran.h b/gcc/fortran/libgfortran.h
index f82fc6a..30cb6ef 100644
--- a/gcc/fortran/libgfortran.h
+++ b/gcc/fortran/libgfortran.h
@@ -174,6 +174,6 @@ typedef enum
typedef enum
{ BT_UNKNOWN = 0, BT_INTEGER, BT_LOGICAL, BT_REAL, BT_COMPLEX,
BT_DERIVED, BT_CHARACTER, BT_CLASS, BT_PROCEDURE, BT_HOLLERITH, BT_VOID,
- BT_ASSUMED, BT_UNION
+ BT_ASSUMED, BT_UNION, BT_BOZ
}
bt;
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 0f3b213..f148a02 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -5552,6 +5552,15 @@ gfc_match_equivalence (void)
gfc_common_head *common_head = NULL;
bool common_flag;
int cnt;
+ char c;
+
+ /* EQUIVALENCE has been matched. After gobbling any possible whitespace,
+ the next character needs to be '('. Check that here, and return
+ MATCH_NO for a variable of the form equivalencej. */
+ gfc_gobble_whitespace ();
+ c = gfc_peek_ascii_char ();
+ if (c != '(')
+ return MATCH_NO;
tail = NULL;
@@ -5742,7 +5751,29 @@ gfc_match_st_function (void)
gfc_symbol *sym;
gfc_expr *expr;
match m;
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ locus old_locus;
+ bool fcn;
+ gfc_formal_arglist *ptr;
+
+ /* Read the possible statement function name, and then check to see if
+ a symbol is already present in the namespace. Record if it is a
+ function and whether it has been referenced. */
+ fcn = false;
+ ptr = NULL;
+ old_locus = gfc_current_locus;
+ m = gfc_match_name (name);
+ if (m == MATCH_YES)
+ {
+ gfc_find_symbol (name, NULL, 1, &sym);
+ if (sym && sym->attr.function && !sym->attr.referenced)
+ {
+ fcn = true;
+ ptr = sym->formal;
+ }
+ }
+ gfc_current_locus = old_locus;
m = gfc_match_symbol (&sym, 0);
if (m != MATCH_YES)
return m;
@@ -5770,6 +5801,13 @@ gfc_match_st_function (void)
return MATCH_ERROR;
}
+ if (fcn && ptr != sym->formal)
+ {
+ gfc_error ("Statement function %qs at %L conflicts with function name",
+ sym->name, &expr->where);
+ return MATCH_ERROR;
+ }
+
sym->value = expr;
if ((gfc_current_state () == COMP_FUNCTION
diff --git a/gcc/fortran/misc.c b/gcc/fortran/misc.c
index ec31fb9..eed203d 100644
--- a/gcc/fortran/misc.c
+++ b/gcc/fortran/misc.c
@@ -100,6 +100,9 @@ gfc_basic_typename (bt type)
case BT_VOID:
p = "VOID";
break;
+ case BT_BOZ:
+ p = "BOZ";
+ break;
case BT_UNKNOWN:
p = "UNKNOWN";
break;
@@ -125,6 +128,7 @@ gfc_typename (gfc_typespec *ts)
static char buffer2[GFC_MAX_SYMBOL_LEN + 7];
static int flag = 0;
char *buffer;
+ gfc_typespec *ts1;
buffer = flag ? buffer1 : buffer2;
flag = !flag;
@@ -156,9 +160,8 @@ gfc_typename (gfc_typespec *ts)
sprintf (buffer, "TYPE(%s)", ts->u.derived->name);
break;
case BT_CLASS:
- if (ts->u.derived->components)
- ts = &ts->u.derived->components->ts;
- if (ts->u.derived->attr.unlimited_polymorphic)
+ ts1 = ts->u.derived->components ? &ts->u.derived->components->ts : NULL;
+ if (ts1 && ts1->u.derived && ts1->u.derived->attr.unlimited_polymorphic)
sprintf (buffer, "CLASS(*)");
else
sprintf (buffer, "CLASS(%s)", ts->u.derived->name);
@@ -169,6 +172,9 @@ gfc_typename (gfc_typespec *ts)
case BT_PROCEDURE:
strcpy (buffer, "PROCEDURE");
break;
+ case BT_BOZ:
+ strcpy (buffer, "BOZ");
+ break;
case BT_UNKNOWN:
strcpy (buffer, "UNKNOWN");
break;
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index 9c8ae13..533445e 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -525,6 +525,8 @@ gfc_match_use (void)
gfc_intrinsic_op op;
match m;
gfc_use_list *use_list;
+ gfc_symtree *st;
+ locus loc;
use_list = gfc_get_use_list ();
@@ -632,6 +634,8 @@ gfc_match_use (void)
case INTERFACE_USER_OP:
case INTERFACE_GENERIC:
case INTERFACE_DTIO:
+ loc = gfc_current_locus;
+
m = gfc_match (" =>");
if (type == INTERFACE_USER_OP && m == MATCH_YES
@@ -642,6 +646,18 @@ gfc_match_use (void)
if (type == INTERFACE_USER_OP)
new_use->op = INTRINSIC_USER;
+ st = gfc_find_symtree (gfc_current_ns->sym_root, name);
+ if (st && type != INTERFACE_USER_OP)
+ {
+ if (m == MATCH_YES)
+ gfc_error ("Symbol %qs at %L conflicts with the rename symbol "
+ "at %L", name, &st->n.sym->declared_at, &loc);
+ else
+ gfc_error ("Symbol %qs at %L conflicts with the symbol "
+ "at %L", name, &st->n.sym->declared_at, &loc);
+ goto cleanup;
+ }
+
if (use_list->only_flag)
{
if (m != MATCH_YES)
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index ef37ccc..146be2f 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -437,7 +437,7 @@ gfc_post_options (const char **pfilename)
/* Set default. */
if (flag_max_stack_var_size == -2)
- flag_max_stack_var_size = 32768;
+ flag_max_stack_var_size = 65536;
/* Implement -fno-automatic as -fmax-stack-var-size=0. */
if (!flag_automatic)
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 8947299..31466d2 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -6319,6 +6319,12 @@ done:
/* Do the resolution. */
resolve_all_program_units (gfc_global_ns_list);
+
+ /* Fixup for external procedures. */
+ for (gfc_current_ns = gfc_global_ns_list; gfc_current_ns;
+ gfc_current_ns = gfc_current_ns->sibling)
+ gfc_check_externals (gfc_current_ns);
+
/* Do the parse tree dump. */
gfc_current_ns = flag_dump_fortran_original ? gfc_global_ns_list : NULL;
@@ -6366,6 +6372,13 @@ done:
/* Do the translation. */
translate_all_program_units (gfc_global_ns_list);
+ /* Dump the global symbol ist. We only do this here because part
+ of it is generated after mangling the identifiers in
+ trans-decl.c. */
+
+ if (flag_dump_fortran_global)
+ gfc_dump_global_symbols (stdout);
+
gfc_end_source_files ();
return true;
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index e918372..a33a797 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -189,6 +189,55 @@ match_digits (int signflag, int radix, char *buffer)
return length;
}
+/* Convert an integer string to an expression node. */
+
+static gfc_expr *
+convert_integer (const char *buffer, int kind, int radix, locus *where)
+{
+ gfc_expr *e;
+ const char *t;
+
+ e = gfc_get_constant_expr (BT_INTEGER, kind, where);
+ /* A leading plus is allowed, but not by mpz_set_str. */
+ if (buffer[0] == '+')
+ t = buffer + 1;
+ else
+ t = buffer;
+ mpz_set_str (e->value.integer, t, radix);
+
+ return e;
+}
+
+
+/* Convert a real string to an expression node. */
+
+static gfc_expr *
+convert_real (const char *buffer, int kind, locus *where)
+{
+ gfc_expr *e;
+
+ e = gfc_get_constant_expr (BT_REAL, kind, where);
+ mpfr_set_str (e->value.real, buffer, 10, GFC_RND_MODE);
+
+ return e;
+}
+
+
+/* Convert a pair of real, constant expression nodes to a single
+ complex expression node. */
+
+static gfc_expr *
+convert_complex (gfc_expr *real, gfc_expr *imag, int kind)
+{
+ gfc_expr *e;
+
+ e = gfc_get_constant_expr (BT_COMPLEX, kind, &real->where);
+ mpc_set_fr_fr (e->value.complex, real->value.real, imag->value.real,
+ GFC_MPC_RND_MODE);
+
+ return e;
+}
+
/* Match an integer (digit string and optional kind).
A sign will be accepted if signflag is set. */
@@ -231,7 +280,7 @@ match_integer_constant (gfc_expr **result, int signflag)
return MATCH_ERROR;
}
- e = gfc_convert_integer (buffer, kind, 10, &gfc_current_locus);
+ e = convert_integer (buffer, kind, 10, &gfc_current_locus);
e->ts.is_c_interop = is_iso_c;
if (gfc_range_check (e) != ARITH_OK)
@@ -337,7 +386,7 @@ cleanup:
static match
match_boz_constant (gfc_expr **result)
{
- int radix, length, x_hex, kind;
+ int radix, length, x_hex;
locus old_loc, start_loc;
char *buffer, post, delim;
gfc_expr *e;
@@ -383,9 +432,9 @@ match_boz_constant (gfc_expr **result)
goto backup;
if (x_hex
- && (!gfc_notify_std(GFC_STD_GNU, "Hexadecimal "
- "constant at %C uses non-standard syntax")))
- return MATCH_ERROR;
+ && gfc_invalid_boz ("Hexadecimal constant at %L uses "
+ "nonstandard syntax", &gfc_current_locus))
+ return MATCH_ERROR;
old_loc = gfc_current_locus;
@@ -421,8 +470,8 @@ match_boz_constant (gfc_expr **result)
goto backup;
}
- if (!gfc_notify_std (GFC_STD_GNU, "BOZ constant "
- "at %C uses non-standard postfix syntax"))
+ if (gfc_invalid_boz ("BOZ constant at %C uses nonstandard postfix "
+ "syntax", &gfc_current_locus))
return MATCH_ERROR;
}
@@ -436,30 +485,19 @@ match_boz_constant (gfc_expr **result)
if (post == 1)
gfc_next_ascii_char (); /* Eat postfixed b, o, z, or x. */
- /* In section 5.2.5 and following C567 in the Fortran 2003 standard, we find
- "If a data-stmt-constant is a boz-literal-constant, the corresponding
- variable shall be of type integer. The boz-literal-constant is treated
- as if it were an int-literal-constant with a kind-param that specifies
- the representation method with the largest decimal exponent range
- supported by the processor." */
-
- kind = gfc_max_integer_kind;
- e = gfc_convert_integer (buffer, kind, radix, &gfc_current_locus);
-
- /* Mark as boz variable. */
- e->is_boz = 1;
-
- if (gfc_range_check (e) != ARITH_OK)
- {
- gfc_error ("Integer too big for integer kind %i at %C", kind);
- gfc_free_expr (e);
- return MATCH_ERROR;
- }
+ e = gfc_get_expr ();
+ e->expr_type = EXPR_CONSTANT;
+ e->ts.type = BT_BOZ;
+ e->where = gfc_current_locus;
+ e->boz.rdx = radix;
+ e->boz.len = length;
+ e->boz.str = XCNEWVEC (char, length + 1);
+ strncpy (e->boz.str, buffer, length);
if (!gfc_in_match_data ()
&& (!gfc_notify_std(GFC_STD_F2003, "BOZ used outside a DATA "
- "statement at %C")))
- return MATCH_ERROR;
+ "statement at %L", &e->where)))
+ return MATCH_ERROR;
*result = e;
return MATCH_YES;
@@ -715,7 +753,7 @@ done:
}
}
- e = gfc_convert_real (buffer, kind, &gfc_current_locus);
+ e = convert_real (buffer, kind, &gfc_current_locus);
if (negate)
mpfr_neg (e->value.real, e->value.real, GFC_RND_MODE);
e->ts.is_c_interop = is_iso_c;
@@ -1433,7 +1471,7 @@ match_complex_constant (gfc_expr **result)
if (imag->ts.type != BT_REAL || kind != imag->ts.kind)
gfc_convert_type (imag, &target, 2);
- e = gfc_convert_complex (real, imag, kind);
+ e = convert_complex (real, imag, kind);
e->where = gfc_current_locus;
gfc_free_expr (real);
@@ -2559,12 +2597,10 @@ gfc_variable_attr (gfc_expr *expr, gfc_typespec *ts)
break;
case AR_UNKNOWN:
- /* If any of start, end or stride is not integer, there will
- already have been an error issued. */
- int errors;
- gfc_get_errors (NULL, &errors);
- if (errors == 0)
- gfc_internal_error ("gfc_variable_attr(): Bad array reference");
+ /* For standard conforming code, AR_UNKNOWN should not happen.
+ For nonconforming code, gfortran can end up here. Treat it
+ as a no-op. */
+ break;
}
break;
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index c82e8f2..1f48045 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -2506,8 +2506,7 @@ gfc_explicit_interface_required (gfc_symbol *sym, char *errmsg, int err_len)
static void
-resolve_global_procedure (gfc_symbol *sym, locus *where,
- gfc_actual_arglist **actual, int sub)
+resolve_global_procedure (gfc_symbol *sym, locus *where, int sub)
{
gfc_gsymbol * gsym;
gfc_namespace *ns;
@@ -2615,14 +2614,6 @@ resolve_global_procedure (gfc_symbol *sym, locus *where,
" %s", sym->name, &sym->declared_at, reason);
goto done;
}
-
- if (!pedantic
- || ((gfc_option.warn_std & GFC_STD_LEGACY)
- && !(gfc_option.warn_std & GFC_STD_GNU)))
- gfc_errors_to_warnings (true);
-
- if (sym->attr.if_source != IFSRC_IFBODY)
- gfc_procedure_use (def_sym, actual, where);
}
done:
@@ -3198,8 +3189,7 @@ resolve_function (gfc_expr *expr)
/* If the procedure is external, check for usage. */
if (sym && is_external_proc (sym))
- resolve_global_procedure (sym, &expr->where,
- &expr->value.function.actual, 0);
+ resolve_global_procedure (sym, &expr->where, 0);
if (sym && sym->ts.type == BT_CHARACTER
&& sym->ts.u.cl
@@ -3675,7 +3665,7 @@ resolve_call (gfc_code *c)
/* If external, check for usage. */
if (csym && is_external_proc (csym))
- resolve_global_procedure (csym, &c->loc, &c->ext.actual, 1);
+ resolve_global_procedure (csym, &c->loc, 1);
t = true;
if (c->resolved_sym == NULL)
@@ -3930,6 +3920,14 @@ resolve_operator (gfc_expr *e)
case INTRINSIC_PARENTHESES:
if (!gfc_resolve_expr (e->value.op.op1))
return false;
+ if (e->value.op.op1
+ && e->value.op.op1->ts.type == BT_BOZ && !e->value.op.op2)
+ {
+ gfc_error ("BOZ literal constant at %L cannot be an operand of "
+ "unary operator %qs", &e->value.op.op1->where,
+ gfc_op2string (e->value.op.op));
+ return false;
+ }
break;
}
@@ -3939,6 +3937,16 @@ resolve_operator (gfc_expr *e)
op2 = e->value.op.op2;
dual_locus_error = false;
+ /* op1 and op2 cannot both be BOZ. */
+ if (op1 && op1->ts.type == BT_BOZ
+ && op2 && op2->ts.type == BT_BOZ)
+ {
+ gfc_error ("Operands at %L and %L cannot appear as operands of "
+ "binary operator %qs", &op1->where, &op2->where,
+ gfc_op2string (e->value.op.op));
+ return false;
+ }
+
if ((op1 && op1->expr_type == EXPR_NULL)
|| (op2 && op2->expr_type == EXPR_NULL))
{
@@ -4092,6 +4100,36 @@ resolve_operator (gfc_expr *e)
break;
}
+ /* If op1 is BOZ, then op2 is not!. Try to convert to type of op2. */
+ if (op1->ts.type == BT_BOZ)
+ {
+ if (gfc_invalid_boz ("BOZ literal constant near %L cannot appear as "
+ "an operand of a relational operator",
+ &op1->where))
+ return false;
+
+ if (op2->ts.type == BT_INTEGER && !gfc_boz2int (op1, op2->ts.kind))
+ return false;
+
+ if (op2->ts.type == BT_REAL && !gfc_boz2real (op1, op2->ts.kind))
+ return false;
+ }
+
+ /* If op2 is BOZ, then op1 is not!. Try to convert to type of op2. */
+ if (op2->ts.type == BT_BOZ)
+ {
+ if (gfc_invalid_boz ("BOZ literal constant near %L cannot appear as "
+ "an operand of a relational operator",
+ &op2->where))
+ return false;
+
+ if (op1->ts.type == BT_INTEGER && !gfc_boz2int (op2, op1->ts.kind))
+ return false;
+
+ if (op1->ts.type == BT_REAL && !gfc_boz2real (op2, op1->ts.kind))
+ return false;
+ }
+
if (gfc_numeric_ts (&op1->ts) && gfc_numeric_ts (&op2->ts))
{
gfc_type_convert_binary (e, 1);
@@ -6432,6 +6470,7 @@ resolve_compcall (gfc_expr* e, const char **name)
return false;
}
+
/* These must not be assign-calls! */
gcc_assert (!e->value.compcall.assign);
@@ -10473,44 +10512,32 @@ resolve_ordinary_assign (gfc_code *code, gfc_namespace *ns)
lhs = code->expr1;
rhs = code->expr2;
- if (rhs->is_boz
- && !gfc_notify_std (GFC_STD_GNU, "BOZ literal at %L outside "
- "a DATA statement and outside INT/REAL/DBLE/CMPLX",
- &code->loc))
- return false;
-
/* Handle the case of a BOZ literal on the RHS. */
- if (rhs->is_boz && lhs->ts.type != BT_INTEGER)
+ if (rhs->ts.type == BT_BOZ)
{
- int rc;
- if (warn_surprising)
- gfc_warning (OPT_Wsurprising,
- "BOZ literal at %L is bitwise transferred "
- "non-integer symbol %qs", &code->loc,
- lhs->symtree->n.sym->name);
-
- if (!gfc_convert_boz (rhs, &lhs->ts))
+ if (gfc_invalid_boz ("BOZ literal constant at %L is neither a DATA "
+ "statement value nor an actual argument of "
+ "INT/REAL/DBLE/CMPLX intrinsic subprogram",
+ &rhs->where))
return false;
- if ((rc = gfc_range_check (rhs)) != ARITH_OK)
- {
- if (rc == ARITH_UNDERFLOW)
- gfc_error ("Arithmetic underflow of bit-wise transferred BOZ at %L"
- ". This check can be disabled with the option "
- "%<-fno-range-check%>", &rhs->where);
- else if (rc == ARITH_OVERFLOW)
- gfc_error ("Arithmetic overflow of bit-wise transferred BOZ at %L"
- ". This check can be disabled with the option "
- "%<-fno-range-check%>", &rhs->where);
- else if (rc == ARITH_NAN)
- gfc_error ("Arithmetic NaN of bit-wise transferred BOZ at %L"
- ". This check can be disabled with the option "
- "%<-fno-range-check%>", &rhs->where);
+
+ switch (lhs->ts.type)
+ {
+ case BT_INTEGER:
+ if (!gfc_boz2int (rhs, lhs->ts.kind))
+ return false;
+ break;
+ case BT_REAL:
+ if (!gfc_boz2real (rhs, lhs->ts.kind))
+ return false;
+ break;
+ default:
+ gfc_error ("Invalid use of BOZ literal constant at %L", &rhs->where);
return false;
}
}
- if (lhs->ts.type == BT_CHARACTER
- && warn_character_truncation)
+ if (lhs->ts.type == BT_CHARACTER && warn_character_truncation)
{
HOST_WIDE_INT llen = 0, rlen = 0;
if (lhs->ts.u.cl != NULL
@@ -13546,14 +13573,34 @@ resolve_typebound_procedure (gfc_symtree* stree)
}
else
{
+ /* If proc has not been resolved at this point, proc->name may
+ actually be a USE associated entity. See PR fortran/89647. */
+ if (!proc->resolved
+ && proc->attr.function == 0 && proc->attr.subroutine == 0)
+ {
+ gfc_symbol *tmp;
+ gfc_find_symbol (proc->name, gfc_current_ns->parent, 1, &tmp);
+ if (tmp && tmp->attr.use_assoc)
+ {
+ proc->module = tmp->module;
+ proc->attr.proc = tmp->attr.proc;
+ proc->attr.function = tmp->attr.function;
+ proc->attr.subroutine = tmp->attr.subroutine;
+ proc->attr.use_assoc = tmp->attr.use_assoc;
+ proc->ts = tmp->ts;
+ proc->result = tmp->result;
+ }
+ }
+
/* Check for F08:C465. */
if ((!proc->attr.subroutine && !proc->attr.function)
|| (proc->attr.proc != PROC_MODULE
&& proc->attr.if_source != IFSRC_IFBODY)
|| proc->attr.abstract)
{
- gfc_error ("%qs must be a module procedure or an external procedure with"
- " an explicit interface at %L", proc->name, &where);
+ gfc_error ("%qs must be a module procedure or an external "
+ "procedure with an explicit interface at %L",
+ proc->name, &where);
goto error;
}
}
@@ -15669,8 +15716,6 @@ check_data_variable (gfc_data_variable *var, locus *where)
return false;
}
- has_pointer = sym->attr.pointer;
-
if (gfc_is_coindexed (e))
{
gfc_error ("DATA element %qs at %L cannot have a coindex", sym->name,
@@ -15678,19 +15723,30 @@ check_data_variable (gfc_data_variable *var, locus *where)
return false;
}
+ has_pointer = sym->attr.pointer;
+
for (ref = e->ref; ref; ref = ref->next)
{
if (ref->type == REF_COMPONENT && ref->u.c.component->attr.pointer)
has_pointer = 1;
- if (has_pointer
- && ref->type == REF_ARRAY
- && ref->u.ar.type != AR_FULL)
- {
- gfc_error ("DATA element %qs at %L is a pointer and so must "
- "be a full array", sym->name, where);
- return false;
- }
+ if (has_pointer)
+ {
+ if (ref->type == REF_ARRAY && ref->u.ar.type != AR_FULL)
+ {
+ gfc_error ("DATA element %qs at %L is a pointer and so must "
+ "be a full array", sym->name, where);
+ return false;
+ }
+
+ if (values.vnode->expr->expr_type == EXPR_CONSTANT)
+ {
+ gfc_error ("DATA object near %L has the pointer attribute "
+ "and the corresponding DATA value is not a valid "
+ "initial-data-target", where);
+ return false;
+ }
+ }
}
if (e->rank == 0 || has_pointer)
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index 2d20913..5ab7c81 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -211,26 +211,6 @@ gfc_convert_mpz_to_signed (mpz_t x, int bitsize)
}
-/* In-place convert BOZ to REAL of the specified kind. */
-
-static gfc_expr *
-convert_boz (gfc_expr *x, int kind)
-{
- if (x && x->ts.type == BT_INTEGER && x->is_boz)
- {
- gfc_typespec ts;
- gfc_clear_ts (&ts);
- ts.type = BT_REAL;
- ts.kind = kind;
-
- if (!gfc_convert_boz (x, &ts))
- return &gfc_bad_expr;
- }
-
- return x;
-}
-
-
/* Test that the expression is a constant array, simplifying if
we are dealing with a parameter array. */
@@ -1660,12 +1640,6 @@ simplify_cmplx (const char *name, gfc_expr *x, gfc_expr *y, int kind)
{
gfc_expr *result;
- if (convert_boz (x, kind) == &gfc_bad_expr)
- return &gfc_bad_expr;
-
- if (convert_boz (y, kind) == &gfc_bad_expr)
- return &gfc_bad_expr;
-
if (x->expr_type != EXPR_CONSTANT
|| (y != NULL && y->expr_type != EXPR_CONSTANT))
return NULL;
@@ -2219,9 +2193,6 @@ gfc_simplify_dble (gfc_expr *e)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- if (convert_boz (e, gfc_default_double_kind) == &gfc_bad_expr)
- return &gfc_bad_expr;
-
result = gfc_convert_constant (e, BT_REAL, gfc_default_double_kind);
if (result == &gfc_bad_expr)
return &gfc_bad_expr;
@@ -2965,15 +2936,7 @@ gfc_simplify_float (gfc_expr *a)
if (a->expr_type != EXPR_CONSTANT)
return NULL;
- if (a->is_boz)
- {
- if (convert_boz (a, gfc_default_real_kind) == &gfc_bad_expr)
- return &gfc_bad_expr;
-
- result = gfc_copy_expr (a);
- }
- else
- result = gfc_int2real (a, gfc_default_real_kind);
+ result = gfc_int2real (a, gfc_default_real_kind);
return range_check (result, "FLOAT");
}
@@ -3610,6 +3573,15 @@ simplify_intconv (gfc_expr *e, int kind, const char *name)
{
gfc_expr *result = NULL;
+ /* Convert BOZ to integer, and return without range checking. */
+ if (e->ts.type == BT_BOZ)
+ {
+ if (!gfc_boz2int (e, kind))
+ return NULL;
+ result = gfc_copy_expr (e);
+ return result;
+ }
+
if (e->expr_type != EXPR_CONSTANT)
return NULL;
@@ -6497,6 +6469,21 @@ gfc_simplify_real (gfc_expr *e, gfc_expr *k)
gfc_expr *result = NULL;
int kind;
+ /* Convert BOZ to real, and return without range checking. */
+ if (e->ts.type == BT_BOZ)
+ {
+ /* Determine kind for conversion of the BOZ. */
+ if (k)
+ gfc_extract_int (k, &kind);
+ else
+ kind = gfc_default_real_kind;
+
+ if (!gfc_boz2real (e, kind))
+ return NULL;
+ result = gfc_copy_expr (e);
+ return result;
+ }
+
if (e->ts.type == BT_COMPLEX)
kind = get_kind (BT_REAL, k, "REAL", e->ts.kind);
else
@@ -6508,9 +6495,6 @@ gfc_simplify_real (gfc_expr *e, gfc_expr *k)
if (e->expr_type != EXPR_CONSTANT)
return NULL;
- if (convert_boz (e, kind) == &gfc_bad_expr)
- return &gfc_bad_expr;
-
result = gfc_convert_constant (e, BT_REAL, kind);
if (result == &gfc_bad_expr)
return &gfc_bad_expr;
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index f427363..cc5b5ef 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -407,8 +407,8 @@ gfc_check_function_type (gfc_namespace *ns)
goto conflict_std;\
}
-static bool
-check_conflict (symbol_attribute *attr, const char *name, locus *where)
+bool
+gfc_check_conflict (symbol_attribute *attr, const char *name, locus *where)
{
static const char *dummy = "DUMMY", *save = "SAVE", *pointer = "POINTER",
*target = "TARGET", *external = "EXTERNAL", *intent = "INTENT",
@@ -544,7 +544,6 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
conf (allocatable, elemental);
conf (in_common, automatic);
- conf (in_equivalence, automatic);
conf (result, automatic);
conf (use_assoc, automatic);
conf (dummy, automatic);
@@ -1004,7 +1003,7 @@ gfc_add_attribute (symbol_attribute *attr, locus *where)
if (check_used (attr, NULL, where))
return false;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
@@ -1030,7 +1029,7 @@ gfc_add_allocatable (symbol_attribute *attr, locus *where)
}
attr->allocatable = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
@@ -1045,7 +1044,7 @@ gfc_add_automatic (symbol_attribute *attr, const char *name, locus *where)
return false;
attr->automatic = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1071,7 +1070,7 @@ gfc_add_codimension (symbol_attribute *attr, const char *name, locus *where)
}
attr->codimension = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1097,7 +1096,7 @@ gfc_add_dimension (symbol_attribute *attr, const char *name, locus *where)
}
attr->dimension = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1109,7 +1108,7 @@ gfc_add_contiguous (symbol_attribute *attr, const char *name, locus *where)
return false;
attr->contiguous = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1134,7 +1133,7 @@ gfc_add_external (symbol_attribute *attr, locus *where)
attr->external = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
@@ -1153,7 +1152,7 @@ gfc_add_intrinsic (symbol_attribute *attr, locus *where)
attr->intrinsic = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
@@ -1171,7 +1170,7 @@ gfc_add_optional (symbol_attribute *attr, locus *where)
}
attr->optional = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
bool
@@ -1184,7 +1183,7 @@ gfc_add_kind (symbol_attribute *attr, locus *where)
}
attr->pdt_kind = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
bool
@@ -1197,7 +1196,7 @@ gfc_add_len (symbol_attribute *attr, locus *where)
}
attr->pdt_len = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
@@ -1222,7 +1221,7 @@ gfc_add_pointer (symbol_attribute *attr, locus *where)
else
attr->pointer = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
@@ -1234,7 +1233,7 @@ gfc_add_cray_pointer (symbol_attribute *attr, locus *where)
return false;
attr->cray_pointer = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
@@ -1253,7 +1252,7 @@ gfc_add_cray_pointee (symbol_attribute *attr, locus *where)
}
attr->cray_pointee = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
@@ -1272,7 +1271,7 @@ gfc_add_protected (symbol_attribute *attr, const char *name, locus *where)
}
attr->is_protected = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1284,7 +1283,7 @@ gfc_add_result (symbol_attribute *attr, const char *name, locus *where)
return false;
attr->result = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1317,7 +1316,7 @@ gfc_add_save (symbol_attribute *attr, save_state s, const char *name,
}
attr->save = s;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1337,7 +1336,7 @@ gfc_add_value (symbol_attribute *attr, const char *name, locus *where)
}
attr->value = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1370,7 +1369,7 @@ gfc_add_volatile (symbol_attribute *attr, const char *name, locus *where)
attr->volatile_ = 1;
attr->volatile_ns = gfc_current_ns;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1389,7 +1388,7 @@ gfc_add_asynchronous (symbol_attribute *attr, const char *name, locus *where)
attr->asynchronous = 1;
attr->asynchronous_ns = gfc_current_ns;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1407,7 +1406,7 @@ gfc_add_threadprivate (symbol_attribute *attr, const char *name, locus *where)
}
attr->threadprivate = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1423,7 +1422,7 @@ gfc_add_omp_declare_target (symbol_attribute *attr, const char *name,
return true;
attr->omp_declare_target = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1439,7 +1438,7 @@ gfc_add_omp_declare_target_link (symbol_attribute *attr, const char *name,
return true;
attr->omp_declare_target_link = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1454,7 +1453,7 @@ gfc_add_oacc_declare_create (symbol_attribute *attr, const char *name,
return true;
attr->oacc_declare_create = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1469,7 +1468,7 @@ gfc_add_oacc_declare_copyin (symbol_attribute *attr, const char *name,
return true;
attr->oacc_declare_copyin = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1484,7 +1483,7 @@ gfc_add_oacc_declare_deviceptr (symbol_attribute *attr, const char *name,
return true;
attr->oacc_declare_deviceptr = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1499,7 +1498,7 @@ gfc_add_oacc_declare_device_resident (symbol_attribute *attr, const char *name,
return true;
attr->oacc_declare_device_resident = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1517,7 +1516,7 @@ gfc_add_target (symbol_attribute *attr, locus *where)
}
attr->target = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
@@ -1530,7 +1529,7 @@ gfc_add_dummy (symbol_attribute *attr, const char *name, locus *where)
/* Duplicate dummy arguments are allowed due to ENTRY statements. */
attr->dummy = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1543,7 +1542,7 @@ gfc_add_in_common (symbol_attribute *attr, const char *name, locus *where)
/* Duplicate attribute already checked for. */
attr->in_common = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1553,7 +1552,7 @@ gfc_add_in_equivalence (symbol_attribute *attr, const char *name, locus *where)
/* Duplicate attribute already checked for. */
attr->in_equivalence = 1;
- if (!check_conflict (attr, name, where))
+ if (!gfc_check_conflict (attr, name, where))
return false;
if (attr->flavor == FL_VARIABLE)
@@ -1571,7 +1570,7 @@ gfc_add_data (symbol_attribute *attr, const char *name, locus *where)
return false;
attr->data = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1580,7 +1579,7 @@ gfc_add_in_namelist (symbol_attribute *attr, const char *name, locus *where)
{
attr->in_namelist = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1592,7 +1591,7 @@ gfc_add_sequence (symbol_attribute *attr, const char *name, locus *where)
return false;
attr->sequence = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1610,7 +1609,7 @@ gfc_add_elemental (symbol_attribute *attr, locus *where)
}
attr->elemental = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
@@ -1628,7 +1627,7 @@ gfc_add_pure (symbol_attribute *attr, locus *where)
}
attr->pure = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
@@ -1646,7 +1645,7 @@ gfc_add_recursive (symbol_attribute *attr, locus *where)
}
attr->recursive = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
@@ -1664,7 +1663,7 @@ gfc_add_entry (symbol_attribute *attr, const char *name, locus *where)
}
attr->entry = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1677,7 +1676,7 @@ gfc_add_function (symbol_attribute *attr, const char *name, locus *where)
return false;
attr->function = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1696,7 +1695,7 @@ gfc_add_subroutine (symbol_attribute *attr, const char *name, locus *where)
compiler-generated), do not check. See PR 84394. */
if (name && *name != '_' && gfc_current_state () != COMP_BLOCK_DATA)
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
else
return true;
}
@@ -1711,7 +1710,7 @@ gfc_add_generic (symbol_attribute *attr, const char *name, locus *where)
return false;
attr->generic = 1;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1734,7 +1733,7 @@ gfc_add_proc (symbol_attribute *attr, const char *name, locus *where)
attr->procedure = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
@@ -1749,7 +1748,7 @@ gfc_add_abstract (symbol_attribute* attr, locus* where)
attr->abstract = 1;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
@@ -1795,7 +1794,7 @@ gfc_add_flavor (symbol_attribute *attr, sym_flavor f, const char *name,
attr->flavor = f;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1842,7 +1841,7 @@ gfc_add_procedure (symbol_attribute *attr, procedure_type t,
|| attr->dimension))
return false;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -1856,7 +1855,7 @@ gfc_add_intent (symbol_attribute *attr, sym_intent intent, locus *where)
if (attr->intent == INTENT_UNKNOWN)
{
attr->intent = intent;
- return check_conflict (attr, NULL, where);
+ return gfc_check_conflict (attr, NULL, where);
}
if (where == NULL)
@@ -1881,7 +1880,7 @@ gfc_add_access (symbol_attribute *attr, gfc_access access,
|| (attr->use_assoc && attr->access != ACCESS_PRIVATE))
{
attr->access = access;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
if (where == NULL)
@@ -1913,7 +1912,7 @@ gfc_add_is_bind_c (symbol_attribute *attr, const char *name, locus *where,
if (!gfc_notify_std (GFC_STD_F2003, "BIND(C) at %L", where))
return false;
- return check_conflict (attr, name, where);
+ return gfc_check_conflict (attr, name, where);
}
@@ -4244,6 +4243,7 @@ save_symbol (gfc_symbol *sym)
return;
if (sym->attr.in_common
+ || sym->attr.in_equivalence
|| sym->attr.dummy
|| sym->attr.result
|| sym->attr.flavor != FL_VARIABLE)
@@ -4357,6 +4357,19 @@ gfc_get_gsymbol (const char *name, bool bind_c)
return s;
}
+void
+gfc_traverse_gsymbol (gfc_gsymbol *gsym,
+ void (*do_something) (gfc_gsymbol *, void *),
+ void *data)
+{
+ if (gsym->left)
+ gfc_traverse_gsymbol (gsym->left, do_something, data);
+
+ (*do_something) (gsym, data);
+
+ if (gsym->right)
+ gfc_traverse_gsymbol (gsym->right, do_something, data);
+}
static gfc_symbol *
get_iso_c_binding_dt (int sym_id)
diff --git a/gcc/fortran/target-memory.c b/gcc/fortran/target-memory.c
index 1354c57..1b23a44 100644
--- a/gcc/fortran/target-memory.c
+++ b/gcc/fortran/target-memory.c
@@ -769,35 +769,19 @@ gfc_convert_boz (gfc_expr *expr, gfc_typespec *ts)
int index;
unsigned char *buffer;
- if (!expr->is_boz)
+ if (expr->ts.type != BT_INTEGER)
return true;
- gcc_assert (expr->expr_type == EXPR_CONSTANT
- && expr->ts.type == BT_INTEGER);
-
/* Don't convert BOZ to logical, character, derived etc. */
- if (ts->type == BT_REAL)
- {
- buffer_size = size_float (ts->kind);
- ts_bit_size = buffer_size * 8;
- }
- else if (ts->type == BT_COMPLEX)
- {
- buffer_size = size_complex (ts->kind);
- ts_bit_size = buffer_size * 8 / 2;
- }
- else
- return true;
+ gcc_assert (ts->type == BT_REAL);
+
+ buffer_size = size_float (ts->kind);
+ ts_bit_size = buffer_size * 8;
/* Convert BOZ to the smallest possible integer kind. */
boz_bit_size = mpz_sizeinbase (expr->value.integer, 2);
- if (boz_bit_size > ts_bit_size)
- {
- gfc_error_now ("BOZ constant at %L is too large (%ld vs %ld bits)",
- &expr->where, (long) boz_bit_size, (long) ts_bit_size);
- return false;
- }
+ gcc_assert (boz_bit_size <= ts_bit_size);
for (index = 0; gfc_integer_kinds[index].kind != 0; ++index)
if ((unsigned) gfc_integer_kinds[index].bit_size >= ts_bit_size)
@@ -810,18 +794,9 @@ gfc_convert_boz (gfc_expr *expr, gfc_typespec *ts)
encode_integer (expr->ts.kind, expr->value.integer, buffer, buffer_size);
mpz_clear (expr->value.integer);
- if (ts->type == BT_REAL)
- {
- mpfr_init (expr->value.real);
- gfc_interpret_float (ts->kind, buffer, buffer_size, expr->value.real);
- }
- else
- {
- mpc_init2 (expr->value.complex, mpfr_get_default_prec());
- gfc_interpret_complex (ts->kind, buffer, buffer_size,
- expr->value.complex);
- }
- expr->is_boz = 0;
+ mpfr_init (expr->value.real);
+ gfc_interpret_float (ts->kind, buffer, buffer_size, expr->value.real);
+
expr->ts.type = ts->type;
expr->ts.kind = ts->kind;
diff --git a/gcc/fortran/trans-common.c b/gcc/fortran/trans-common.c
index 9fc23ff..18ad60f 100644
--- a/gcc/fortran/trans-common.c
+++ b/gcc/fortran/trans-common.c
@@ -339,7 +339,7 @@ build_field (segment_info *h, tree union_type, record_layout_info rli)
/* Get storage for local equivalence. */
static tree
-build_equiv_decl (tree union_type, bool is_init, bool is_saved)
+build_equiv_decl (tree union_type, bool is_init, bool is_saved, bool is_auto)
{
tree decl;
char name[18];
@@ -359,8 +359,8 @@ build_equiv_decl (tree union_type, bool is_init, bool is_saved)
DECL_ARTIFICIAL (decl) = 1;
DECL_IGNORED_P (decl) = 1;
- if (!gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
- || is_saved)
+ if (!is_auto && (!gfc_can_put_var_on_stack (DECL_SIZE_UNIT (decl))
+ || is_saved))
TREE_STATIC (decl) = 1;
TREE_ADDRESSABLE (decl) = 1;
@@ -611,6 +611,7 @@ create_common (gfc_common_head *com, segment_info *head, bool saw_equiv)
tree decl;
bool is_init = false;
bool is_saved = false;
+ bool is_auto = false;
/* Declare the variables inside the common block.
If the current common block contains any equivalence object, then
@@ -654,6 +655,10 @@ create_common (gfc_common_head *com, segment_info *head, bool saw_equiv)
/* Has SAVE attribute. */
if (s->sym->attr.save)
is_saved = true;
+
+ /* Has AUTOMATIC attribute. */
+ if (s->sym->attr.automatic)
+ is_auto = true;
}
finish_record_layout (rli, true);
@@ -661,7 +666,7 @@ create_common (gfc_common_head *com, segment_info *head, bool saw_equiv)
if (com)
decl = build_common_decl (com, union_type, is_init);
else
- decl = build_equiv_decl (union_type, is_init, is_saved);
+ decl = build_equiv_decl (union_type, is_init, is_saved, is_auto);
if (is_init)
{
@@ -948,6 +953,59 @@ add_condition (segment_info *f, gfc_equiv *eq1, gfc_equiv *eq2)
confirm_condition (f, eq1, n, eq2);
}
+static void
+accumulate_equivalence_attributes (symbol_attribute *dummy_symbol, gfc_equiv *e)
+{
+ symbol_attribute attr = e->expr->symtree->n.sym->attr;
+
+ dummy_symbol->dummy |= attr.dummy;
+ dummy_symbol->pointer |= attr.pointer;
+ dummy_symbol->target |= attr.target;
+ dummy_symbol->external |= attr.external;
+ dummy_symbol->intrinsic |= attr.intrinsic;
+ dummy_symbol->allocatable |= attr.allocatable;
+ dummy_symbol->elemental |= attr.elemental;
+ dummy_symbol->recursive |= attr.recursive;
+ dummy_symbol->in_common |= attr.in_common;
+ dummy_symbol->result |= attr.result;
+ dummy_symbol->in_namelist |= attr.in_namelist;
+ dummy_symbol->optional |= attr.optional;
+ dummy_symbol->entry |= attr.entry;
+ dummy_symbol->function |= attr.function;
+ dummy_symbol->subroutine |= attr.subroutine;
+ dummy_symbol->dimension |= attr.dimension;
+ dummy_symbol->in_equivalence |= attr.in_equivalence;
+ dummy_symbol->use_assoc |= attr.use_assoc;
+ dummy_symbol->cray_pointer |= attr.cray_pointer;
+ dummy_symbol->cray_pointee |= attr.cray_pointee;
+ dummy_symbol->data |= attr.data;
+ dummy_symbol->value |= attr.value;
+ dummy_symbol->volatile_ |= attr.volatile_;
+ dummy_symbol->is_protected |= attr.is_protected;
+ dummy_symbol->is_bind_c |= attr.is_bind_c;
+ dummy_symbol->procedure |= attr.procedure;
+ dummy_symbol->proc_pointer |= attr.proc_pointer;
+ dummy_symbol->abstract |= attr.abstract;
+ dummy_symbol->asynchronous |= attr.asynchronous;
+ dummy_symbol->codimension |= attr.codimension;
+ dummy_symbol->contiguous |= attr.contiguous;
+ dummy_symbol->generic |= attr.generic;
+ dummy_symbol->automatic |= attr.automatic;
+ dummy_symbol->threadprivate |= attr.threadprivate;
+ dummy_symbol->omp_declare_target |= attr.omp_declare_target;
+ dummy_symbol->omp_declare_target_link |= attr.omp_declare_target_link;
+ dummy_symbol->oacc_declare_copyin |= attr.oacc_declare_copyin;
+ dummy_symbol->oacc_declare_create |= attr.oacc_declare_create;
+ dummy_symbol->oacc_declare_deviceptr |= attr.oacc_declare_deviceptr;
+ dummy_symbol->oacc_declare_device_resident
+ |= attr.oacc_declare_device_resident;
+
+ /* Not strictly correct, but probably close enough. */
+ if (attr.save > dummy_symbol->save)
+ dummy_symbol->save = attr.save;
+ if (attr.access > dummy_symbol->access)
+ dummy_symbol->access = attr.access;
+}
/* Given a segment element, search through the equivalence lists for unused
conditions that involve the symbol. Add these rules to the segment. */
@@ -965,9 +1023,12 @@ find_equivalence (segment_info *n)
eq = NULL;
/* Search the equivalence list, including the root (first) element
- for the symbol that owns the segment. */
+ for the symbol that owns the segment. */
+ symbol_attribute dummy_symbol;
+ memset (&dummy_symbol, 0, sizeof (dummy_symbol));
for (e2 = e1; e2; e2 = e2->eq)
{
+ accumulate_equivalence_attributes (&dummy_symbol, e2);
if (!e2->used && e2->expr->symtree->n.sym == n->sym)
{
eq = e2;
@@ -975,6 +1036,8 @@ find_equivalence (segment_info *n)
}
}
+ gfc_check_conflict (&dummy_symbol, e1->expr->symtree->name, &e1->expr->where);
+
/* Go to the next root element. */
if (eq == NULL)
continue;
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 64ce4bb..3c6ab60 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -102,7 +102,7 @@ tree gfor_fndecl_error_stop_string;
tree gfor_fndecl_runtime_error;
tree gfor_fndecl_runtime_error_at;
tree gfor_fndecl_runtime_warning_at;
-tree gfor_fndecl_os_error;
+tree gfor_fndecl_os_error_at;
tree gfor_fndecl_generate_error;
tree gfor_fndecl_set_args;
tree gfor_fndecl_set_fpe;
@@ -345,39 +345,45 @@ gfc_get_label_decl (gfc_st_label * lp)
}
}
+/* Return the name of an identifier. */
-/* Convert a gfc_symbol to an identifier of the same name. */
-
-static tree
-gfc_sym_identifier (gfc_symbol * sym)
+static const char *
+sym_identifier (gfc_symbol *sym)
{
if (sym->attr.is_main_program && strcmp (sym->name, "main") == 0)
- return (get_identifier ("MAIN__"));
+ return "MAIN__";
else
- return (get_identifier (sym->name));
+ return sym->name;
}
-
-/* Construct mangled name from symbol name. */
+/* Convert a gfc_symbol to an identifier of the same name. */
static tree
-gfc_sym_mangled_identifier (gfc_symbol * sym)
+gfc_sym_identifier (gfc_symbol * sym)
{
- char name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
+ return get_identifier (sym_identifier (sym));
+}
+
+/* Construct mangled name from symbol name. */
+static const char *
+mangled_identifier (gfc_symbol *sym)
+{
+ static char name[GFC_MAX_MANGLED_SYMBOL_LEN + 1];
/* Prevent the mangling of identifiers that have an assigned
binding label (mainly those that are bind(c)). */
+
if (sym->attr.is_bind_c == 1 && sym->binding_label)
- return get_identifier (sym->binding_label);
+ return sym->binding_label;
if (!sym->fn_result_spec)
{
if (sym->module == NULL)
- return gfc_sym_identifier (sym);
+ return sym_identifier (sym);
else
{
snprintf (name, sizeof name, "__%s_MOD_%s", sym->module, sym->name);
- return get_identifier (name);
+ return name;
}
}
else
@@ -392,17 +398,40 @@ gfc_sym_mangled_identifier (gfc_symbol * sym)
sym->ns->proc_name->module,
sym->ns->proc_name->name,
sym->name);
- return get_identifier (name);
+ return name;
}
else
{
snprintf (name, sizeof name, "__%s_PROC_%s",
sym->ns->proc_name->name, sym->name);
- return get_identifier (name);
+ return name;
}
}
}
+/* Get mangled identifier, adding the symbol to the global table if
+ it is not yet already there. */
+
+static tree
+gfc_sym_mangled_identifier (gfc_symbol * sym)
+{
+ tree result;
+ gfc_gsymbol *gsym;
+ const char *name;
+
+ name = mangled_identifier (sym);
+ result = get_identifier (name);
+
+ gsym = gfc_find_gsymbol (gfc_gsym_root, name);
+ if (gsym == NULL)
+ {
+ gsym = gfc_get_gsymbol (name, false);
+ gsym->ns = sym->ns;
+ gsym->sym_name = sym->name;
+ }
+
+ return result;
+}
/* Construct mangled function name from symbol name. */
@@ -724,6 +753,16 @@ gfc_finish_var_decl (tree decl, gfc_symbol * sym)
|| sym->attr.allocatable)
&& !DECL_ARTIFICIAL (decl))
{
+ gfc_warning (OPT_Wsurprising,
+ "Array %qs at %L is larger than limit set by"
+ " %<-fmax-stack-var-size=%>, moved from stack to static"
+ " storage. This makes the procedure unsafe when called"
+ " recursively, or concurrently from multiple threads."
+ " Consider using %<-frecursive%>, or increase the"
+ " %<-fmax-stack-var-size=%> limit, or change the code to"
+ " use an ALLOCATABLE array.",
+ sym->name, &sym->declared_at);
+
TREE_STATIC (decl) = 1;
/* Because the size of this variable isn't known until now, we may have
@@ -1914,6 +1953,22 @@ get_proc_pointer_decl (gfc_symbol *sym)
tree decl;
tree attributes;
+ if (sym->module || sym->fn_result_spec)
+ {
+ const char *name;
+ gfc_gsymbol *gsym;
+
+ name = mangled_identifier (sym);
+ gsym = gfc_find_gsymbol (gfc_gsym_root, name);
+ if (gsym != NULL)
+ {
+ gfc_symbol *s;
+ gfc_find_symbol (sym->name, gsym->ns, 0, &s);
+ if (s && s->backend_decl)
+ return s->backend_decl;
+ }
+ }
+
decl = sym->backend_decl;
if (decl)
return decl;
@@ -3624,11 +3679,11 @@ gfc_build_builtin_function_decls (void)
void_type_node, 3, pvoid_type_node, integer_type_node,
pchar_type_node);
- gfor_fndecl_os_error = gfc_build_library_function_decl_with_spec (
- get_identifier (PREFIX("os_error")), ".R",
- void_type_node, 1, pchar_type_node);
- /* The runtime_error function does not return. */
- TREE_THIS_VOLATILE (gfor_fndecl_os_error) = 1;
+ gfor_fndecl_os_error_at = gfc_build_library_function_decl_with_spec (
+ get_identifier (PREFIX("os_error_at")), ".RR",
+ void_type_node, -2, pchar_type_node, pchar_type_node);
+ /* The os_error_at function does not return. */
+ TREE_THIS_VOLATILE (gfor_fndecl_os_error_at) = 1;
gfor_fndecl_set_args = gfc_build_library_function_decl (
get_identifier (PREFIX("set_args")),
@@ -6404,6 +6459,20 @@ gfc_generate_return (void)
TREE_TYPE (result), DECL_RESULT (fndecl),
result);
}
+ else
+ {
+ /* If the function does not have a result variable, result is
+ NULL_TREE, and a 'return' is generated without a variable.
+ The following generates a 'return __result_XXX' where XXX is
+ the function name. */
+ if (sym == sym->result && sym->attr.function)
+ {
+ result = gfc_get_fake_result_decl (sym, 0);
+ result = fold_build2_loc (input_location, MODIFY_EXPR,
+ TREE_TYPE (result),
+ DECL_RESULT (fndecl), result);
+ }
+ }
}
return build1_v (RETURN_EXPR, result);
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index a4e8351..2adc112 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -10796,7 +10796,8 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
if (expr1->ts.deferred
&& gfc_expr_attr (expr1).allocatable
&& gfc_check_dependency (expr1, expr2, true))
- rse.string_length = gfc_evaluate_now (rse.string_length, &rse.pre);
+ rse.string_length =
+ gfc_evaluate_now_function_scope (rse.string_length, &rse.pre);
string_length = rse.string_length;
}
else
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index a6e3383..26ea624 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -5428,7 +5428,7 @@ gfc_conv_intrinsic_findloc (gfc_se *se, gfc_expr *expr)
tree type;
tree tmp;
tree found;
- tree forward_branch;
+ tree forward_branch = NULL_TREE;
tree back_branch;
gfc_loopinfo loop;
gfc_ss *arrayss;
@@ -9930,9 +9930,13 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr)
break;
case GFC_ISYM_CONVERSION:
- case GFC_ISYM_REAL:
- case GFC_ISYM_LOGICAL:
case GFC_ISYM_DBLE:
+ case GFC_ISYM_DFLOAT:
+ case GFC_ISYM_FLOAT:
+ case GFC_ISYM_LOGICAL:
+ case GFC_ISYM_REAL:
+ case GFC_ISYM_REALPART:
+ case GFC_ISYM_SNGL:
gfc_conv_intrinsic_conversion (se, expr);
break;
diff --git a/gcc/fortran/trans.c b/gcc/fortran/trans.c
index 303abd9..583f6e3 100644
--- a/gcc/fortran/trans.c
+++ b/gcc/fortran/trans.c
@@ -118,6 +118,19 @@ gfc_evaluate_now (tree expr, stmtblock_t * pblock)
return gfc_evaluate_now_loc (input_location, expr, pblock);
}
+/* Like gfc_evaluate_now, but add the created variable to the
+ function scope. */
+
+tree
+gfc_evaluate_now_function_scope (tree expr, stmtblock_t * pblock)
+{
+ tree var;
+ var = gfc_create_var_np (TREE_TYPE (expr), NULL);
+ gfc_add_decl_to_function (var);
+ gfc_add_modify (pblock, var, expr);
+
+ return var;
+}
/* Build a MODIFY_EXPR node and add it to a given statement block PBLOCK.
A MODIFY_EXPR is an assignment:
@@ -434,7 +447,7 @@ gfc_build_array_ref (tree base, tree offset, tree decl, tree vptr)
arguments and a locus. */
static tree
-trans_runtime_error_vararg (bool error, locus* where, const char* msgid,
+trans_runtime_error_vararg (tree errorfunc, locus* where, const char* msgid,
va_list ap)
{
stmtblock_t block;
@@ -488,18 +501,13 @@ trans_runtime_error_vararg (bool error, locus* where, const char* msgid,
/* Build the function call to runtime_(warning,error)_at; because of the
variable number of arguments, we can't use build_call_expr_loc dinput_location,
irectly. */
- if (error)
- fntype = TREE_TYPE (gfor_fndecl_runtime_error_at);
- else
- fntype = TREE_TYPE (gfor_fndecl_runtime_warning_at);
+ fntype = TREE_TYPE (errorfunc);
loc = where ? where->lb->location : input_location;
tmp = fold_build_call_array_loc (loc, TREE_TYPE (fntype),
fold_build1_loc (loc, ADDR_EXPR,
build_pointer_type (fntype),
- error
- ? gfor_fndecl_runtime_error_at
- : gfor_fndecl_runtime_warning_at),
+ errorfunc),
nargs + 2, argarray);
gfc_add_expr_to_block (&block, tmp);
@@ -514,7 +522,10 @@ gfc_trans_runtime_error (bool error, locus* where, const char* msgid, ...)
tree result;
va_start (ap, msgid);
- result = trans_runtime_error_vararg (error, where, msgid, ap);
+ result = trans_runtime_error_vararg (error
+ ? gfor_fndecl_runtime_error_at
+ : gfor_fndecl_runtime_warning_at,
+ where, msgid, ap);
va_end (ap);
return result;
}
@@ -553,8 +564,10 @@ gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock,
/* The code to generate the error. */
va_start (ap, msgid);
gfc_add_expr_to_block (&block,
- trans_runtime_error_vararg (error, where,
- msgid, ap));
+ trans_runtime_error_vararg
+ (error ? gfor_fndecl_runtime_error_at
+ : gfor_fndecl_runtime_warning_at,
+ where, msgid, ap));
va_end (ap);
if (once)
@@ -582,13 +595,28 @@ gfc_trans_runtime_check (bool error, bool once, tree cond, stmtblock_t * pblock,
}
+static tree
+trans_os_error_at (locus* where, const char* msgid, ...)
+{
+ va_list ap;
+ tree result;
+
+ va_start (ap, msgid);
+ result = trans_runtime_error_vararg (gfor_fndecl_os_error_at,
+ where, msgid, ap);
+ va_end (ap);
+ return result;
+}
+
+
+
/* Call malloc to allocate size bytes of memory, with special conditions:
+ if size == 0, return a malloced area of size 1,
+ if malloc returns NULL, issue a runtime error. */
tree
gfc_call_malloc (stmtblock_t * block, tree type, tree size)
{
- tree tmp, msg, malloc_result, null_result, res, malloc_tree;
+ tree tmp, malloc_result, null_result, res, malloc_tree;
stmtblock_t block2;
/* Create a variable to hold the result. */
@@ -613,13 +641,14 @@ gfc_call_malloc (stmtblock_t * block, tree type, tree size)
null_result = fold_build2_loc (input_location, EQ_EXPR,
logical_type_node, res,
build_int_cst (pvoid_type_node, 0));
- msg = gfc_build_addr_expr (pchar_type_node,
- gfc_build_localized_cstring_const ("Memory allocation failed"));
tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
null_result,
- build_call_expr_loc (input_location,
- gfor_fndecl_os_error, 1, msg),
- build_empty_stmt (input_location));
+ trans_os_error_at (NULL,
+ "Error allocating %lu bytes",
+ fold_convert
+ (long_unsigned_type_node,
+ size)),
+ build_empty_stmt (input_location));
gfc_add_expr_to_block (&block2, tmp);
}
@@ -688,11 +717,9 @@ gfc_allocate_using_malloc (stmtblock_t * block, tree pointer,
}
else
{
- /* Here, os_error already implies PRED_NORETURN. */
- tmp = build_call_expr_loc (input_location, gfor_fndecl_os_error, 1,
- gfc_build_addr_expr (pchar_type_node,
- gfc_build_localized_cstring_const
- ("Allocation would exceed memory limit")));
+ /* Here, os_error_at already implies PRED_NORETURN. */
+ tree lusize = fold_convert (long_unsigned_type_node, size);
+ tmp = trans_os_error_at (NULL, "Error allocating %lu bytes", lusize);
gfc_add_expr_to_block (&on_error, tmp);
}
@@ -1651,7 +1678,7 @@ internal_realloc (void *mem, size_t size)
tree
gfc_call_realloc (stmtblock_t * block, tree mem, tree size)
{
- tree msg, res, nonzero, null_result, tmp;
+ tree res, nonzero, null_result, tmp;
tree type = TREE_TYPE (mem);
/* Only evaluate the size once. */
@@ -1671,12 +1698,12 @@ gfc_call_realloc (stmtblock_t * block, tree mem, tree size)
build_int_cst (size_type_node, 0));
null_result = fold_build2_loc (input_location, TRUTH_AND_EXPR, logical_type_node,
null_result, nonzero);
- msg = gfc_build_addr_expr (pchar_type_node, gfc_build_localized_cstring_const
- ("Allocation would exceed memory limit"));
tmp = fold_build3_loc (input_location, COND_EXPR, void_type_node,
null_result,
- build_call_expr_loc (input_location,
- gfor_fndecl_os_error, 1, msg),
+ trans_os_error_at (NULL,
+ "Error reallocating to %lu bytes",
+ fold_convert
+ (long_unsigned_type_node, size)),
build_empty_stmt (input_location));
gfc_add_expr_to_block (block, tmp);
diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h
index 0305d33..8082b41 100644
--- a/gcc/fortran/trans.h
+++ b/gcc/fortran/trans.h
@@ -507,6 +507,7 @@ void gfc_conv_label_variable (gfc_se * se, gfc_expr * expr);
/* If the value is not constant, Create a temporary and copy the value. */
tree gfc_evaluate_now_loc (location_t, tree, stmtblock_t *);
tree gfc_evaluate_now (tree, stmtblock_t *);
+tree gfc_evaluate_now_function_scope (tree, stmtblock_t *);
/* Find the appropriate variant of a math intrinsic. */
tree gfc_builtin_decl_for_float_kind (enum built_in_function, int);
@@ -802,7 +803,7 @@ extern GTY(()) tree gfor_fndecl_error_stop_string;
extern GTY(()) tree gfor_fndecl_runtime_error;
extern GTY(()) tree gfor_fndecl_runtime_error_at;
extern GTY(()) tree gfor_fndecl_runtime_warning_at;
-extern GTY(()) tree gfor_fndecl_os_error;
+extern GTY(()) tree gfor_fndecl_os_error_at;
extern GTY(()) tree gfor_fndecl_generate_error;
extern GTY(()) tree gfor_fndecl_set_fpe;
extern GTY(()) tree gfor_fndecl_set_options;
diff --git a/gcc/function.c b/gcc/function.c
index 2a0061c..e368f7c 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -2274,8 +2274,6 @@ struct assign_parm_data_one
int partial;
BOOL_BITFIELD named_arg : 1;
BOOL_BITFIELD passed_pointer : 1;
- BOOL_BITFIELD on_stack : 1;
- BOOL_BITFIELD loaded_in_reg : 1;
};
/* A subroutine of assign_parms. Initialize ALL. */
@@ -2813,8 +2811,9 @@ assign_parm_adjust_stack_rtl (struct assign_parm_data_one *data)
ultimate type, don't use that slot after entry. We'll make another
stack slot, if we need one. */
if (stack_parm
- && ((STRICT_ALIGNMENT
- && GET_MODE_ALIGNMENT (data->nominal_mode) > MEM_ALIGN (stack_parm))
+ && ((GET_MODE_ALIGNMENT (data->nominal_mode) > MEM_ALIGN (stack_parm)
+ && targetm.slow_unaligned_access (data->nominal_mode,
+ MEM_ALIGN (stack_parm)))
|| (data->nominal_type
&& TYPE_ALIGN (data->nominal_type) > MEM_ALIGN (stack_parm)
&& MEM_ALIGN (stack_parm) < PREFERRED_STACK_BOUNDARY)))
@@ -3128,6 +3127,7 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
int unsignedp = TYPE_UNSIGNED (TREE_TYPE (parm));
bool did_conversion = false;
bool need_conversion, moved;
+ enum insn_code icode;
rtx rtl;
/* Store the parm in a pseudoregister during the function, but we may
@@ -3189,7 +3189,6 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
conversion. We verify that this insn does not clobber any
hard registers. */
- enum insn_code icode;
rtx op0, op1;
icode = can_extend_p (promoted_nominal_mode, data->passed_mode,
@@ -3292,6 +3291,23 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
did_conversion = true;
}
+ else if (MEM_P (data->entry_parm)
+ && GET_MODE_ALIGNMENT (promoted_nominal_mode)
+ > MEM_ALIGN (data->entry_parm)
+ && (((icode = optab_handler (movmisalign_optab,
+ promoted_nominal_mode))
+ != CODE_FOR_nothing)
+ || targetm.slow_unaligned_access (promoted_nominal_mode,
+ MEM_ALIGN (data->entry_parm))))
+ {
+ if (icode != CODE_FOR_nothing)
+ emit_insn (GEN_FCN (icode) (parmreg, validated_mem));
+ else
+ rtl = parmreg = extract_bit_field (validated_mem,
+ GET_MODE_BITSIZE (promoted_nominal_mode), 0,
+ unsignedp, parmreg,
+ promoted_nominal_mode, VOIDmode, false, NULL);
+ }
else
emit_move_insn (parmreg, validated_mem);
diff --git a/gcc/gcc.c b/gcc/gcc.c
index a4323eb..1216cdd 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -8268,6 +8268,8 @@ driver::maybe_run_linker (const char *argv0) const
{
int tmp = execution_count;
+ detect_jobserver ();
+
if (! have_c)
{
#if HAVE_LTO_PLUGIN > 0
@@ -8357,6 +8359,46 @@ driver::final_actions () const
}
}
+/* Detect whether jobserver is active and working. If not drop
+ --jobserver-auth from MAKEFLAGS. */
+
+void
+driver::detect_jobserver () const
+{
+ /* Detect jobserver and drop it if it's not working. */
+ const char *makeflags = env.get ("MAKEFLAGS");
+ if (makeflags != NULL)
+ {
+ const char *needle = "--jobserver-auth=";
+ const char *n = strstr (makeflags, needle);
+ if (n != NULL)
+ {
+ int rfd = -1;
+ int wfd = -1;
+
+ bool jobserver
+ = (sscanf (n + strlen (needle), "%d,%d", &rfd, &wfd) == 2
+ && rfd > 0
+ && wfd > 0
+ && is_valid_fd (rfd)
+ && is_valid_fd (wfd));
+
+ /* Drop the jobserver if it's not working now. */
+ if (!jobserver)
+ {
+ unsigned offset = n - makeflags;
+ char *dup = xstrdup (makeflags);
+ dup[offset] = '\0';
+
+ const char *space = strchr (makeflags + offset, ' ');
+ if (space != NULL)
+ strcpy (dup + offset, space);
+ xputenv (concat ("MAKEFLAGS=", dup, NULL));
+ }
+ }
+ }
+}
+
/* Determine what the exit code of the driver should be. */
int
diff --git a/gcc/gcc.h b/gcc/gcc.h
index a0a1d94..dc77dba 100644
--- a/gcc/gcc.h
+++ b/gcc/gcc.h
@@ -51,6 +51,7 @@ class driver
void do_spec_on_infiles () const;
void maybe_run_linker (const char *argv0) const;
void final_actions () const;
+ void detect_jobserver () const;
int get_exit_code () const;
private:
diff --git a/gcc/gensupport.c b/gcc/gensupport.c
index 1aab711..c64f683 100644
--- a/gcc/gensupport.c
+++ b/gcc/gensupport.c
@@ -788,9 +788,10 @@ has_subst_attribute (class queue_elem *elem, class queue_elem *subst_elem)
return false;
case SET_ATTR_ALTERNATIVE:
- error_at (elem->loc,
- "%s: `set_attr_alternative' is unsupported by "
- "`define_subst'", XSTR (elem->data, 0));
+ if (strcmp (XSTR (cur_attr, 0), subst_name) == 0)
+ error_at (elem->loc,
+ "%s: `set_attr_alternative' is unsupported by "
+ "`define_subst'", XSTR (elem->data, 0));
return false;
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index be83620..d576b08 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -641,14 +641,7 @@ replace_call_with_call_and_fold (gimple_stmt_iterator *gsi, gimple *repl)
gimple *stmt = gsi_stmt (*gsi);
gimple_call_set_lhs (repl, gimple_call_lhs (stmt));
gimple_set_location (repl, gimple_location (stmt));
- if (gimple_vdef (stmt)
- && TREE_CODE (gimple_vdef (stmt)) == SSA_NAME)
- {
- gimple_set_vdef (repl, gimple_vdef (stmt));
- SSA_NAME_DEF_STMT (gimple_vdef (repl)) = repl;
- }
- if (gimple_vuse (stmt))
- gimple_set_vuse (repl, gimple_vuse (stmt));
+ gimple_move_vops (repl, stmt);
gsi_replace (gsi, repl, false);
fold_stmt (gsi);
}
@@ -832,11 +825,7 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
= gimple_build_assign (fold_build2 (MEM_REF, desttype,
dest, off0),
srcmem);
- gimple_set_vuse (new_stmt, gimple_vuse (stmt));
- gimple_set_vdef (new_stmt, gimple_vdef (stmt));
- if (gimple_vdef (new_stmt)
- && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
- SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
+ gimple_move_vops (new_stmt, stmt);
if (!lhs)
{
gsi_replace (gsi, new_stmt, false);
@@ -1097,11 +1086,7 @@ gimple_fold_builtin_memory_op (gimple_stmt_iterator *gsi,
= gimple_build_assign (fold_build2 (MEM_REF, desttype, dest, off0),
fold_build2 (MEM_REF, srctype, src, off0));
set_vop_and_replace:
- gimple_set_vuse (new_stmt, gimple_vuse (stmt));
- gimple_set_vdef (new_stmt, gimple_vdef (stmt));
- if (gimple_vdef (new_stmt)
- && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
- SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
+ gimple_move_vops (new_stmt, stmt);
if (!lhs)
{
gsi_replace (gsi, new_stmt, false);
@@ -1273,13 +1258,7 @@ gimple_fold_builtin_memset (gimple_stmt_iterator *gsi, tree c, tree len)
var = fold_build2 (MEM_REF, etype, dest, build_int_cst (ptr_type_node, 0));
gimple *store = gimple_build_assign (var, build_int_cst_type (etype, cval));
- gimple_set_vuse (store, gimple_vuse (stmt));
- tree vdef = gimple_vdef (stmt);
- if (vdef && TREE_CODE (vdef) == SSA_NAME)
- {
- gimple_set_vdef (store, gimple_vdef (stmt));
- SSA_NAME_DEF_STMT (gimple_vdef (stmt)) = store;
- }
+ gimple_move_vops (store, stmt);
gsi_insert_before (gsi, store, GSI_SAME_STMT);
if (gimple_call_lhs (stmt))
{
@@ -2982,11 +2961,7 @@ gimple_fold_builtin_stpcpy (gimple_stmt_iterator *gsi)
tem, build_int_cst (size_type_node, 1));
gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
gcall *repl = gimple_build_call (fn, 3, dest, src, lenp1);
- gimple_set_vuse (repl, gimple_vuse (stmt));
- gimple_set_vdef (repl, gimple_vdef (stmt));
- if (gimple_vdef (repl)
- && TREE_CODE (gimple_vdef (repl)) == SSA_NAME)
- SSA_NAME_DEF_STMT (gimple_vdef (repl)) = repl;
+ gimple_move_vops (repl, stmt);
gsi_insert_before (gsi, repl, GSI_SAME_STMT);
/* Replace the result with dest + len. */
stmts = NULL;
@@ -3751,7 +3726,7 @@ gimple_fold_builtin_strlen (gimple_stmt_iterator *gsi)
/* Set the strlen() range to [0, MAXLEN]. */
if (tree lhs = gimple_call_lhs (stmt))
- set_strlen_range (lhs, maxlen);
+ set_strlen_range (lhs, minlen, maxlen);
return false;
}
@@ -4134,9 +4109,7 @@ fold_builtin_atomic_compare_exchange (gimple_stmt_iterator *gsi)
gimple_call_arg (stmt, 5));
tree lhs = make_ssa_name (ctype);
gimple_call_set_lhs (g, lhs);
- gimple_set_vdef (g, gimple_vdef (stmt));
- gimple_set_vuse (g, gimple_vuse (stmt));
- SSA_NAME_DEF_STMT (gimple_vdef (g)) = g;
+ gimple_move_vops (g, stmt);
tree oldlhs = gimple_call_lhs (stmt);
if (stmt_can_throw_internal (cfun, stmt))
{
@@ -4207,6 +4180,63 @@ arith_overflowed_p (enum tree_code code, const_tree type,
return wi::min_precision (wres, sign) > TYPE_PRECISION (type);
}
+/* If IFN_MASK_LOAD/STORE call CALL is unconditional, return a MEM_REF
+ for the memory it references, otherwise return null. VECTYPE is the
+ type of the memory vector. */
+
+static tree
+gimple_fold_mask_load_store_mem_ref (gcall *call, tree vectype)
+{
+ tree ptr = gimple_call_arg (call, 0);
+ tree alias_align = gimple_call_arg (call, 1);
+ tree mask = gimple_call_arg (call, 2);
+ if (!tree_fits_uhwi_p (alias_align) || !integer_all_onesp (mask))
+ return NULL_TREE;
+
+ unsigned HOST_WIDE_INT align = tree_to_uhwi (alias_align) * BITS_PER_UNIT;
+ if (TYPE_ALIGN (vectype) != align)
+ vectype = build_aligned_type (vectype, align);
+ tree offset = build_zero_cst (TREE_TYPE (alias_align));
+ return fold_build2 (MEM_REF, vectype, ptr, offset);
+}
+
+/* Try to fold IFN_MASK_LOAD call CALL. Return true on success. */
+
+static bool
+gimple_fold_mask_load (gimple_stmt_iterator *gsi, gcall *call)
+{
+ tree lhs = gimple_call_lhs (call);
+ if (!lhs)
+ return false;
+
+ if (tree rhs = gimple_fold_mask_load_store_mem_ref (call, TREE_TYPE (lhs)))
+ {
+ gassign *new_stmt = gimple_build_assign (lhs, rhs);
+ gimple_set_location (new_stmt, gimple_location (call));
+ gimple_move_vops (new_stmt, call);
+ gsi_replace (gsi, new_stmt, false);
+ return true;
+ }
+ return false;
+}
+
+/* Try to fold IFN_MASK_STORE call CALL. Return true on success. */
+
+static bool
+gimple_fold_mask_store (gimple_stmt_iterator *gsi, gcall *call)
+{
+ tree rhs = gimple_call_arg (call, 3);
+ if (tree lhs = gimple_fold_mask_load_store_mem_ref (call, TREE_TYPE (rhs)))
+ {
+ gassign *new_stmt = gimple_build_assign (lhs, rhs);
+ gimple_set_location (new_stmt, gimple_location (call));
+ gimple_move_vops (new_stmt, call);
+ gsi_replace (gsi, new_stmt, false);
+ return true;
+ }
+ return false;
+}
+
/* Attempt to fold a call statement referenced by the statement iterator GSI.
The statement may be replaced by another statement, e.g., if the call
simplifies to a constant value. Return true if any changes were made.
@@ -4315,8 +4345,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
SSA_NAME_DEF_STMT (lhs) = gimple_build_nop ();
set_ssa_default_def (cfun, var, lhs);
}
- gimple_set_vuse (new_stmt, gimple_vuse (stmt));
- gimple_set_vdef (new_stmt, gimple_vdef (stmt));
+ gimple_move_vops (new_stmt, stmt);
gsi_replace (gsi, new_stmt, false);
return true;
}
@@ -4437,6 +4466,12 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
subcode = MULT_EXPR;
cplx_result = true;
break;
+ case IFN_MASK_LOAD:
+ changed |= gimple_fold_mask_load (gsi, stmt);
+ break;
+ case IFN_MASK_STORE:
+ changed |= gimple_fold_mask_store (gsi, stmt);
+ break;
default:
break;
}
diff --git a/gcc/gimple-loop-versioning.cc b/gcc/gimple-loop-versioning.cc
index be8c2d8..8fa1948 100644
--- a/gcc/gimple-loop-versioning.cc
+++ b/gcc/gimple-loop-versioning.cc
@@ -1489,7 +1489,7 @@ loop_versioning::prune_loop_conditions (class loop *loop, vr_values *vrs)
EXECUTE_IF_SET_IN_BITMAP (&li.unity_names, 0, i, bi)
{
tree name = ssa_name (i);
- value_range *vr = vrs->get_value_range (name);
+ const value_range *vr = vrs->get_value_range (name);
if (vr && !vr->may_contain_p (build_one_cst (TREE_TYPE (name))))
{
if (dump_enabled_p ())
diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c
index 46f5a01..68f317f 100644
--- a/gcc/gimple-ssa-evrp-analyze.c
+++ b/gcc/gimple-ssa-evrp-analyze.c
@@ -84,7 +84,7 @@ evrp_range_analyzer::try_find_new_range (tree name,
tree op, tree_code code, tree limit)
{
value_range vr;
- value_range *old_vr = get_value_range (name);
+ const value_range *old_vr = get_value_range (name);
/* Discover VR when condition is true. */
vr_values->extract_range_for_var_from_comparison_expr (name, code, op,
@@ -209,12 +209,15 @@ evrp_range_analyzer::record_ranges_from_incoming_edge (basic_block bb)
/* But make sure we do not weaken ranges like when
getting first [64, +INF] and then ~[0, 0] from
conditions like (s & 0x3cc0) == 0). */
- value_range *old_vr = get_value_range (vrs[i].first);
+ const value_range *old_vr = get_value_range (vrs[i].first);
value_range_base tem (old_vr->kind (), old_vr->min (),
old_vr->max ());
tem.intersect (vrs[i].second);
if (tem.equal_p (*old_vr))
- continue;
+ {
+ vr_values->free_value_range (vrs[i].second);
+ continue;
+ }
push_value_range (vrs[i].first, vrs[i].second);
if (is_fallthru
&& m_update_global_ranges
@@ -251,13 +254,18 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
if (virtual_operand_p (lhs))
continue;
+ /* Skips floats and other things we can't represent in a
+ range. */
+ if (!value_range_base::supports_type_p (TREE_TYPE (lhs)))
+ continue;
+
value_range vr_result;
bool interesting = stmt_interesting_for_vrp (phi);
if (!has_unvisited_preds && interesting)
vr_values->extract_range_from_phi_node (phi, &vr_result);
else
{
- vr_result.set_varying ();
+ vr_result.set_varying (TREE_TYPE (lhs));
/* When we have an unvisited executable predecessor we can't
use PHI arg ranges which may be still UNDEFINED but have
to use VARYING for them. But we can still resort to
@@ -393,7 +401,7 @@ evrp_range_analyzer::pop_to_marker (void)
{
gcc_checking_assert (!stack.is_empty ());
while (stack.last ().first != NULL_TREE)
- pop_value_range (stack.last ().first);
+ pop_value_range ();
stack.pop ();
}
@@ -421,17 +429,18 @@ evrp_range_analyzer::push_value_range (tree var, value_range *vr)
dump_value_range (dump_file, vr);
fprintf (dump_file, "\n");
}
- stack.safe_push (std::make_pair (var, get_value_range (var)));
- vr_values->set_vr_value (var, vr);
+ value_range *old_vr = vr_values->swap_vr_value (var, vr);
+ stack.safe_push (std::make_pair (var, old_vr));
}
-/* Pop the Value Range from the vrp_stack and update VAR with it. */
+/* Pop a Value Range from the vrp_stack. */
-value_range *
-evrp_range_analyzer::pop_value_range (tree var)
+void
+evrp_range_analyzer::pop_value_range ()
{
- value_range *vr = stack.last ().second;
- gcc_checking_assert (var == stack.last ().first);
+ std::pair<tree, value_range *> e = stack.pop ();
+ tree var = e.first;
+ value_range *vr = e.second;
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "popping range for ");
@@ -440,7 +449,9 @@ evrp_range_analyzer::pop_value_range (tree var)
dump_value_range (dump_file, vr);
fprintf (dump_file, "\n");
}
- vr_values->set_vr_value (var, vr);
- stack.pop ();
- return vr;
+ /* We saved off a lattice entry, now give it back and release
+ the one we popped. */
+ value_range *popped_vr = vr_values->swap_vr_value (var, vr);
+ if (popped_vr)
+ vr_values->free_value_range (popped_vr);
}
diff --git a/gcc/gimple-ssa-evrp-analyze.h b/gcc/gimple-ssa-evrp-analyze.h
index 1157027..a136cea 100644
--- a/gcc/gimple-ssa-evrp-analyze.h
+++ b/gcc/gimple-ssa-evrp-analyze.h
@@ -37,7 +37,7 @@ class evrp_range_analyzer
void record_ranges_from_stmt (gimple *, bool);
/* Main interface to retrieve range information. */
- value_range *get_value_range (const_tree op)
+ const value_range *get_value_range (const_tree op)
{ return vr_values->get_value_range (op); }
/* Record a new unwindable range. */
@@ -62,14 +62,14 @@ class evrp_range_analyzer
DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer);
class vr_values *vr_values;
- value_range *pop_value_range (tree var);
+ void pop_value_range ();
value_range *try_find_new_range (tree, tree op, tree_code code, tree limit);
void record_ranges_from_incoming_edge (basic_block);
void record_ranges_from_phis (basic_block);
void set_ssa_range_info (tree, value_range *);
/* STACK holds the old VR. */
- auto_vec<std::pair <tree, value_range*> > stack;
+ auto_vec<std::pair <tree, value_range *> > stack;
/* True if we are updating global ranges, false otherwise. */
bool m_update_global_ranges;
diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c
index 5b99388..c4ac137 100644
--- a/gcc/gimple-ssa-evrp.c
+++ b/gcc/gimple-ssa-evrp.c
@@ -109,7 +109,7 @@ evrp_dom_walker::before_dom_children (basic_block bb)
if (virtual_operand_p (lhs))
continue;
- value_range *vr = evrp_range_analyzer.get_value_range (lhs);
+ const value_range *vr = evrp_range_analyzer.get_value_range (lhs);
/* Mark PHIs whose lhs we fully propagate for removal. */
tree val;
if (vr->singleton_p (&val) && may_propagate_copy (lhs, val))
@@ -159,7 +159,8 @@ evrp_dom_walker::before_dom_children (basic_block bb)
if (output)
{
tree val;
- value_range *vr = evrp_range_analyzer.get_value_range (output);
+ const value_range *vr
+ = evrp_range_analyzer.get_value_range (output);
/* Mark stmts whose output we fully propagate for removal. */
if (vr->singleton_p (&val)
@@ -243,7 +244,7 @@ evrp_dom_walker::before_dom_children (basic_block bb)
if (TREE_CODE (arg) != SSA_NAME
|| virtual_operand_p (arg))
continue;
- value_range *vr = evrp_range_analyzer.get_value_range (arg);
+ const value_range *vr = evrp_range_analyzer.get_value_range (arg);
tree val;
if (vr->singleton_p (&val) && may_propagate_copy (arg, val))
propagate_value (use_p, val);
diff --git a/gcc/gimple-ssa-isolate-paths.c b/gcc/gimple-ssa-isolate-paths.c
index 72e6c77..aca5304 100644
--- a/gcc/gimple-ssa-isolate-paths.c
+++ b/gcc/gimple-ssa-isolate-paths.c
@@ -502,7 +502,7 @@ is_addr_local (gimple *return_stmt, tree exp, locmap_t *plocmap,
}
if (code == GIMPLE_CALL
- && gimple_call_builtin_p (def_stmt))
+ && gimple_call_builtin_p (def_stmt, BUILT_IN_NORMAL))
{
/* Handle alloca and friends that return pointers to automatic
storage. */
diff --git a/gcc/gimple-ssa-sprintf.c b/gcc/gimple-ssa-sprintf.c
index 6ba3d86..88ba1f2 100644
--- a/gcc/gimple-ssa-sprintf.c
+++ b/gcc/gimple-ssa-sprintf.c
@@ -1086,7 +1086,7 @@ get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
&& TYPE_PRECISION (argtype) <= TYPE_PRECISION (type))
{
/* Try to determine the range of values of the integer argument. */
- value_range *vr = vr_values->get_value_range (arg);
+ const value_range *vr = vr_values->get_value_range (arg);
if (range_int_cst_p (vr))
{
HOST_WIDE_INT type_min
@@ -1386,7 +1386,7 @@ format_integer (const directive &dir, tree arg, vr_values *vr_values)
{
/* Try to determine the range of values of the integer argument
(range information is not available for pointers). */
- value_range *vr = vr_values->get_value_range (arg);
+ const value_range *vr = vr_values->get_value_range (arg);
if (range_int_cst_p (vr))
{
argmin = vr->min ();
@@ -4119,7 +4119,7 @@ sprintf_dom_walker::handle_gimple_call (gimple_stmt_iterator *gsi)
/* Try to determine the range of values of the argument
and use the greater of the two at level 1 and the smaller
of them at level 2. */
- value_range *vr = evrp_range_analyzer.get_value_range (size);
+ const value_range *vr = evrp_range_analyzer.get_value_range (size);
if (range_int_cst_p (vr))
{
unsigned HOST_WIDE_INT minsize = TREE_INT_CST_LOW (vr->min ());
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 63c8d5e..633ef51 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1583,7 +1583,7 @@ gimple_call_nonnull_result_p (gcall *call)
if (!fndecl)
return false;
if (flag_delete_null_pointer_checks && !flag_check_new
- && DECL_IS_OPERATOR_NEW (fndecl)
+ && DECL_IS_OPERATOR_NEW_P (fndecl)
&& !TREE_NOTHROW (fndecl))
return true;
@@ -2057,6 +2057,18 @@ gimple_copy (gimple *stmt)
return copy;
}
+/* Move OLD_STMT's vuse and vdef operands to NEW_STMT, on the assumption
+ that OLD_STMT is about to be removed. */
+
+void
+gimple_move_vops (gimple *new_stmt, gimple *old_stmt)
+{
+ tree vdef = gimple_vdef (old_stmt);
+ gimple_set_vuse (new_stmt, gimple_vuse (old_stmt));
+ gimple_set_vdef (new_stmt, vdef);
+ if (vdef && TREE_CODE (vdef) == SSA_NAME)
+ SSA_NAME_DEF_STMT (vdef) = new_stmt;
+}
/* Return true if statement S has side-effects. We consider a
statement to have side effects if:
@@ -2695,6 +2707,18 @@ gimple_builtin_call_types_compatible_p (const gimple *stmt, tree fndecl)
return true;
}
+/* Return true when STMT is operator delete call. */
+
+bool
+gimple_call_operator_delete_p (const gcall *stmt)
+{
+ tree fndecl;
+
+ if ((fndecl = gimple_call_fndecl (stmt)) != NULL_TREE)
+ return DECL_IS_OPERATOR_DELETE_P (fndecl);
+ return false;
+}
+
/* Return true when STMT is builtins call. */
bool
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 442a121..55f5d0d 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -1532,6 +1532,7 @@ void gimple_assign_set_rhs_with_ops (gimple_stmt_iterator *, enum tree_code,
tree gimple_get_lhs (const gimple *);
void gimple_set_lhs (gimple *, tree);
gimple *gimple_copy (gimple *);
+void gimple_move_vops (gimple *, gimple *);
bool gimple_has_side_effects (const gimple *);
bool gimple_could_trap_p_1 (gimple *, bool, bool);
bool gimple_could_trap_p (gimple *);
@@ -1547,6 +1548,7 @@ extern alias_set_type gimple_get_alias_set (tree);
extern bool gimple_ior_addresses_taken (bitmap, gimple *);
extern bool gimple_builtin_call_types_compatible_p (const gimple *, tree);
extern combined_fn gimple_call_combined_fn (const gimple *);
+extern bool gimple_call_operator_delete_p (const gcall *);
extern bool gimple_call_builtin_p (const gimple *);
extern bool gimple_call_builtin_p (const gimple *, enum built_in_class);
extern bool gimple_call_builtin_p (const gimple *, enum built_in_function);
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 723897f..daa0b71 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -775,14 +775,27 @@ gimple_add_tmp_var (tree tmp)
if (gimplify_omp_ctxp)
{
struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
+ int flag = GOVD_LOCAL;
while (ctx
&& (ctx->region_type == ORT_WORKSHARE
|| ctx->region_type == ORT_TASKGROUP
|| ctx->region_type == ORT_SIMD
|| ctx->region_type == ORT_ACC))
- ctx = ctx->outer_context;
+ {
+ if (ctx->region_type == ORT_SIMD
+ && TREE_ADDRESSABLE (tmp)
+ && !TREE_STATIC (tmp))
+ {
+ if (TREE_CODE (DECL_SIZE_UNIT (tmp)) != INTEGER_CST)
+ ctx->add_safelen1 = true;
+ else
+ flag = GOVD_PRIVATE;
+ break;
+ }
+ ctx = ctx->outer_context;
+ }
if (ctx)
- omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN);
+ omp_add_variable (ctx, tmp, flag | GOVD_SEEN);
}
}
else if (cfun)
@@ -6919,8 +6932,10 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
else if (flags & GOVD_PRIVATE)
nflags = GOVD_PRIVATE;
- else if ((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
- && (flags & GOVD_FIRSTPRIVATE))
+ else if (((ctx->region_type & (ORT_TARGET | ORT_TARGET_DATA)) != 0
+ && (flags & GOVD_FIRSTPRIVATE))
+ || (ctx->region_type == ORT_TARGET_DATA
+ && (flags & GOVD_DATA_SHARE_CLASS) == 0))
nflags = GOVD_PRIVATE | GOVD_EXPLICIT;
else
nflags = GOVD_FIRSTPRIVATE;
@@ -9002,8 +9017,10 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
goto do_notice;
case OMP_CLAUSE_USE_DEVICE_PTR:
- flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
+ flags = GOVD_EXPLICIT;
goto do_add;
+
case OMP_CLAUSE_IS_DEVICE_PTR:
flags = GOVD_FIRSTPRIVATE | GOVD_EXPLICIT;
goto do_add;
@@ -10251,6 +10268,7 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
case OMP_CLAUSE_ORDER:
case OMP_CLAUSE_BIND:
case OMP_CLAUSE_USE_DEVICE_PTR:
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
case OMP_CLAUSE_IS_DEVICE_PTR:
case OMP_CLAUSE_ASYNC:
case OMP_CLAUSE_WAIT:
@@ -10590,6 +10608,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
orig_for_stmt = for_stmt = *expr_p;
+ bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
+ != NULL_TREE);
if (OMP_FOR_INIT (for_stmt) == NULL_TREE)
{
tree *data[4] = { NULL, NULL, NULL, NULL };
@@ -10641,7 +10661,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
}
for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner_for_stmt)); i++)
- if (OMP_FOR_ORIG_DECLS (inner_for_stmt)
+ if (!loop_p
+ && OMP_FOR_ORIG_DECLS (inner_for_stmt)
&& TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
i)) == TREE_LIST
&& TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt),
@@ -10649,7 +10670,9 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
{
tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner_for_stmt), i);
/* Class iterators aren't allowed on OMP_SIMD, so the only
- case we need to solve is distribute parallel for. */
+ case we need to solve is distribute parallel for. They are
+ allowed on the loop construct, but that is already handled
+ in gimplify_omp_loop. */
gcc_assert (TREE_CODE (inner_for_stmt) == OMP_FOR
&& TREE_CODE (for_stmt) == OMP_DISTRIBUTE
&& data[1]);
@@ -10663,6 +10686,22 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
&& OMP_CLAUSE_DECL (*pc) == orig_decl)
break;
if (*pc == NULL_TREE)
+ {
+ tree *spc;
+ for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
+ *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
+ if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
+ && OMP_CLAUSE_DECL (*spc) == orig_decl)
+ break;
+ if (*spc)
+ {
+ tree c = *spc;
+ *spc = OMP_CLAUSE_CHAIN (c);
+ OMP_CLAUSE_CHAIN (c) = NULL_TREE;
+ *pc = c;
+ }
+ }
+ if (*pc == NULL_TREE)
;
else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
{
@@ -10775,8 +10814,6 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
}
}
- bool loop_p = (omp_find_clause (OMP_FOR_CLAUSES (for_stmt), OMP_CLAUSE_BIND)
- != NULL_TREE);
if (TREE_CODE (for_stmt) != OMP_TASKLOOP)
gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p, ort,
loop_p && TREE_CODE (for_stmt) != OMP_SIMD
@@ -11147,6 +11184,13 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
|| !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
if (TREE_PRIVATE (t))
lastprivate = false;
+ if (loop_p && OMP_FOR_ORIG_DECLS (for_stmt))
+ {
+ tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
+ if (TREE_CODE (elt) == TREE_LIST && TREE_PURPOSE (elt))
+ lastprivate = false;
+ }
+
struct gimplify_omp_ctx *outer
= gimplify_omp_ctxp->outer_context;
if (outer && lastprivate)
@@ -11469,7 +11513,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
BITMAP_FREE (has_decl_expr);
- if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
+ if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
+ || (loop_p && orig_for_stmt == for_stmt))
{
push_gimplify_context ();
if (TREE_CODE (OMP_FOR_BODY (orig_for_stmt)) != BIND_EXPR)
@@ -11484,7 +11529,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gimple *g = gimplify_and_return_first (OMP_FOR_BODY (orig_for_stmt),
&for_body);
- if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP)
+ if (TREE_CODE (orig_for_stmt) == OMP_TASKLOOP
+ || (loop_p && orig_for_stmt == for_stmt))
{
if (gimple_code (g) == GIMPLE_BIND)
pop_gimplify_context (g);
@@ -11524,6 +11570,11 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
default:
gcc_unreachable ();
}
+ if (loop_p && kind == GF_OMP_FOR_KIND_SIMD)
+ {
+ gimplify_seq_add_seq (pre_p, for_pre_body);
+ for_pre_body = NULL;
+ }
gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (orig_for_stmt),
TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
for_pre_body);
@@ -11624,7 +11675,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
a shared clause on task. If the same decl is also firstprivate,
add also firstprivate clause on the inner taskloop. */
case OMP_CLAUSE_LASTPRIVATE:
- if (OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c))
+ if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
{
/* For taskloop C++ lastprivate IVs, we want:
1) private on outer taskloop
@@ -11947,6 +11998,21 @@ gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
OMP_PARALLEL_BODY (*expr_p) = bind;
OMP_PARALLEL_COMBINED (*expr_p) = 1;
SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (for_stmt));
+ tree *pc = &OMP_PARALLEL_CLAUSES (*expr_p);
+ for (i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)); i++)
+ if (OMP_FOR_ORIG_DECLS (for_stmt)
+ && (TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i))
+ == TREE_LIST))
+ {
+ tree elt = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (for_stmt), i);
+ if (TREE_PURPOSE (elt) && TREE_VALUE (elt))
+ {
+ *pc = build_omp_clause (UNKNOWN_LOCATION,
+ OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (*pc) = TREE_VALUE (elt);
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ }
+ }
}
tree t = make_node (pass == 2 ? OMP_DISTRIBUTE : OMP_FOR);
tree *pc = &OMP_FOR_CLAUSES (t);
@@ -11963,12 +12029,29 @@ gimplify_omp_loop (tree *expr_p, gimple_seq *pre_p)
pc = &OMP_CLAUSE_CHAIN (*pc);
break;
case OMP_CLAUSE_PRIVATE:
+ case OMP_CLAUSE_FIRSTPRIVATE:
/* Only needed on innermost. */
break;
case OMP_CLAUSE_LASTPRIVATE:
+ if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c) && pass != last)
+ {
+ *pc = build_omp_clause (OMP_CLAUSE_LOCATION (c),
+ OMP_CLAUSE_FIRSTPRIVATE);
+ OMP_CLAUSE_DECL (*pc) = OMP_CLAUSE_DECL (c);
+ lang_hooks.decls.omp_finish_clause (*pc, NULL);
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ }
*pc = copy_node (c);
OMP_CLAUSE_LASTPRIVATE_STMT (*pc) = NULL_TREE;
TREE_TYPE (*pc) = unshare_expr (TREE_TYPE (c));
+ if (OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
+ {
+ if (pass != last)
+ OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (*pc) = 1;
+ else
+ lang_hooks.decls.omp_finish_clause (*pc, NULL);
+ OMP_CLAUSE_LASTPRIVATE_LOOP_IV (*pc) = 0;
+ }
pc = &OMP_CLAUSE_CHAIN (*pc);
break;
case OMP_CLAUSE_REDUCTION:
@@ -12326,8 +12409,27 @@ gimplify_omp_workshare (tree *expr_p, gimple_seq *pre_p)
OMP_CLAUSES (expr));
break;
case OMP_TARGET_DATA:
- stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
- OMP_CLAUSES (expr));
+ /* Put use_device_{ptr,addr} clauses last, as map clauses are supposed
+ to be evaluated before the use_device_{ptr,addr} clauses if they
+ refer to the same variables. */
+ {
+ tree use_device_clauses;
+ tree *pc, *uc = &use_device_clauses;
+ for (pc = &OMP_CLAUSES (expr); *pc; )
+ if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_PTR
+ || OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_USE_DEVICE_ADDR)
+ {
+ *uc = *pc;
+ *pc = OMP_CLAUSE_CHAIN (*pc);
+ uc = &OMP_CLAUSE_CHAIN (*uc);
+ }
+ else
+ pc = &OMP_CLAUSE_CHAIN (*pc);
+ *uc = NULL_TREE;
+ *pc = use_device_clauses;
+ stmt = gimple_build_omp_target (body, GF_OMP_TARGET_KIND_DATA,
+ OMP_CLAUSES (expr));
+ }
break;
case OMP_TEAMS:
stmt = gimple_build_omp_teams (body, OMP_CLAUSES (expr));
@@ -14354,7 +14456,7 @@ flag_instrument_functions_exclude_p (tree fndecl)
int i;
char *s;
- name = lang_hooks.decl_printable_name (fndecl, 0);
+ name = lang_hooks.decl_printable_name (fndecl, 1);
FOR_EACH_VEC_ELT (*v, i, s)
if (strstr (name, s) != NULL)
return true;
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index 60d1187..9413c20 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -51,10 +51,10 @@
2019-02-05 Nikhil Benesch <nikhil.benesch@gmail.com>
- PR go/89019
- * go-gcc.cc (Gcc_backend::placeholder_struct_type): Mark
- placeholder structs as requiring structural equality.
- (Gcc_backend::set_placeholder_pointer_type): Propagate the
+ PR go/89019
+ * go-gcc.cc (Gcc_backend::placeholder_struct_type): Mark
+ placeholder structs as requiring structural equality.
+ (Gcc_backend::set_placeholder_pointer_type): Propagate the
canonical type from the desired pointer type to the placeholder
pointer type.
@@ -952,7 +952,7 @@
2013-11-22 Andrew MacLeod <amacleod@redhat.com>
* go-gcc.cc: Add required include files from gimple.h.
- * go-lang.c: Likewise
+ * go-lang.c: Likewise.
2013-11-18 Richard Sandiford <rdsandiford@googlemail.com>
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index ba7282e..b1a6579 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-480477ca64c3001b9c7e92ef8b978dc92a5912d2
+b0ba5daa8216a0424b24f74466cedab0b986f3b4
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index abc4bba..995a18c 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -10294,7 +10294,13 @@ Builtin_call_expression::do_get_backend(Translate_context* context)
{
Type* itype = Type::lookup_integer_type("uint64");
arg = Expression::make_cast(itype, arg, location);
- code = Runtime::PRINTUINT;
+ if (gogo->compiling_runtime()
+ && type->named_type() != NULL
+ && gogo->unpack_hidden_name(type->named_type()->name())
+ == "hex")
+ code = Runtime::PRINTHEX;
+ else
+ code = Runtime::PRINTUINT;
}
else if (type->integer_type() != NULL)
{
diff --git a/gcc/go/gofrontend/lex.cc b/gcc/go/gofrontend/lex.cc
index 82fd355..3276de4 100644
--- a/gcc/go/gofrontend/lex.cc
+++ b/gcc/go/gofrontend/lex.cc
@@ -986,6 +986,26 @@ Lex::is_hex_digit(char c)
|| (c >= 'a' && c <= 'f'));
}
+// Return whether C is a valid digit in BASE.
+
+bool
+Lex::is_base_digit(int base, char c)
+{
+ switch (base)
+ {
+ case 2:
+ return c == '0' || c == '1';
+ case 8:
+ return c >= '0' && c <= '7';
+ case 10:
+ return c >= '0' && c <= '9';
+ case 16:
+ return Lex::is_hex_digit(c);
+ default:
+ go_unreachable();
+ }
+}
+
// not a hex value
#define NHV 100
@@ -1032,13 +1052,24 @@ Lex::hex_val(char c)
return hex_value_lookup_table[static_cast<unsigned char>(c)];
}
-// Return whether an exponent could start at P.
+// Return whether an exponent could start at P, in base BASE.
bool
-Lex::could_be_exponent(const char* p, const char* pend)
+Lex::could_be_exponent(int base, const char* p, const char* pend)
{
- if (*p != 'e' && *p != 'E')
- return false;
+ switch (base)
+ {
+ case 10:
+ if (*p != 'e' && *p != 'E')
+ return false;
+ break;
+ case 16:
+ if (*p != 'p' && *p != 'P')
+ return false;
+ break;
+ default:
+ go_unreachable();
+ }
++p;
if (p >= pend)
return false;
@@ -1062,87 +1093,160 @@ Lex::gather_number()
Location location = this->location();
- bool neg = false;
- if (*p == '+')
- ++p;
- else if (*p == '-')
- {
- ++p;
- neg = true;
- }
-
- const char* pnum = p;
+ int base = 10;
+ std::string num;
if (*p == '0')
{
- int base;
- if ((p[1] == 'x' || p[1] == 'X')
- && Lex::is_hex_digit(p[2]))
+ int basecheck;
+ int off;
+ if (p[1] == 'x' || p[1] == 'X')
{
base = 16;
- p += 2;
- pnum = p;
- while (p < pend)
- {
- if (!Lex::is_hex_digit(*p))
- break;
- ++p;
- }
+ basecheck = 16;
+ off = 2;
+ }
+ else if (p[1] == 'o' || p[1] == 'O')
+ {
+ base = 8;
+ basecheck = 8;
+ off = 2;
+ }
+ else if (p[1] == 'b' || p[1] == 'B')
+ {
+ base = 2;
+ basecheck = 2;
+ off = 2;
}
else
{
+ // Old style octal literal. May also be the start of a
+ // floating-point number (e.g., 09.2, 09e2) or an imaginary
+ // literal (e.g., 09i), so we have to accept decimal digits.
base = 8;
- pnum = p;
- while (p < pend)
- {
- if (*p < '0' || *p > '9')
- break;
- ++p;
- }
+ basecheck = 10;
+ off = 0;
+ }
+
+ p += off;
+ if (*p == '_' && Lex::is_base_digit(basecheck, p[1]))
+ ++p;
+
+ while (Lex::is_base_digit(basecheck, *p))
+ {
+ num.push_back(*p);
+ ++p;
+ if (*p == '_' && Lex::is_base_digit(basecheck, p[1]))
+ ++p;
+ }
+
+ // We must see at least one valid digit, except for a case like
+ // 0x.0p1.
+ if (num.length() == 0 && (base != 16 || *p != '.'))
+ {
+ go_error_at(this->location(), "invalid numeric literal");
+ this->lineoff_ = p - this->linebuf_;
+ mpz_t val;
+ mpz_init_set_ui(val, 0);
+ Token ret = Token::make_integer_token(val, location);
+ mpz_clear(val);
+ return ret;
+ }
+
+ bool is_float = false;
+ // A number that looks like an old-style octal literal might
+ // actually be the beginning of a floating-point or imaginary
+ // literal, in which case the value is decimal digits. Handle
+ // that case below by treating the leading '0' as decimal.
+ if (off == 0
+ && (*p == '.' || *p == 'i' || Lex::could_be_exponent(10, p, pend)))
+ {
+ is_float = true;
+ base = 10;
}
+ else if (base == 16
+ && (*p == '.' || Lex::could_be_exponent(16, p, pend)))
+ is_float = true;
- // A partial token that looks like an octal literal might actually be the
- // beginning of a floating-point or imaginary literal.
- if (base == 16 || (*p != '.' && *p != 'i' && !Lex::could_be_exponent(p, pend)))
+ if (!is_float)
{
- std::string s(pnum, p - pnum);
mpz_t val;
- int r = mpz_init_set_str(val, s.c_str(), base);
+ int r = mpz_init_set_str(val, num.c_str(), base);
if (r != 0)
{
- if (base == 8)
- go_error_at(this->location(), "invalid octal literal");
- else
- go_error_at(this->location(), "invalid hex literal");
+ const char *errword;
+ switch (base)
+ {
+ case 2:
+ errword = "binary";
+ break;
+ case 8:
+ errword = "octal";
+ break;
+ case 16:
+ errword = "hex";
+ break;
+ default:
+ go_unreachable();
+ }
+ go_error_at(this->location(), "invalid %s literal", errword);
}
- if (neg)
- mpz_neg(val, val);
+ bool is_imaginary = *p == 'i';
+ if (is_imaginary)
+ ++p;
this->lineoff_ = p - this->linebuf_;
- Token ret = Token::make_integer_token(val, location);
- mpz_clear(val);
- return ret;
+
+ if (*p == 'e' || *p == 'E' || *p == 'p' || *p == 'P')
+ {
+ go_error_at(location,
+ "invalid prefix for floating constant");
+ this->skip_exponent();
+ }
+
+ if (!is_imaginary)
+ {
+ Token ret = Token::make_integer_token(val, location);
+ mpz_clear(val);
+ return ret;
+ }
+ else
+ {
+ mpfr_t ival;
+ mpfr_init_set_z(ival, val, GMP_RNDN);
+ mpz_clear(val);
+ Token ret = Token::make_imaginary_token(ival, location);
+ mpfr_clear(ival);
+ return ret;
+ }
}
}
while (p < pend)
{
- if (*p < '0' || *p > '9')
+ if (*p == '_' && p[1] >= '0' && p[1] <= '9')
+ ++p;
+ else if (*p < '0' || *p > '9')
break;
+ num.push_back(*p);
++p;
}
- if (*p != '.' && *p != 'i' && !Lex::could_be_exponent(p, pend))
+ if (*p != '.' && *p != 'i' && !Lex::could_be_exponent(base, p, pend))
{
- std::string s(pnum, p - pnum);
mpz_t val;
- int r = mpz_init_set_str(val, s.c_str(), 10);
+ int r = mpz_init_set_str(val, num.c_str(), 10);
go_assert(r == 0);
- if (neg)
- mpz_neg(val, val);
-
this->lineoff_ = p - this->linebuf_;
+
+ if (*p == 'e' || *p == 'E' || *p == 'p' || *p == 'P')
+ {
+ go_error_at(location,
+ "invalid prefix for floating constant");
+ this->skip_exponent();
+ }
+
Token ret = Token::make_integer_token(val, location);
mpz_clear(val);
return ret;
@@ -1152,48 +1256,76 @@ Lex::gather_number()
{
bool dot = *p == '.';
+ num.push_back(*p);
++p;
if (!dot)
{
if (*p == '+' || *p == '-')
- ++p;
+ {
+ num.push_back(*p);
+ ++p;
+ }
}
+ bool first = true;
while (p < pend)
{
- if (*p < '0' || *p > '9')
+ if (!first && *p == '_' && Lex::is_base_digit(base, p[1]))
+ ++p;
+ else if (!Lex::is_base_digit(base, *p))
break;
+ num.push_back(*p);
++p;
+ first = false;
}
- if (dot && Lex::could_be_exponent(p, pend))
+ if (dot && Lex::could_be_exponent(base, p, pend))
{
+ num.push_back(*p);
++p;
if (*p == '+' || *p == '-')
- ++p;
+ {
+ num.push_back(*p);
+ ++p;
+ }
+ first = true;
while (p < pend)
{
- if (*p < '0' || *p > '9')
+ if (!first && *p == '_' && p[1] >= '0' && p[1] <= '9')
+ ++p;
+ else if (*p < '0' || *p > '9')
break;
+ num.push_back(*p);
++p;
+ first = false;
}
}
+ else if (dot && base == 16)
+ {
+ go_error_at(this->location(),
+ "invalid hex floating-point literal with no exponent");
+ num.append("p0");
+ }
}
- std::string s(pnum, p - pnum);
mpfr_t val;
- int r = mpfr_init_set_str(val, s.c_str(), 10, GMP_RNDN);
+ int r = mpfr_init_set_str(val, num.c_str(), base, GMP_RNDN);
go_assert(r == 0);
- if (neg)
- mpfr_neg(val, val, GMP_RNDN);
-
bool is_imaginary = *p == 'i';
if (is_imaginary)
++p;
this->lineoff_ = p - this->linebuf_;
+
+ if (*p == 'e' || *p == 'E' || *p == 'p' || *p == 'P')
+ {
+ go_error_at(location,
+ "invalid prefix for floating constant");
+ this->skip_exponent();
+ }
+
if (is_imaginary)
{
Token ret = Token::make_imaginary_token(val, location);
@@ -1208,6 +1340,27 @@ Lex::gather_number()
}
}
+// Skip an exponent after reporting an error.
+
+void
+Lex::skip_exponent()
+{
+ const char* p = this->linebuf_ + this->lineoff_;
+ const char* pend = this->linebuf_ + this->linesize_;
+ if (*p != 'e' && *p != 'E' && *p != 'p' && *p != 'P')
+ return;
+ ++p;
+ if (*p == '+' || *p == '-')
+ ++p;
+ while (p < pend)
+ {
+ if ((*p < '0' || *p > '9') && *p != '_')
+ break;
+ ++p;
+ }
+ this->lineoff_ = p - this->linebuf_;
+}
+
// Advance one character, possibly escaped. Return the pointer beyond
// the character. Set *VALUE to the character. Set *IS_CHARACTER if
// this is a character (e.g., 'a' or '\u1234') rather than a byte
diff --git a/gcc/go/gofrontend/lex.h b/gcc/go/gofrontend/lex.h
index 75e37f8..59b770c 100644
--- a/gcc/go/gofrontend/lex.h
+++ b/gcc/go/gofrontend/lex.h
@@ -462,6 +462,9 @@ class Lex
static bool
is_hex_digit(char);
+ static bool
+ is_base_digit(int base, char);
+
static unsigned char
octal_value(char c)
{ return c - '0'; }
@@ -482,11 +485,14 @@ class Lex
gather_identifier();
static bool
- could_be_exponent(const char*, const char*);
+ could_be_exponent(int base, const char*, const char*);
Token
gather_number();
+ void
+ skip_exponent();
+
Token
gather_character();
diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def
index c754739..7eac880 100644
--- a/gcc/go/gofrontend/runtime.def
+++ b/gcc/go/gofrontend/runtime.def
@@ -287,6 +287,10 @@ DEF_GO_RUNTIME(GO, "__go_go", P2(UINTPTR, POINTER), R1(POINTER))
DEF_GO_RUNTIME(DEFERPROC, "runtime.deferproc", P3(BOOLPTR, UINTPTR, POINTER),
R0())
+// Defer a function, with stack-allocated defer structure.
+DEF_GO_RUNTIME(DEFERPROCSTACK, "runtime.deferprocStack",
+ P4(POINTER, BOOLPTR, UINTPTR, POINTER), R0())
+
// Convert an empty interface to an empty interface, returning ok.
DEF_GO_RUNTIME(IFACEE2E2, "runtime.ifaceE2E2", P1(EFACE), R2(EFACE, BOOL))
@@ -384,6 +388,9 @@ DEF_GO_RUNTIME(PRINTSTRING, "runtime.printstring", P1(STRING), R0())
// Print a uint64 (for print/println).
DEF_GO_RUNTIME(PRINTUINT, "runtime.printuint", P1(UINT64), R0())
+// Print a uint64 in hex (for print/println, used for runtime.hex type).
+DEF_GO_RUNTIME(PRINTHEX, "runtime.printhex", P1(UINT64), R0())
+
// Print a int64 (for print/println).
DEF_GO_RUNTIME(PRINTINT, "runtime.printint", P1(INT64), R0())
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index 6d9c0eb..27c309e 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -2614,7 +2614,11 @@ Thunk_statement::simplify_statement(Gogo* gogo, Named_object* function,
if (this->classification() == STATEMENT_GO)
s = Statement::make_go_statement(call, location);
else if (this->classification() == STATEMENT_DEFER)
- s = Statement::make_defer_statement(call, location);
+ {
+ s = Statement::make_defer_statement(call, location);
+ if ((Node::make_node(this)->encoding() & ESCAPE_MASK) == Node::ESCAPE_NONE)
+ s->defer_statement()->set_on_stack();
+ }
else
go_unreachable();
@@ -3019,13 +3023,45 @@ Defer_statement::do_get_backend(Translate_context* context)
Location loc = this->location();
Expression* ds = context->function()->func_value()->defer_stack(loc);
- Expression* call = Runtime::make_call(Runtime::DEFERPROC, loc, 3,
- ds, fn, arg);
+ Expression* call;
+ if (this->on_stack_)
+ {
+ if (context->gogo()->debug_optimization())
+ go_debug(loc, "stack allocated defer");
+
+ Type* defer_type = Defer_statement::defer_struct_type();
+ Expression* defer = Expression::make_allocation(defer_type, loc);
+ defer->allocation_expression()->set_allocate_on_stack();
+ defer->allocation_expression()->set_no_zero();
+ call = Runtime::make_call(Runtime::DEFERPROCSTACK, loc, 4,
+ defer, ds, fn, arg);
+ }
+ else
+ call = Runtime::make_call(Runtime::DEFERPROC, loc, 3,
+ ds, fn, arg);
Bexpression* bcall = call->get_backend(context);
Bfunction* bfunction = context->function()->func_value()->get_decl();
return context->backend()->expression_statement(bfunction, bcall);
}
+Type*
+Defer_statement::defer_struct_type()
+{
+ Type* ptr_type = Type::make_pointer_type(Type::make_void_type());
+ Type* uintptr_type = Type::lookup_integer_type("uintptr");
+ Type* bool_type = Type::make_boolean_type();
+ return Type::make_builtin_struct_type(9,
+ "link", ptr_type,
+ "frame", ptr_type,
+ "panicStack", ptr_type,
+ "_panic", ptr_type,
+ "pfn", uintptr_type,
+ "arg", ptr_type,
+ "retaddr", uintptr_type,
+ "makefunccanrecover", bool_type,
+ "heap", bool_type);
+}
+
// Dump the AST representation for defer statement.
void
diff --git a/gcc/go/gofrontend/statements.h b/gcc/go/gofrontend/statements.h
index 7c254d0..311bbaa 100644
--- a/gcc/go/gofrontend/statements.h
+++ b/gcc/go/gofrontend/statements.h
@@ -24,6 +24,7 @@ class Expression_statement;
class Block_statement;
class Return_statement;
class Thunk_statement;
+class Defer_statement;
class Goto_statement;
class Goto_unnamed_statement;
class Label_statement;
@@ -403,6 +404,11 @@ class Statement
Thunk_statement*
thunk_statement();
+ // If this is a defer statement, return it. Otherwise return NULL.
+ Defer_statement*
+ defer_statement()
+ { return this->convert<Defer_statement, STATEMENT_DEFER>(); }
+
// If this is a goto statement, return it. Otherwise return NULL.
Goto_statement*
goto_statement()
@@ -1419,15 +1425,26 @@ class Defer_statement : public Thunk_statement
{
public:
Defer_statement(Call_expression* call, Location location)
- : Thunk_statement(STATEMENT_DEFER, call, location)
+ : Thunk_statement(STATEMENT_DEFER, call, location),
+ on_stack_(false)
{ }
+ void
+ set_on_stack()
+ { this->on_stack_ = true; }
+
protected:
Bstatement*
do_get_backend(Translate_context*);
void
do_dump_statement(Ast_dump_context*) const;
+
+ private:
+ static Type*
+ defer_struct_type();
+
+ bool on_stack_;
};
// A goto statement.
diff --git a/gcc/inchash.h b/gcc/inchash.h
index f61e631..56588d2 100644
--- a/gcc/inchash.h
+++ b/gcc/inchash.h
@@ -85,7 +85,7 @@ class hash
{
add_int (x.get_len ());
for (unsigned i = 0; i < x.get_len (); i++)
- add_hwi (x.elt (i));
+ add_hwi (x.sext_elt (i));
}
/* Hash in pointer PTR. */
diff --git a/gcc/int-vector-builder.h b/gcc/int-vector-builder.h
index adf0904..dc96510 100644
--- a/gcc/int-vector-builder.h
+++ b/gcc/int-vector-builder.h
@@ -26,10 +26,11 @@ along with GCC; see the file COPYING3. If not see
encoding as tree and rtx constants. See vector_builder for more
details. */
template<typename T>
-class int_vector_builder : public vector_builder<T, int_vector_builder<T> >
+class int_vector_builder : public vector_builder<T, poly_uint64,
+ int_vector_builder<T> >
{
- typedef vector_builder<T, int_vector_builder> parent;
- friend class vector_builder<T, int_vector_builder>;
+ typedef vector_builder<T, poly_uint64, int_vector_builder> parent;
+ friend class vector_builder<T, poly_uint64, int_vector_builder>;
public:
int_vector_builder () {}
@@ -45,6 +46,8 @@ private:
T apply_step (T, unsigned int, T) const;
bool can_elide_p (T) const { return true; }
void note_representative (T *, T) {}
+
+ static poly_uint64 shape_nelts (poly_uint64 x) { return x; }
};
/* Create a new builder for a vector with FULL_NELTS elements.
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index 1067376..ad86b9a 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -3286,7 +3286,9 @@ static void (*const internal_fn_expanders[]) (internal_fn, gcall *) = {
T (MAX_EXPR, IFN_COND_MAX) \
T (BIT_AND_EXPR, IFN_COND_AND) \
T (BIT_IOR_EXPR, IFN_COND_IOR) \
- T (BIT_XOR_EXPR, IFN_COND_XOR)
+ T (BIT_XOR_EXPR, IFN_COND_XOR) \
+ T (LSHIFT_EXPR, IFN_COND_SHL) \
+ T (RSHIFT_EXPR, IFN_COND_SHR)
/* Return a function that only performs CODE when a certain condition is met
and that uses a given fallback value otherwise. For example, if CODE is
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 906d74b..9461693 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -167,6 +167,10 @@ DEF_INTERNAL_OPTAB_FN (COND_IOR, ECF_CONST | ECF_NOTHROW,
cond_ior, cond_binary)
DEF_INTERNAL_OPTAB_FN (COND_XOR, ECF_CONST | ECF_NOTHROW,
cond_xor, cond_binary)
+DEF_INTERNAL_OPTAB_FN (COND_SHL, ECF_CONST | ECF_NOTHROW,
+ cond_ashl, cond_binary)
+DEF_INTERNAL_SIGNED_OPTAB_FN (COND_SHR, ECF_CONST | ECF_NOTHROW, first,
+ cond_ashr, cond_lshr, cond_binary)
DEF_INTERNAL_OPTAB_FN (COND_FMA, ECF_CONST, cond_fma, cond_ternary)
DEF_INTERNAL_OPTAB_FN (COND_FMS, ECF_CONST, cond_fms, cond_ternary)
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index b20a6d0..0046064 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -977,7 +977,12 @@ ipcp_vr_lattice::set_to_bottom ()
{
if (m_vr.varying_p ())
return false;
- m_vr.set_varying ();
+ /* ?? We create all sorts of VARYING ranges for floats, structures,
+ and other types which we cannot handle as ranges. We should
+ probably avoid handling them throughout the pass, but it's easier
+ to create a sensible VARYING here and let the lattice
+ propagate. */
+ m_vr.set_varying (integer_type_node);
return true;
}
@@ -2436,8 +2441,7 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
if (can_refer)
{
if (!target
- || (TREE_CODE (TREE_TYPE (target)) == FUNCTION_TYPE
- && DECL_FUNCTION_CODE (target) == BUILT_IN_UNREACHABLE)
+ || fndecl_built_in_p (target, BUILT_IN_UNREACHABLE)
|| !possible_polymorphic_call_target_p
(ie, cgraph_node::get (target)))
{
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 95e2d95..e5028bc 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -1003,7 +1003,7 @@ warn_types_mismatch (tree t1, tree t2, location_t loc1, location_t loc2)
n2 = DECL_NAME (n2);
/* Most of the time, the type names will match, do not be unnecesarily
verbose. */
- if (IDENTIFIER_POINTER (n1) != IDENTIFIER_POINTER (n2))
+ if (n1 != n2)
inform (loc_t1,
"type %qT defined in anonymous namespace cannot match "
"type %qT across the translation unit boundary",
@@ -1613,7 +1613,7 @@ add_type_duplicate (odr_type val, tree type)
val->types_set->add (type);
if (!odr_hash)
- return NULL;
+ return false;
gcc_checking_assert (can_be_name_hashed_p (type)
&& can_be_name_hashed_p (val->type));
@@ -3426,12 +3426,10 @@ possible_polymorphic_call_target_p (tree otr_type,
{
vec <cgraph_node *> targets;
unsigned int i;
- enum built_in_function fcode;
bool final;
- if (TREE_CODE (TREE_TYPE (n->decl)) == FUNCTION_TYPE
- && ((fcode = DECL_FUNCTION_CODE (n->decl)) == BUILT_IN_UNREACHABLE
- || fcode == BUILT_IN_TRAP))
+ if (fndecl_built_in_p (n->decl, BUILT_IN_UNREACHABLE)
+ || fndecl_built_in_p (n->decl, BUILT_IN_TRAP))
return true;
if (is_cxa_pure_virtual_p (n->decl))
@@ -3526,7 +3524,7 @@ likely_target_p (struct cgraph_node *n)
/* Compare type warning records P1 and P2 and choose one with larger count;
helper for qsort. */
-int
+static int
type_warning_cmp (const void *p1, const void *p2)
{
const odr_type_warn_count *t1 = (const odr_type_warn_count *)p1;
@@ -3542,7 +3540,7 @@ type_warning_cmp (const void *p1, const void *p2)
/* Compare decl warning records P1 and P2 and choose one with larger count;
helper for qsort. */
-int
+static int
decl_warning_cmp (const void *p1, const void *p2)
{
const decl_warn_count *t1 = *(const decl_warn_count * const *)p1;
diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c
index fe125ac..278bf60 100644
--- a/gcc/ipa-fnsummary.c
+++ b/gcc/ipa-fnsummary.c
@@ -382,7 +382,7 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
continue;
}
- if (tree_to_shwi (TYPE_SIZE (TREE_TYPE (val))) != c->size)
+ if (maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (val))), c->size))
{
clause |= 1 << (i + predicate::first_dynamic_condition);
nonspec_clause |= 1 << (i + predicate::first_dynamic_condition);
@@ -922,7 +922,7 @@ mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
static tree
unmodified_parm_1 (ipa_func_body_info *fbi, gimple *stmt, tree op,
- HOST_WIDE_INT *size_p)
+ poly_int64 *size_p)
{
/* SSA_NAME referring to parm default def? */
if (TREE_CODE (op) == SSA_NAME
@@ -930,7 +930,7 @@ unmodified_parm_1 (ipa_func_body_info *fbi, gimple *stmt, tree op,
&& TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL)
{
if (size_p)
- *size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op)));
+ *size_p = tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (op)));
return SSA_NAME_VAR (op);
}
/* Non-SSA parm reference? */
@@ -951,7 +951,7 @@ unmodified_parm_1 (ipa_func_body_info *fbi, gimple *stmt, tree op,
if (!modified)
{
if (size_p)
- *size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op)));
+ *size_p = tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (op)));
return op;
}
}
@@ -965,7 +965,7 @@ unmodified_parm_1 (ipa_func_body_info *fbi, gimple *stmt, tree op,
static tree
unmodified_parm (ipa_func_body_info *fbi, gimple *stmt, tree op,
- HOST_WIDE_INT *size_p)
+ poly_int64 *size_p)
{
tree res = unmodified_parm_1 (fbi, stmt, op, size_p);
if (res)
@@ -990,7 +990,7 @@ unmodified_parm (ipa_func_body_info *fbi, gimple *stmt, tree op,
static bool
unmodified_parm_or_parm_agg_item (struct ipa_func_body_info *fbi,
gimple *stmt, tree op, int *index_p,
- HOST_WIDE_INT *size_p,
+ poly_int64 *size_p,
struct agg_position_info *aggpos)
{
tree res = unmodified_parm_1 (fbi, stmt, op, size_p);
@@ -1169,7 +1169,7 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
gimple *last;
tree op;
int index;
- HOST_WIDE_INT size;
+ poly_int64 size;
struct agg_position_info aggpos;
enum tree_code code, inverted_code;
edge e;
@@ -1254,7 +1254,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
gimple *lastg;
tree op;
int index;
- HOST_WIDE_INT size;
+ poly_int64 size;
struct agg_position_info aggpos;
edge e;
edge_iterator ei;
@@ -1393,7 +1393,7 @@ will_be_nonconstant_expr_predicate (ipa_func_body_info *fbi,
{
tree parm;
int index;
- HOST_WIDE_INT size;
+ poly_int64 size;
while (UNARY_CLASS_P (expr))
expr = TREE_OPERAND (expr, 0);
@@ -1468,7 +1468,7 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
predicate op_non_const;
bool is_load;
int base_index;
- HOST_WIDE_INT size;
+ poly_int64 size;
struct agg_position_info aggpos;
/* What statments might be optimized away
@@ -1524,7 +1524,7 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
op_non_const = false;
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
{
- HOST_WIDE_INT size;
+ poly_int64 size;
tree parm = unmodified_parm (fbi, stmt, use, &size);
int index;
@@ -3292,7 +3292,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
{
struct condition c;
c.operand_num = streamer_read_uhwi (&ib);
- c.size = streamer_read_uhwi (&ib);
+ c.size = streamer_read_poly_uint64 (&ib);
c.code = (enum tree_code) streamer_read_uhwi (&ib);
c.val = stream_read_tree (&ib, data_in);
bp = streamer_read_bitpack (&ib);
@@ -3446,7 +3446,7 @@ ipa_fn_summary_write (void)
for (i = 0; vec_safe_iterate (info->conds, i, &c); i++)
{
streamer_write_uhwi (ob, c->operand_num);
- streamer_write_uhwi (ob, c->size);
+ streamer_write_poly_uint64 (ob, c->size);
streamer_write_uhwi (ob, c->code);
stream_write_tree (ob, c->val, true);
bp = bitpack_create (ob->main_stream);
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index 2174fb7..c9c3cb4 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -344,8 +344,8 @@ sem_item::compare_referenced_symbol_properties (symtab_node *used_by,
return return_false_with_msg ("inline attributes are different");
}
- if (DECL_IS_OPERATOR_NEW (n1->decl)
- != DECL_IS_OPERATOR_NEW (n2->decl))
+ if (DECL_IS_OPERATOR_NEW_P (n1->decl)
+ != DECL_IS_OPERATOR_NEW_P (n2->decl))
return return_false_with_msg ("operator new flags are different");
}
@@ -409,7 +409,7 @@ sem_item::hash_referenced_symbol_properties (symtab_node *ref,
hstate.add_flag (DECL_DISREGARD_INLINE_LIMITS (ref->decl));
hstate.add_flag (DECL_DECLARED_INLINE_P (ref->decl));
}
- hstate.add_flag (DECL_IS_OPERATOR_NEW (ref->decl));
+ hstate.add_flag (DECL_IS_OPERATOR_NEW_P (ref->decl));
}
else if (is_a <varpool_node *> (ref))
{
@@ -1024,20 +1024,23 @@ sem_function::merge (sem_item *alias_item)
bool original_address_matters = original->address_matters_p ();
bool alias_address_matters = alias->address_matters_p ();
+ AUTO_DUMP_SCOPE ("merge",
+ dump_user_location_t::from_function_decl (decl));
+
if (DECL_EXTERNAL (alias->decl))
{
- if (dump_file)
- fprintf (dump_file, "Not unifying; alias is external.\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Not unifying; alias is external.\n");
return false;
}
if (DECL_NO_INLINE_WARNING_P (original->decl)
!= DECL_NO_INLINE_WARNING_P (alias->decl))
{
- if (dump_file)
- fprintf (dump_file,
- "Not unifying; "
- "DECL_NO_INLINE_WARNING mismatch.\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Not unifying; DECL_NO_INLINE_WARNING mismatch.\n");
return false;
}
@@ -1047,21 +1050,20 @@ sem_function::merge (sem_item *alias_item)
|| (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
&& DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
{
- if (dump_file)
- fprintf (dump_file,
- "Not unifying; "
- "original and alias are in different sections.\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Not unifying; "
+ "original and alias are in different sections.\n");
return false;
}
if (!original->in_same_comdat_group_p (alias)
|| original->comdat_local_p ())
{
- if (dump_file)
- fprintf (dump_file,
- "Not unifying; alias nor wrapper cannot be created; "
- "across comdat group boundary\n\n");
-
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Not unifying; alias nor wrapper cannot be created; "
+ "across comdat group boundary\n");
return false;
}
@@ -1106,10 +1108,10 @@ sem_function::merge (sem_item *alias_item)
if (!sem_item::compare_referenced_symbol_properties (NULL, original, alias,
alias->address_taken))
{
- if (dump_file)
- fprintf (dump_file,
- "Wrapper cannot be created because referenced symbol "
- "properties mismatch\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Wrapper cannot be created because referenced symbol "
+ "properties mismatch\n");
}
/* Do not turn function in one comdat group into wrapper to another
comdat group. Other compiler producing the body of the
@@ -1120,40 +1122,41 @@ sem_function::merge (sem_item *alias_item)
&& (DECL_COMDAT_GROUP (alias->decl)
!= DECL_COMDAT_GROUP (original->decl)))
{
- if (dump_file)
- fprintf (dump_file,
- "Wrapper cannot be created because of COMDAT\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Wrapper cannot be created because of COMDAT\n");
}
else if (DECL_STATIC_CHAIN (alias->decl)
|| DECL_STATIC_CHAIN (original->decl))
{
- if (dump_file)
- fprintf (dump_file,
- "Cannot create wrapper of nested function.\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Cannot create wrapper of nested function.\n");
}
/* TODO: We can also deal with variadic functions never calling
VA_START. */
else if (stdarg_p (TREE_TYPE (alias->decl)))
{
- if (dump_file)
- fprintf (dump_file,
- "cannot create wrapper of stdarg function.\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "cannot create wrapper of stdarg function.\n");
}
else if (ipa_fn_summaries
&& ipa_fn_summaries->get (alias) != NULL
&& ipa_fn_summaries->get (alias)->self_size <= 2)
{
- if (dump_file)
- fprintf (dump_file, "Wrapper creation is not "
- "profitable (function is too small).\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION, "Wrapper creation is not "
+ "profitable (function is too small).\n");
}
/* If user paid attention to mark function noinline, assume it is
somewhat special and do not try to turn it into a wrapper that
cannot be undone by inliner. */
else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (alias->decl)))
{
- if (dump_file)
- fprintf (dump_file, "Wrappers are not created for noinline.\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Wrappers are not created for noinline.\n");
}
else
create_wrapper = true;
@@ -1171,9 +1174,10 @@ sem_function::merge (sem_item *alias_item)
if (!redirect_callers && !create_wrapper)
{
- if (dump_file)
- fprintf (dump_file, "Not unifying; cannot redirect callers nor "
- "produce wrapper\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Not unifying; cannot redirect callers nor "
+ "produce wrapper\n");
return false;
}
@@ -1202,17 +1206,18 @@ sem_function::merge (sem_item *alias_item)
redirect_callers = false;
if (!local_original)
{
- if (dump_file)
- fprintf (dump_file, "Not unifying; "
- "cannot produce local alias.\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Not unifying; cannot produce local alias.\n");
return false;
}
if (!redirect_callers && !create_wrapper)
{
- if (dump_file)
- fprintf (dump_file, "Not unifying; "
- "cannot redirect callers nor produce a wrapper\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Not unifying; "
+ "cannot redirect callers nor produce a wrapper\n");
return false;
}
if (!create_wrapper
@@ -1220,9 +1225,10 @@ sem_function::merge (sem_item *alias_item)
NULL, true)
&& !alias->can_remove_if_no_direct_calls_p ())
{
- if (dump_file)
- fprintf (dump_file, "Not unifying; cannot make wrapper and "
- "function has other uses than direct calls\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Not unifying; cannot make wrapper and "
+ "function has other uses than direct calls\n");
return false;
}
}
@@ -1238,9 +1244,10 @@ sem_function::merge (sem_item *alias_item)
alias->icf_merged = true;
local_original->icf_merged = true;
- if (dump_file && nredirected)
- fprintf (dump_file, "%i local calls have been "
- "redirected.\n", nredirected);
+ if (dump_enabled_p ())
+ dump_printf (MSG_NOTE,
+ "%i local calls have been "
+ "redirected.\n", nredirected);
}
/* If all callers was redirected, do not produce wrapper. */
@@ -1272,8 +1279,9 @@ sem_function::merge (sem_item *alias_item)
original->call_for_symbol_thunks_and_aliases
(set_local, (void *)(size_t) original->local_p (), true);
- if (dump_file)
- fprintf (dump_file, "Unified; Function alias has been created.\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_OPTIMIZED_LOCATIONS,
+ "Unified; Function alias has been created.\n");
}
if (create_wrapper)
{
@@ -1285,8 +1293,9 @@ sem_function::merge (sem_item *alias_item)
ipa_merge_profiles (original, alias, true);
alias->create_wrapper (local_original);
- if (dump_file)
- fprintf (dump_file, "Unified; Wrapper has been created.\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_OPTIMIZED_LOCATIONS,
+ "Unified; Wrapper has been created.\n");
}
/* It's possible that redirection can hit thunks that block
@@ -1299,8 +1308,8 @@ sem_function::merge (sem_item *alias_item)
on this optimization. */
if (original->merged_comdat && !alias->merged_comdat)
{
- if (dump_file)
- fprintf (dump_file, "Dropping merged_comdat flag.\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_NOTE, "Dropping merged_comdat flag.\n");
if (local_original)
local_original->merged_comdat = false;
original->merged_comdat = false;
@@ -1313,8 +1322,9 @@ sem_function::merge (sem_item *alias_item)
alias->reset ();
alias->body_removed = true;
alias->icf_merged = true;
- if (dump_file)
- fprintf (dump_file, "Unified; Function body was removed.\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_OPTIMIZED_LOCATIONS,
+ "Unified; Function body was removed.\n");
}
return true;
@@ -2085,18 +2095,21 @@ sem_variable::merge (sem_item *alias_item)
{
gcc_assert (alias_item->type == VAR);
+ AUTO_DUMP_SCOPE ("merge",
+ dump_user_location_t::from_function_decl (decl));
if (!sem_item::target_supports_symbol_aliases_p ())
{
- if (dump_file)
- fprintf (dump_file, "Not unifying; "
- "Symbol aliases are not supported by target\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION, "Not unifying; "
+ "Symbol aliases are not supported by target\n");
return false;
}
if (DECL_EXTERNAL (alias_item->decl))
{
- if (dump_file)
- fprintf (dump_file, "Not unifying; alias is external.\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Not unifying; alias is external.\n");
return false;
}
@@ -2128,9 +2141,9 @@ sem_variable::merge (sem_item *alias_item)
if (DECL_IN_CONSTANT_POOL (alias->decl)
|| DECL_IN_CONSTANT_POOL (original->decl))
{
- if (dump_file)
- fprintf (dump_file,
- "Not unifying; constant pool variables.\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Not unifying; constant pool variables.\n");
return false;
}
@@ -2140,45 +2153,48 @@ sem_variable::merge (sem_item *alias_item)
|| (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
&& DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
{
- if (dump_file)
- fprintf (dump_file,
- "Not unifying; "
- "original and alias are in different sections.\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Not unifying; "
+ "original and alias are in different sections.\n");
return false;
}
/* We cannot merge if address comparsion metters. */
if (alias_address_matters && flag_merge_constants < 2)
{
- if (dump_file)
- fprintf (dump_file,
- "Not unifying; address of original may be compared.\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Not unifying; address of original may be compared.\n");
return false;
}
if (DECL_ALIGN (original->decl) < DECL_ALIGN (alias->decl))
{
- if (dump_file)
- fprintf (dump_file, "Not unifying; "
- "original and alias have incompatible alignments\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Not unifying; "
+ "original and alias have incompatible alignments\n");
return false;
}
if (DECL_COMDAT_GROUP (original->decl) != DECL_COMDAT_GROUP (alias->decl))
{
- if (dump_file)
- fprintf (dump_file, "Not unifying; alias cannot be created; "
- "across comdat group boundary\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Not unifying; alias cannot be created; "
+ "across comdat group boundary\n");
return false;
}
if (original_discardable)
{
- if (dump_file)
- fprintf (dump_file, "Not unifying; alias cannot be created; "
- "target is discardable\n\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "Not unifying; alias cannot be created; "
+ "target is discardable\n");
return false;
}
@@ -2199,8 +2215,9 @@ sem_variable::merge (sem_item *alias_item)
varpool_node::create_alias (alias_var->decl, decl);
alias->resolve_alias (original);
- if (dump_file)
- fprintf (dump_file, "Unified; Variable alias has been created.\n");
+ if (dump_enabled_p ())
+ dump_printf (MSG_OPTIMIZED_LOCATIONS,
+ "Unified; Variable alias has been created.\n");
return true;
}
@@ -3477,23 +3494,26 @@ sem_item_optimizer::merge_classes (unsigned int prev_class_count)
if (alias == source)
continue;
- if (dump_file)
+ dump_user_location_t loc
+ = dump_user_location_t::from_function_decl (source->decl);
+ if (dump_enabled_p ())
{
- fprintf (dump_file, "Semantic equality hit:%s->%s\n",
- xstrdup_for_dump (source->node->name ()),
- xstrdup_for_dump (alias->node->name ()));
- fprintf (dump_file, "Assembler symbol names:%s->%s\n",
- xstrdup_for_dump (source->node->asm_name ()),
- xstrdup_for_dump (alias->node->asm_name ()));
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
+ "Semantic equality hit:%s->%s\n",
+ xstrdup_for_dump (source->node->name ()),
+ xstrdup_for_dump (alias->node->name ()));
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
+ "Assembler symbol names:%s->%s\n",
+ xstrdup_for_dump (source->node->asm_name ()),
+ xstrdup_for_dump (alias->node->asm_name ()));
}
if (lookup_attribute ("no_icf", DECL_ATTRIBUTES (alias->decl)))
{
- if (dump_file)
- fprintf (dump_file,
- "Merge operation is skipped due to no_icf "
- "attribute.\n\n");
-
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
+ "Merge operation is skipped due to no_icf "
+ "attribute.\n");
continue;
}
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index 4a3a193..897c563 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -237,10 +237,13 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
}
}
-/* Check all speculations in N and resolve them if they seems useless. */
+/* Check all speculations in N and if any seem useless, resolve them. When a
+ first edge is resolved, pop all edges from NEW_EDGES and insert them to
+ EDGE_SET. Then remove each resolved edge from EDGE_SET, if it is there. */
static bool
-check_speculations (cgraph_node *n)
+check_speculations_1 (cgraph_node *n, vec<cgraph_edge *> *new_edges,
+ hash_set <cgraph_edge *> *edge_set)
{
bool speculation_removed = false;
cgraph_edge *next;
@@ -250,15 +253,46 @@ check_speculations (cgraph_node *n)
next = e->next_callee;
if (e->speculative && !speculation_useful_p (e, true))
{
+ while (new_edges && !new_edges->is_empty ())
+ edge_set->add (new_edges->pop ());
+ edge_set->remove (e);
+
e->resolve_speculation (NULL);
speculation_removed = true;
}
else if (!e->inline_failed)
- speculation_removed |= check_speculations (e->callee);
+ speculation_removed |= check_speculations_1 (e->callee, new_edges,
+ edge_set);
}
return speculation_removed;
}
+/* Push E to NEW_EDGES. Called from hash_set traverse method, which
+ unfortunately means this function has to have external linkage, otherwise
+ the code will not compile with gcc 4.8. */
+
+bool
+push_all_edges_in_set_to_vec (cgraph_edge * const &e,
+ vec<cgraph_edge *> *new_edges)
+{
+ new_edges->safe_push (e);
+ return true;
+}
+
+/* Check all speculations in N and if any seem useless, resolve them and remove
+ them from NEW_EDGES. */
+
+static bool
+check_speculations (cgraph_node *n, vec<cgraph_edge *> *new_edges)
+{
+ hash_set <cgraph_edge *> edge_set;
+ bool res = check_speculations_1 (n, new_edges, &edge_set);
+ if (!edge_set.is_empty ())
+ edge_set.traverse <vec<cgraph_edge *> *,
+ push_all_edges_in_set_to_vec> (new_edges);
+ return res;
+}
+
/* Mark all call graph edges coming out of NODE and all nodes that have been
inlined to it as in_polymorphic_cdtor. */
@@ -450,7 +484,7 @@ inline_call (struct cgraph_edge *e, bool update_original,
mark_all_inlined_calls_cdtor (e->callee);
if (opt_for_fn (e->caller->decl, optimize))
new_edges_found = ipa_propagate_indirect_call_infos (curr, new_edges);
- check_speculations (e->callee);
+ check_speculations (e->callee, new_edges);
if (update_overall_summary)
ipa_update_overall_fn_summary (to);
else
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 5862d00..b62d280 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -810,7 +810,7 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
| INLINE_HINT_loop_stride))
&& !(big_speedup = big_speedup_p (e)))))
{
- e->inline_failed = CIF_MAX_INLINE_INSNS_SINGLE_LIMIT;
+ e->inline_failed = CIF_MAX_INLINE_INSNS_SINGLE_LIMIT;
want_inline = false;
}
else if (!DECL_DECLARED_INLINE_P (callee->decl)
@@ -818,12 +818,12 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
&& growth >= PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SMALL))
{
/* growth_likely_positive is expensive, always test it last. */
- if (growth >= MAX_INLINE_INSNS_SINGLE
+ if (growth >= MAX_INLINE_INSNS_SINGLE
|| growth_likely_positive (callee, growth))
{
- e->inline_failed = CIF_NOT_DECLARED_INLINED;
+ e->inline_failed = CIF_NOT_DECLARED_INLINED;
want_inline = false;
- }
+ }
}
/* Apply MAX_INLINE_INSNS_AUTO limit for functions not declared inline
Upgrade it to MAX_INLINE_INSNS_SINGLE when hints suggests that
@@ -839,19 +839,22 @@ want_inline_small_function_p (struct cgraph_edge *e, bool report)
&& !(big_speedup == -1 ? big_speedup_p (e) : big_speedup))
{
/* growth_likely_positive is expensive, always test it last. */
- if (growth >= MAX_INLINE_INSNS_SINGLE
+ if (growth >= MAX_INLINE_INSNS_SINGLE
|| growth_likely_positive (callee, growth))
{
e->inline_failed = CIF_MAX_INLINE_INSNS_AUTO_LIMIT;
want_inline = false;
- }
+ }
}
/* If call is cold, do not inline when function body would grow. */
else if (!e->maybe_hot_p ()
&& (growth >= MAX_INLINE_INSNS_SINGLE
|| growth_likely_positive (callee, growth)))
{
- e->inline_failed = CIF_UNLIKELY_CALL;
+ if (e->count.ipa () == profile_count::zero ())
+ e->inline_failed = CIF_NEVER_CALL;
+ else
+ e->inline_failed = CIF_UNLIKELY_CALL;
want_inline = false;
}
}
@@ -1626,6 +1629,7 @@ add_new_edges_to_heap (edge_heap_t *heap, vec<cgraph_edge *> new_edges)
struct cgraph_edge *edge = new_edges.pop ();
gcc_assert (!edge->aux);
+ gcc_assert (edge->callee);
if (edge->inline_failed
&& can_inline_edge_p (edge, true)
&& want_inline_small_function_p (edge, true)
@@ -1653,6 +1657,10 @@ heap_edge_removal_hook (struct cgraph_edge *e, void *data)
bool
speculation_useful_p (struct cgraph_edge *e, bool anticipate_inlining)
{
+ /* If we have already decided to inline the edge, it seems useful. */
+ if (!e->inline_failed)
+ return true;
+
enum availability avail;
struct cgraph_node *target = e->callee->ultimate_alias_target (&avail,
e->caller);
@@ -1687,12 +1695,11 @@ speculation_useful_p (struct cgraph_edge *e, bool anticipate_inlining)
to an ipa-cp clone (that are seen by having local flag set),
it is probably pointless to inline it unless hardware is missing
indirect call predictor. */
- if (!anticipate_inlining && e->inline_failed && !target->local.local)
+ if (!anticipate_inlining && !target->local.local)
return false;
/* For overwritable targets there is not much to do. */
- if (e->inline_failed
- && (!can_inline_edge_p (e, false)
- || !can_inline_edge_by_limits_p (e, false, true)))
+ if (!can_inline_edge_p (e, false)
+ || !can_inline_edge_by_limits_p (e, false, true))
return false;
/* OK, speculation seems interesting. */
return true;
diff --git a/gcc/ipa-param-manipulation.c b/gcc/ipa-param-manipulation.c
index 037253a..1af6d05 100644
--- a/gcc/ipa-param-manipulation.c
+++ b/gcc/ipa-param-manipulation.c
@@ -219,10 +219,7 @@ ipa_modify_formal_parameters (tree fndecl, ipa_parm_adjustment_vec adjustments)
/* When signature changes, we need to clear builtin info. */
if (fndecl_built_in_p (fndecl))
- {
- DECL_BUILT_IN_CLASS (fndecl) = NOT_BUILT_IN;
- DECL_FUNCTION_CODE (fndecl) = (enum built_in_function) 0;
- }
+ set_decl_built_in_function (fndecl, NOT_BUILT_IN, 0);
TREE_TYPE (fndecl) = new_type;
DECL_VIRTUAL_P (fndecl) = 0;
@@ -452,14 +449,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gcall *stmt,
gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
gimple_call_copy_flags (new_stmt, stmt);
if (gimple_in_ssa_p (cfun))
- {
- gimple_set_vuse (new_stmt, gimple_vuse (stmt));
- if (gimple_vdef (stmt))
- {
- gimple_set_vdef (new_stmt, gimple_vdef (stmt));
- SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
- }
- }
+ gimple_move_vops (new_stmt, stmt);
if (dump_file && (dump_flags & TDF_DETAILS))
{
diff --git a/gcc/ipa-predicate.c b/gcc/ipa-predicate.c
index 49622e9..8a9851a 100644
--- a/gcc/ipa-predicate.c
+++ b/gcc/ipa-predicate.c
@@ -523,7 +523,7 @@ predicate::stream_out (struct output_block *ob)
predicate
add_condition (class ipa_fn_summary *summary, int operand_num,
- HOST_WIDE_INT size, struct agg_position_info *aggpos,
+ poly_int64 size, struct agg_position_info *aggpos,
enum tree_code code, tree val)
{
int i;
@@ -549,7 +549,7 @@ add_condition (class ipa_fn_summary *summary, int operand_num,
for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++)
{
if (c->operand_num == operand_num
- && c->size == size
+ && known_eq (c->size, size)
&& c->code == code
&& c->val == val
&& c->agg_contents == agg_contents
diff --git a/gcc/ipa-predicate.h b/gcc/ipa-predicate.h
index c2adba3..237306d 100644
--- a/gcc/ipa-predicate.h
+++ b/gcc/ipa-predicate.h
@@ -31,7 +31,7 @@ struct GTY(()) condition
loaded. */
HOST_WIDE_INT offset;
/* Size of the access reading the data (or the PARM_DECL SSA_NAME). */
- HOST_WIDE_INT size;
+ poly_int64 size;
tree val;
int operand_num;
ENUM_BITFIELD(tree_code) code : 16;
@@ -228,5 +228,5 @@ private:
void dump_condition (FILE *f, conditions conditions, int cond);
predicate add_condition (class ipa_fn_summary *summary, int operand_num,
- HOST_WIDE_INT size, struct agg_position_info *aggpos,
+ poly_int64 size, struct agg_position_info *aggpos,
enum tree_code code, tree val);
diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
index 1fb939b..970dba3 100644
--- a/gcc/ipa-profile.c
+++ b/gcc/ipa-profile.c
@@ -192,8 +192,8 @@ ipa_profile_generate_summary (void)
if (h)
{
gcov_type val, count, all;
- if (get_most_common_single_value (NULL, "indirect call",
- h, &val, &count, &all))
+ if (get_nth_most_common_value (NULL, "indirect call", h,
+ &val, &count, &all))
{
struct cgraph_edge * e = node->get_edge (stmt);
if (e && !e->indirect_unknown_callee)
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 344b78e..1a0e12e 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -1059,7 +1059,7 @@ bool
ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
vec<ipa_param_descriptor, va_gc> *descriptors,
gimple *stmt, tree op, int *index_p,
- HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
+ HOST_WIDE_INT *offset_p, poly_int64 *size_p,
bool *by_ref_p, bool *guaranteed_unmodified)
{
int index;
@@ -3331,8 +3331,7 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
if (can_refer)
{
if (!t
- || (TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE
- && DECL_FUNCTION_CODE (t) == BUILT_IN_UNREACHABLE)
+ || fndecl_built_in_p (t, BUILT_IN_UNREACHABLE)
|| !possible_polymorphic_call_target_p
(ie, cgraph_node::get (t)))
{
@@ -4917,7 +4916,8 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
struct ipa_agg_replacement_value *v;
gimple *stmt = gsi_stmt (gsi);
tree rhs, val, t;
- HOST_WIDE_INT offset, size;
+ HOST_WIDE_INT offset;
+ poly_int64 size;
int index;
bool by_ref, vce;
@@ -4952,7 +4952,8 @@ ipcp_modif_dom_walker::before_dom_children (basic_block bb)
break;
if (!v
|| v->by_ref != by_ref
- || tree_to_shwi (TYPE_SIZE (TREE_TYPE (v->value))) != size)
+ || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v->value))),
+ size))
continue;
gcc_checking_assert (is_gimple_ip_invariant (v->value));
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 6470c93..30948fb 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -763,7 +763,7 @@ tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg, tree scalar,
bool ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
vec<ipa_param_descriptor, va_gc> *descriptors,
gimple *stmt, tree op, int *index_p,
- HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
+ HOST_WIDE_INT *offset_p, poly_int64 *size_p,
bool *by_ref, bool *guaranteed_unmodified = NULL);
/* Debugging interface. */
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index db91d2c1..4b2a79f 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -199,7 +199,7 @@ suggest_attribute (int option, tree decl, bool known_finite,
hash_set<tree> *warned_about,
const char * attrib_name)
{
- if (!option_enabled (option, &global_options))
+ if (!option_enabled (option, lang_hooks.option_lang_mask (), &global_options))
return warned_about;
if (TREE_THIS_VOLATILE (decl)
|| (known_finite && function_always_visible_to_compiler_p (decl)))
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 86b26d3..cecfe05 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1351,10 +1351,7 @@ split_function (basic_block return_bb, class split_point *split_point,
changes. For partial inlining we however cannot expect the part
of builtin implementation to have same semantic as the whole. */
if (fndecl_built_in_p (node->decl))
- {
- DECL_BUILT_IN_CLASS (node->decl) = NOT_BUILT_IN;
- DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0;
- }
+ set_decl_built_in_function (node->decl, NOT_BUILT_IN, 0);
/* If return_bb contains any clobbers that refer to SSA_NAMEs
set in the split part, remove them. Also reset debug stmts that
diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog
index af3f6b7..110367e 100644
--- a/gcc/jit/ChangeLog
+++ b/gcc/jit/ChangeLog
@@ -1,4 +1,9 @@
-2019-07-22 Andrea Corallo <andrea.corallo@arm.com>
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR middle-end/91421
+ * jit-playback.c (new_function): Use set_decl_built_in_function.
+
+2019-07-22 Andrea Corallo <andrea.corallo@arm.com>
* jit-recording.c (unary_op_reproducer_strings): Make it extern.
(binary_op_reproducer_strings): Likewise.
@@ -8,12 +13,12 @@
numeric type.
* libgccjit.c (gcc_jit_context_new_binary_op): Improve error message.
-2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
+2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
* libgccjit.c (gcc_jit_context_new_binary_op): Check result_type to be a
numeric type.
-2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
+2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
* docs/topics/compatibility.rst (LIBGCCJIT_ABI_12): New ABI tag.
* docs/topics/types.rst: Add gcc_jit_context_new_bitfield.
@@ -50,7 +55,7 @@
* jit-recording.c (reproducer::m_set_identifiers): Use false as Lazy
in hash_set template param.
-2019-02-05 Andrea Corallo <andrea.corallo@arm.com>
+2019-02-05 Andrea Corallo <andrea.corallo@arm.com>
* docs/topics/compatibility.rst (LIBGCCJIT_ABI_11): New ABI tag.
* docs/topics/contexts.rst (Additional driver options): New
diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
index 942c7304..9eeb2a7 100644
--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -453,12 +453,11 @@ new_function (location *loc,
if (builtin_id)
{
- DECL_FUNCTION_CODE (fndecl) = builtin_id;
gcc_assert (loc == NULL);
DECL_SOURCE_LOCATION (fndecl) = BUILTINS_LOCATION;
- DECL_BUILT_IN_CLASS (fndecl) =
- builtins_manager::get_class (builtin_id);
+ built_in_class fclass = builtins_manager::get_class (builtin_id);
+ set_decl_built_in_function (fndecl, fclass, builtin_id);
set_builtin_decl (builtin_id, fndecl,
builtins_manager::implicit_p (builtin_id));
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 2df97f2..22ace13 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -615,12 +615,8 @@ add_builtin_function_common (const char *name,
TREE_PUBLIC (decl) = 1;
DECL_EXTERNAL (decl) = 1;
- DECL_BUILT_IN_CLASS (decl) = cl;
- DECL_FUNCTION_CODE (decl) = (enum built_in_function) function_code;
-
- /* DECL_FUNCTION_CODE is a bitfield; verify that the value fits. */
- gcc_assert (DECL_FUNCTION_CODE (decl) == function_code);
+ set_decl_built_in_function (decl, cl, function_code);
if (library_name)
{
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 55d8d13..f258407 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -1866,11 +1866,12 @@ prohibited_class_reg_set_mode_p (enum reg_class rclass,
alternative. */
static unsigned int curr_small_class_check = 0;
-/* Update number of used inputs of class OP_CLASS for operand NOP.
- Return true if we have more such class operands than the number of
- available regs. */
+/* Update number of used inputs of class OP_CLASS for operand NOP
+ of alternative NALT. Return true if we have more such class operands
+ than the number of available regs. */
static bool
-update_and_check_small_class_inputs (int nop, enum reg_class op_class)
+update_and_check_small_class_inputs (int nop, int nalt,
+ enum reg_class op_class)
{
static unsigned int small_class_check[LIM_REG_CLASSES];
static int small_class_input_nums[LIM_REG_CLASSES];
@@ -1881,7 +1882,7 @@ update_and_check_small_class_inputs (int nop, enum reg_class op_class)
&& hard_reg_set_intersect_p (reg_class_contents[op_class],
ira_no_alloc_regs)
&& (curr_static_id->operand[nop].type != OP_OUT
- || curr_static_id->operand[nop].early_clobber))
+ || TEST_BIT (curr_static_id->operand[nop].early_clobber_alts, nalt)))
{
if (small_class_check[op_class] == curr_small_class_check)
small_class_input_nums[op_class]++;
@@ -2150,7 +2151,8 @@ process_alt_operands (int only_alternative)
/* We should reject matching of an early
clobber operand if the matching operand is
not dying in the insn. */
- if (! curr_static_id->operand[m].early_clobber
+ if (!TEST_BIT (curr_static_id->operand[m]
+ .early_clobber_alts, nalt)
|| operand_reg[nop] == NULL_RTX
|| (find_regno_note (curr_insn, REG_DEAD,
REGNO (op))
@@ -2171,6 +2173,14 @@ process_alt_operands (int only_alternative)
}
else
{
+ /* If the operands do not match and one
+ operand is INOUT, we can not match them.
+ Try other possibilities, e.g. other
+ alternatives or commutative operand
+ exchange. */
+ if (curr_static_id->operand[nop].type == OP_INOUT
+ || curr_static_id->operand[m].type == OP_INOUT)
+ break;
/* Operands don't match. If the operands are
different user defined explicit hard
registers, then we cannot make them match
@@ -2226,7 +2236,8 @@ process_alt_operands (int only_alternative)
it results in less hard regs required for
the insn than a non-matching earlyclobber
alternative. */
- if (curr_static_id->operand[m].early_clobber)
+ if (TEST_BIT (curr_static_id->operand[m]
+ .early_clobber_alts, nalt))
{
if (lra_dump_file != NULL)
fprintf
@@ -2867,7 +2878,8 @@ process_alt_operands (int only_alternative)
goto fail;
}
- if (update_and_check_small_class_inputs (nop, this_alternative))
+ if (update_and_check_small_class_inputs (nop, nalt,
+ this_alternative))
{
if (lra_dump_file != NULL)
fprintf (lra_dump_file,
diff --git a/gcc/lra-int.h b/gcc/lra-int.h
index f8db969..77abb7b 100644
--- a/gcc/lra-int.h
+++ b/gcc/lra-int.h
@@ -142,10 +142,6 @@ struct lra_operand_data
unsigned int strict_low : 1;
/* True if the operand is an operator. */
unsigned int is_operator : 1;
- /* True if there is an early clobber alternative for this operand.
- This field is set up every time when corresponding
- operand_alternative in lra_static_insn_data is set up. */
- unsigned int early_clobber : 1;
/* True if the operand is an address. */
unsigned int is_address : 1;
};
@@ -164,9 +160,6 @@ struct lra_insn_reg
/* True if the reg is accessed through a subreg and the subreg is
just a part of the register. */
unsigned int subreg_p : 1;
- /* True if there is an early clobber alternative for this
- operand. */
- unsigned int early_clobber : 1;
/* True if the reg is clobber highed by the operand. */
unsigned int clobber_high : 1;
/* The corresponding regno of the register. */
@@ -403,6 +396,7 @@ extern bool lra_coalesce (void);
/* lra-spills.c: */
+extern bool lra_need_for_scratch_reg_p (void);
extern bool lra_need_for_spills_p (void);
extern void lra_spill (void);
extern void lra_final_code_change (void);
diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c
index 96aa7c4..057ef8c 100644
--- a/gcc/lra-lives.c
+++ b/gcc/lra-lives.c
@@ -624,10 +624,10 @@ check_pseudos_live_through_calls (int regno,
static inline bool
reg_early_clobber_p (const struct lra_insn_reg *reg, int n_alt)
{
- return (reg->early_clobber
- && (n_alt == LRA_UNKNOWN_ALT
- || (n_alt != LRA_NON_CLOBBERED_ALT
- && TEST_BIT (reg->early_clobber_alts, n_alt))));
+ return (n_alt == LRA_UNKNOWN_ALT
+ ? reg->early_clobber_alts != 0
+ : (n_alt != LRA_NON_CLOBBERED_ALT
+ && TEST_BIT (reg->early_clobber_alts, n_alt)));
}
/* Return true if call instructions CALL1 and CALL2 use ABIs that
diff --git a/gcc/lra-remat.c b/gcc/lra-remat.c
index 6a5bf4f..ef2a552 100644
--- a/gcc/lra-remat.c
+++ b/gcc/lra-remat.c
@@ -1021,7 +1021,6 @@ get_hard_regs (struct lra_insn_reg *reg, int &nregs)
static void
update_scratch_ops (rtx_insn *remat_insn)
{
- int hard_regno;
lra_insn_recog_data_t id = lra_get_insn_recog_data (remat_insn);
struct lra_static_insn_data *static_id = id->insn_static_data;
for (int i = 0; i < static_id->n_operands; i++)
@@ -1032,17 +1031,9 @@ update_scratch_ops (rtx_insn *remat_insn)
int regno = REGNO (*loc);
if (! lra_former_scratch_p (regno))
continue;
- hard_regno = reg_renumber[regno];
*loc = lra_create_new_reg (GET_MODE (*loc), *loc,
lra_get_allocno_class (regno),
"scratch pseudo copy");
- if (hard_regno >= 0)
- {
- reg_renumber[REGNO (*loc)] = hard_regno;
- if (lra_dump_file)
- fprintf (lra_dump_file, " Assigning the same %d to r%d\n",
- REGNO (*loc), hard_regno);
- }
lra_register_new_scratch_op (remat_insn, i, id->icode);
}
diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c
index c73d501..a322da8 100644
--- a/gcc/lra-spills.c
+++ b/gcc/lra-spills.c
@@ -549,6 +549,19 @@ spill_pseudos (void)
}
}
+/* Return true if we need scratch reg assignments. */
+bool
+lra_need_for_scratch_reg_p (void)
+{
+ int i; max_regno = max_reg_num ();
+
+ for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+ if (lra_reg_info[i].nrefs != 0 && lra_get_regno_hard_regno (i) < 0
+ && lra_former_scratch_p (i))
+ return true;
+ return false;
+}
+
/* Return true if we need to change some pseudos into memory. */
bool
lra_need_for_spills_p (void)
diff --git a/gcc/lra.c b/gcc/lra.c
index af40f43..1f97744 100644
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -536,16 +536,14 @@ object_allocator<lra_insn_reg> lra_insn_reg_pool ("insn regs");
/* Create LRA insn related info about a reference to REGNO in INSN
with TYPE (in/out/inout), biggest reference mode MODE, flag that it
- is reference through subreg (SUBREG_P), flag that is early
- clobbered in the insn (EARLY_CLOBBER), and reference to the next
+ is reference through subreg (SUBREG_P), and reference to the next
insn reg info (NEXT). If REGNO can be early clobbered,
alternatives in which it can be early clobbered are given by
EARLY_CLOBBER_ALTS. CLOBBER_HIGH marks if reference is a clobber
high. */
static struct lra_insn_reg *
new_insn_reg (rtx_insn *insn, int regno, enum op_type type,
- machine_mode mode,
- bool subreg_p, bool early_clobber,
+ machine_mode mode, bool subreg_p,
alternative_mask early_clobber_alts,
struct lra_insn_reg *next, bool clobber_high)
{
@@ -556,7 +554,6 @@ new_insn_reg (rtx_insn *insn, int regno, enum op_type type,
&& partial_subreg_p (lra_reg_info[regno].biggest_mode, mode))
lra_reg_info[regno].biggest_mode = mode;
ir->subreg_p = subreg_p;
- ir->early_clobber = early_clobber;
ir->early_clobber_alts = early_clobber_alts;
ir->clobber_high = clobber_high;
ir->regno = regno;
@@ -605,7 +602,7 @@ static struct lra_operand_data debug_operand_data =
0, /* early_clobber_alts */
E_VOIDmode, /* We are not interesting in the operand mode. */
OP_IN,
- 0, 0, 0, 0
+ 0, 0, 0
};
/* The following data are used as static insn data for all debug
@@ -801,7 +798,6 @@ setup_operand_alternative (lra_insn_recog_data_t data,
for (i = 0; i < nop; i++)
{
static_data->operand[i].early_clobber_alts = 0;
- static_data->operand[i].early_clobber = false;
static_data->operand[i].is_address = false;
if (static_data->operand[i].constraint[0] == '%')
{
@@ -817,7 +813,6 @@ setup_operand_alternative (lra_insn_recog_data_t data,
for (j = 0; j < nalt; j++)
for (i = 0; i < nop; i++, op_alt++)
{
- static_data->operand[i].early_clobber |= op_alt->earlyclobber;
if (op_alt->earlyclobber)
static_data->operand[i].early_clobber_alts |= (alternative_mask) 1 << j;
static_data->operand[i].is_address |= op_alt->is_address;
@@ -878,10 +873,7 @@ collect_non_operand_hard_regs (rtx_insn *insn, rtx *x,
if (curr->type != type)
curr->type = OP_INOUT;
if (early_clobber)
- {
- curr->early_clobber = true;
- curr->early_clobber_alts = ALL_ALTERNATIVES;
- }
+ curr->early_clobber_alts = ALL_ALTERNATIVES;
break;
}
if (curr == NULL)
@@ -897,7 +889,6 @@ collect_non_operand_hard_regs (rtx_insn *insn, rtx *x,
&& regno <= LAST_STACK_REG));
#endif
list = new_insn_reg (data->insn, regno, type, mode, subreg_p,
- early_clobber,
early_clobber ? ALL_ALTERNATIVES : 0, list,
clobber_high);
}
@@ -1449,15 +1440,13 @@ lra_get_copy (int n)
/* This page contains code dealing with info about registers in
insns. */
-/* Process X of INSN recursively and add info (operand type is
- given by TYPE, flag of that it is early clobber is EARLY_CLOBBER)
- about registers in X to the insn DATA. If X can be early clobbered,
- alternatives in which it can be early clobbered are given by
- EARLY_CLOBBER_ALTS. */
+/* Process X of INSN recursively and add info (operand type is given
+ by TYPE) about registers in X to the insn DATA. If X can be early
+ clobbered, alternatives in which it can be early clobbered are given
+ by EARLY_CLOBBER_ALTS. */
static void
add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x,
- rtx_insn *insn,
- enum op_type type, bool early_clobber,
+ rtx_insn *insn, enum op_type type,
alternative_mask early_clobber_alts)
{
int i, j, regno;
@@ -1487,8 +1476,7 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x,
if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, INSN_UID (insn)))
{
data->regs = new_insn_reg (data->insn, regno, type, mode, subreg_p,
- early_clobber, early_clobber_alts,
- data->regs, false);
+ early_clobber_alts, data->regs, false);
return;
}
else
@@ -1500,15 +1488,12 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x,
/* The info cannot be integrated into the found
structure. */
data->regs = new_insn_reg (data->insn, regno, type, mode,
- subreg_p, early_clobber,
- early_clobber_alts, data->regs,
- false);
+ subreg_p, early_clobber_alts,
+ data->regs, false);
else
{
if (curr->type != type)
curr->type = OP_INOUT;
- if (curr->early_clobber != early_clobber)
- curr->early_clobber = true;
curr->early_clobber_alts |= early_clobber_alts;
}
return;
@@ -1520,23 +1505,23 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x,
switch (code)
{
case SET:
- add_regs_to_insn_regno_info (data, SET_DEST (x), insn, OP_OUT, false, 0);
- add_regs_to_insn_regno_info (data, SET_SRC (x), insn, OP_IN, false, 0);
+ add_regs_to_insn_regno_info (data, SET_DEST (x), insn, OP_OUT, 0);
+ add_regs_to_insn_regno_info (data, SET_SRC (x), insn, OP_IN, 0);
break;
case CLOBBER:
/* We treat clobber of non-operand hard registers as early
clobber. */
add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_OUT,
- true, ALL_ALTERNATIVES);
+ ALL_ALTERNATIVES);
break;
case CLOBBER_HIGH:
gcc_unreachable ();
case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
- add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, false, 0);
+ add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, 0);
break;
case PRE_MODIFY: case POST_MODIFY:
- add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, false, 0);
- add_regs_to_insn_regno_info (data, XEXP (x, 1), insn, OP_IN, false, 0);
+ add_regs_to_insn_regno_info (data, XEXP (x, 0), insn, OP_INOUT, 0);
+ add_regs_to_insn_regno_info (data, XEXP (x, 1), insn, OP_IN, 0);
break;
default:
if ((code != PARALLEL && code != EXPR_LIST) || type != OP_OUT)
@@ -1557,12 +1542,12 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x,
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
- add_regs_to_insn_regno_info (data, XEXP (x, i), insn, type, false, 0);
+ add_regs_to_insn_regno_info (data, XEXP (x, i), insn, type, 0);
else if (fmt[i] == 'E')
{
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
add_regs_to_insn_regno_info (data, XVECEXP (x, i, j), insn,
- type, false, 0);
+ type, 0);
}
}
}
@@ -1652,11 +1637,10 @@ lra_update_insn_regno_info (rtx_insn *insn)
for (i = static_data->n_operands - 1; i >= 0; i--)
add_regs_to_insn_regno_info (data, *data->operand_loc[i], insn,
static_data->operand[i].type,
- static_data->operand[i].early_clobber,
static_data->operand[i].early_clobber_alts);
if ((code = GET_CODE (PATTERN (insn))) == CLOBBER || code == USE)
add_regs_to_insn_regno_info (data, XEXP (PATTERN (insn), 0), insn,
- code == USE ? OP_IN : OP_OUT, false, 0);
+ code == USE ? OP_IN : OP_OUT, 0);
if (CALL_P (insn))
/* On some targets call insns can refer to pseudos in memory in
CALL_INSN_FUNCTION_USAGE list. Process them in order to
@@ -1673,7 +1657,7 @@ lra_update_insn_regno_info (rtx_insn *insn)
if ((code == USE || code == CLOBBER)
&& MEM_P (XEXP (XEXP (link, 0), 0)))
add_regs_to_insn_regno_info (data, XEXP (XEXP (link, 0), 0), insn,
- code == USE ? OP_IN : OP_OUT, false, 0);
+ code == USE ? OP_IN : OP_OUT, 0);
}
if (NONDEBUG_INSN_P (insn))
setup_insn_reg_info (data, freq);
@@ -2583,7 +2567,11 @@ lra (FILE *f)
lra_create_live_ranges (lra_reg_spill_p, true);
live_p = true;
if (! lra_need_for_spills_p ())
- break;
+ {
+ if (lra_need_for_scratch_reg_p ())
+ continue;
+ break;
+ }
}
lra_spill ();
/* Assignment of stack slots changes elimination offsets for
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index e0881cf5..d85b03a 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -1121,12 +1121,12 @@ hash_tree (struct streamer_tree_cache_d *cache, hash_map<tree, hashval_t> *map,
hstate.add_int (DECL_BUILT_IN_CLASS (t));
hstate.add_flag (DECL_STATIC_CONSTRUCTOR (t));
hstate.add_flag (DECL_STATIC_DESTRUCTOR (t));
+ hstate.add_flag (FUNCTION_DECL_DECL_TYPE (t));
hstate.add_flag (DECL_UNINLINABLE (t));
hstate.add_flag (DECL_POSSIBLY_INLINED (t));
hstate.add_flag (DECL_IS_NOVOPS (t));
hstate.add_flag (DECL_IS_RETURNS_TWICE (t));
hstate.add_flag (DECL_IS_MALLOC (t));
- hstate.add_flag (DECL_IS_OPERATOR_NEW (t));
hstate.add_flag (DECL_DECLARED_INLINE_P (t));
hstate.add_flag (DECL_STATIC_CHAIN (t));
hstate.add_flag (DECL_NO_INLINE_WARNING_P (t));
@@ -1137,7 +1137,7 @@ hash_tree (struct streamer_tree_cache_d *cache, hash_map<tree, hashval_t> *map,
hstate.add_flag (DECL_LOOPING_CONST_OR_PURE_P (t));
hstate.commit_flag ();
if (DECL_BUILT_IN_CLASS (t) != NOT_BUILT_IN)
- hstate.add_int (DECL_FUNCTION_CODE (t));
+ hstate.add_int (DECL_UNCHECKED_FUNCTION_CODE (t));
}
if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
@@ -2642,12 +2642,6 @@ write_symbol (struct streamer_tree_cache_d *cache,
const char *comdat;
unsigned char c;
- gcc_checking_assert (TREE_PUBLIC (t)
- && (TREE_CODE (t) != FUNCTION_DECL
- || !fndecl_built_in_p (t))
- && !DECL_ABSTRACT_P (t)
- && (!VAR_P (t) || !DECL_HARD_REGISTER (t)));
-
gcc_assert (VAR_OR_FUNCTION_DECL_P (t));
name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (t));
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index 9468977..68f63da 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -128,12 +128,11 @@ maybe_unlink (const char *file)
#define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
/* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
- environment according to LANG_MASK. */
+ environment. */
static void
get_options_from_collect_gcc_options (const char *collect_gcc,
const char *collect_gcc_options,
- unsigned int lang_mask,
struct cl_decoded_option **decoded_options,
unsigned int *decoded_options_count)
{
@@ -176,8 +175,7 @@ get_options_from_collect_gcc_options (const char *collect_gcc,
argc = obstack_object_size (&argv_obstack) / sizeof (void *) - 1;
argv = XOBFINISH (&argv_obstack, const char **);
- decode_cmdline_options_to_array (argc, (const char **)argv,
- lang_mask,
+ decode_cmdline_options_to_array (argc, (const char **)argv, CL_DRIVER,
decoded_options, decoded_options_count);
obstack_free (&argv_obstack, NULL);
}
@@ -1009,8 +1007,7 @@ find_and_merge_options (int fd, off_t file_offset, const char *prefix,
{
struct cl_decoded_option *f2decoded_options;
unsigned int f2decoded_options_count;
- get_options_from_collect_gcc_options (collect_gcc,
- fopts, CL_LANG_ALL,
+ get_options_from_collect_gcc_options (collect_gcc, fopts,
&f2decoded_options,
&f2decoded_options_count);
if (!fdecoded_options)
@@ -1110,6 +1107,136 @@ cmp_priority (const void *a, const void *b)
return *((const int *)b)-*((const int *)a);
}
+/* Number of CPUs that can be used for parallel LTRANS phase. */
+
+static unsigned long nthreads_var = 0;
+
+#ifdef HAVE_PTHREAD_AFFINITY_NP
+unsigned long cpuset_size;
+static unsigned long get_cpuset_size;
+cpu_set_t *cpusetp;
+
+unsigned long
+static cpuset_popcount (unsigned long cpusetsize, cpu_set_t *cpusetp)
+{
+#ifdef CPU_COUNT_S
+ /* glibc 2.7 and above provide a macro for this. */
+ return CPU_COUNT_S (cpusetsize, cpusetp);
+#else
+#ifdef CPU_COUNT
+ if (cpusetsize == sizeof (cpu_set_t))
+ /* glibc 2.6 and above provide a macro for this. */
+ return CPU_COUNT (cpusetp);
+#endif
+ size_t i;
+ unsigned long ret = 0;
+ STATIC_ASSERT (sizeof (cpusetp->__bits[0]) == sizeof (unsigned long int));
+ for (i = 0; i < cpusetsize / sizeof (cpusetp->__bits[0]); i++)
+ {
+ unsigned long int mask = cpusetp->__bits[i];
+ if (mask == 0)
+ continue;
+ ret += __builtin_popcountl (mask);
+ }
+ return ret;
+#endif
+}
+#endif
+
+/* At startup, determine the default number of threads. It would seem
+ this should be related to the number of cpus online. */
+
+static void
+init_num_threads (void)
+{
+#ifdef HAVE_PTHREAD_AFFINITY_NP
+#if defined (_SC_NPROCESSORS_CONF) && defined (CPU_ALLOC_SIZE)
+ cpuset_size = sysconf (_SC_NPROCESSORS_CONF);
+ cpuset_size = CPU_ALLOC_SIZE (cpuset_size);
+#else
+ cpuset_size = sizeof (cpu_set_t);
+#endif
+
+ cpusetp = (cpu_set_t *) xmalloc (gomp_cpuset_size);
+ do
+ {
+ int ret = pthread_getaffinity_np (pthread_self (), gomp_cpuset_size,
+ cpusetp);
+ if (ret == 0)
+ {
+ /* Count only the CPUs this process can use. */
+ nthreads_var = cpuset_popcount (cpuset_size, cpusetp);
+ if (nthreads_var == 0)
+ break;
+ get_cpuset_size = cpuset_size;
+#ifdef CPU_ALLOC_SIZE
+ unsigned long i;
+ for (i = cpuset_size * 8; i; i--)
+ if (CPU_ISSET_S (i - 1, cpuset_size, cpusetp))
+ break;
+ cpuset_size = CPU_ALLOC_SIZE (i);
+#endif
+ return;
+ }
+ if (ret != EINVAL)
+ break;
+#ifdef CPU_ALLOC_SIZE
+ if (cpuset_size < sizeof (cpu_set_t))
+ cpuset_size = sizeof (cpu_set_t);
+ else
+ cpuset_size = cpuset_size * 2;
+ if (cpuset_size < 8 * sizeof (cpu_set_t))
+ cpusetp
+ = (cpu_set_t *) realloc (cpusetp, cpuset_size);
+ else
+ {
+ /* Avoid fatal if too large memory allocation would be
+ requested, e.g. kernel returning EINVAL all the time. */
+ void *p = realloc (cpusetp, cpuset_size);
+ if (p == NULL)
+ break;
+ cpusetp = (cpu_set_t *) p;
+ }
+#else
+ break;
+#endif
+ }
+ while (1);
+ cpuset_size = 0;
+ nthreads_var = 1;
+ free (cpusetp);
+ cpusetp = NULL;
+#endif
+#ifdef _SC_NPROCESSORS_ONLN
+ nthreads_var = sysconf (_SC_NPROCESSORS_ONLN);
+#endif
+}
+
+/* FIXME: once using -std=c11, we can use std::thread::hardware_concurrency. */
+
+/* Return true when a jobserver is running and can accept a job. */
+
+static bool
+jobserver_active_p (void)
+{
+ const char *makeflags = getenv ("MAKEFLAGS");
+ if (makeflags == NULL)
+ return false;
+
+ const char *needle = "--jobserver-auth=";
+ const char *n = strstr (makeflags, needle);
+ if (n == NULL)
+ return false;
+
+ int rfd = -1;
+ int wfd = -1;
+
+ return (sscanf (n + strlen (needle), "%d,%d", &rfd, &wfd) == 2
+ && rfd > 0
+ && wfd > 0
+ && is_valid_fd (rfd)
+ && is_valid_fd (wfd));
+}
/* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
@@ -1124,6 +1251,7 @@ run_gcc (unsigned argc, char *argv[])
const char *collect_gcc, *collect_gcc_options;
int parallel = 0;
int jobserver = 0;
+ int auto_parallel = 0;
bool no_partition = false;
struct cl_decoded_option *fdecoded_options = NULL;
struct cl_decoded_option *offload_fdecoded_options = NULL;
@@ -1151,7 +1279,6 @@ run_gcc (unsigned argc, char *argv[])
fatal_error (input_location,
"environment variable %<COLLECT_GCC_OPTIONS%> must be set");
get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options,
- CL_LANG_ALL,
&decoded_options,
&decoded_options_count);
@@ -1247,9 +1374,11 @@ run_gcc (unsigned argc, char *argv[])
case OPT_flto_:
if (strcmp (option->arg, "jobserver") == 0)
+ jobserver = 1;
+ else if (strcmp (option->arg, "auto") == 0)
{
- jobserver = 1;
parallel = 1;
+ auto_parallel = 1;
}
else
{
@@ -1291,8 +1420,11 @@ run_gcc (unsigned argc, char *argv[])
{
lto_mode = LTO_MODE_LTO;
jobserver = 0;
+ auto_parallel = 0;
parallel = 0;
}
+ else if (!jobserver)
+ jobserver = jobserver_active_p ();
if (linker_output)
{
@@ -1484,7 +1616,21 @@ cont1:
strcpy (tmp, ltrans_output_file);
if (jobserver)
- obstack_ptr_grow (&argv_obstack, xstrdup ("-fwpa=jobserver"));
+ {
+ if (verbose)
+ fprintf (stderr, "Using make jobserver\n");
+ obstack_ptr_grow (&argv_obstack, xstrdup ("-fwpa=jobserver"));
+ }
+ else if (auto_parallel)
+ {
+ char buf[256];
+ init_num_threads ();
+ if (verbose)
+ fprintf (stderr, "LTO parallelism level set to %ld\n",
+ nthreads_var);
+ sprintf (buf, "-fwpa=%ld", nthreads_var);
+ obstack_ptr_grow (&argv_obstack, xstrdup (buf));
+ }
else if (parallel > 1)
{
char buf[256];
@@ -1692,7 +1838,8 @@ cont:
i = 3;
if (!jobserver)
{
- snprintf (jobs, 31, "-j%d", parallel);
+ snprintf (jobs, 31, "-j%ld",
+ auto_parallel ? nthreads_var : parallel);
new_argv[i++] = jobs;
}
new_argv[i++] = "all";
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index c18b2c4..2467d78 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,20 @@
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR middle-end/91421
+ * lto-common.c (compare_tree_sccs_1): Use DECL_UNCHECKED_FUNCTION_CODE
+ instead of DECL_FUNCTION_CODE.
+ * lto-symtab.c (lto_symtab_merge_p): Likewise.
+
+2019-08-01 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * Make-lang.in (lto.install-common): Remove unnecessary slash
+ between $(DESTDIR) and $(bindir).
+
+2019-07-25 Martin Liska <mliska@suse.cz>
+
+ * lto-common.c (compare_tree_sccs_1): Use new macros
+ (e.g. DECL_SET_LAMBDA_FUNCTION and DECL_LAMBDA_FUNCTION_P).
+
2019-07-22 Giuliano Belinassi <giuliano.belinassi@usp.br>
* lang.opt (flag_dump_callgraph): New flag.
@@ -61,6 +78,11 @@
(dump_list_functions): Release memory.
(dump_list_variables): Likewise.
+2019-06-25 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * lto-lang.c (lto_build_c_type_nodes): Accept "__intN__"
+ format of "__intN" types for SIZE_TYPE.
+
2019-06-24 Jan Hubicka <jh@suse.cz>
* lto-common.c (compare_tree_sccs_1): Compare CXX_ODR_P;
@@ -72,8 +94,8 @@
2019-05-16 Martin Sebor <msebor@redhat.com>
- * lto-dump.c (lto_main): Same.
- * lto.c (stream_out): Same.
+ * lto-dump.c (lto_main): Same.
+ * lto.c (stream_out): Same.
2019-05-10 Martin Liska <mliska@suse.cz>
@@ -205,7 +227,7 @@
2018-10-26 Jan Hubicka <jh@suse.cz>
- * lto/lto-symtab.c (lto_symtab_merge_decls_2): Fix extra space.
+ * lto-symtab.c (lto_symtab_merge_decls_2): Fix extra space.
2018-10-17 David Malcolm <dmalcolm@redhat.com>
@@ -230,7 +252,7 @@
2018-08-21 Tom de Vries <tdevries@suse.de>
- * lto.c (lto_main): Call debuginfo_early_start and
+ * lto.c (lto_main): Call debuginfo_early_start and
debuginfo_early_stop.
2018-07-20 Martin Sebor <msebor@redhat.com>
@@ -588,7 +610,7 @@
* lto-lang.c (lto_init): Set in_lto_p earlier.
2017-04-12 Richard Biener <rguenther@suse.de>
- Bernd Edlinger <bernd.edlinger@hotmail.de>
+ Bernd Edlinger <bernd.edlinger@hotmail.de>
PR middle-end/79671
* lto.c (compare_tree_sccs_1): Compare TYPE_TYPELESS_STORAGE.
@@ -694,7 +716,7 @@
2016-06-10 Martin Sebor <msebor@redhat.com>
PR c/71392
- * gcc/lto/lto-lang.c (handle_nonnull_attribute): Accept the nonnull
+ * lto-lang.c (handle_nonnull_attribute): Accept the nonnull
attribute in type-generic builtins.
2016-05-16 Jan Hubicka <hubicka@ucw.cz>
@@ -1037,7 +1059,6 @@
2015-06-08 Jan Hubicka <hubicka@ucw.cz>
-
* lto.c (hash_canonical_type): Do not hash TREE_CODE of TREE_TYPE of
pointers.
@@ -1243,7 +1264,7 @@
Andrey Turetskiy <andrey.turetskiy@intel.com>
Michael Zolotukhin <michael.v.zolotukhin@intel.com>
- * lto/lto.c (read_cgraph_and_symbols): Call input_offload_tables.
+ * lto.c (read_cgraph_and_symbols): Call input_offload_tables.
2014-11-13 Ilya Verbin <ilya.verbin@intel.com>
Ilya Tocar <ilya.tocar@intel.com>
@@ -1397,7 +1418,7 @@
2014-07-11 Jan Hubicka <hubicka@ucw.cz>
- * lto-partition.c (add_references_to_partition): Use
+ * lto-partition.c (add_references_to_partition): Use
varpool_ctor_useable_for_folding_p.
* lto.c (lto_read_in_decl_state): Update sanity check.
@@ -1428,11 +1449,11 @@
2014-06-25 Martin Liska <mliska@suse.cz>
- * lto/lto-partition.c (add_references_to_partition): New IPA REF function
+ * lto-partition.c (add_references_to_partition): New IPA REF function
used.
(add_symbol_to_partition_1): Likewise.
(lto_balanced_map): Likewise.
- * lto/lto-symtab.c (lto_cgraph_replace_node): Likewise.
+ * lto-symtab.c (lto_cgraph_replace_node): Likewise.
2014-06-24 Jan Hubicka <hubicka@ucw.cz>
@@ -1553,7 +1574,7 @@
2014-04-14 Jan Hubicka <hubicka@ucw.cz>
- * lto/lto-symtab.c (lto_cgraph_replace_node): Don't re-merge
+ * lto-symtab.c (lto_cgraph_replace_node): Don't re-merge
tp_first_run.
2014-03-19 Jan Hubicka <hubicka@ucw.cz>
@@ -1564,7 +1585,7 @@
2014-03-19 Richard Biener <rguenther@suse.de>
PR middle-end/60553
- * lto-tree.h (lang_tree_node): For types use TYPE_NEXT_VARIANT
+ * lto-tree.h (lang_tree_node): For types use TYPE_NEXT_VARIANT
instead of TREE_CHAIN as chain_next.
2014-03-19 Richard Biener <rguenther@suse.de>
@@ -1659,7 +1680,7 @@
2014-02-04 Jan Hubicka <hubicka@ucw.cz>
- * lto-partition.c (get_symbol_class): Only unforced DECL_ONE_ONLY
+ * lto-partition.c (get_symbol_class): Only unforced DECL_ONE_ONLY
needs duplicating, not generic COMDAT.
2014-02-04 Richard Biener <rguenther@suse.de>
@@ -1717,10 +1738,10 @@
2013-11-22 Andrew MacLeod <amacleod@redhat.com>
* lto.c: Add required include files from gimple.h.
- * lto-lang.c: Likewise
- * lto-object.c: Likewise
- * lto-partition.c: Likewise
- * lto-symtab.c: Likewise
+ * lto-lang.c: Likewise.
+ * lto-object.c: Likewise.
+ * lto-partition.c: Likewise.
+ * lto-symtab.c: Likewise.
2013-11-18 Trevor Saunders <tsaunders@mozilla.com>
@@ -1832,8 +1853,8 @@
2013-10-29 Andrew MacLeod <amacleod@redhat.com>
- * lto/lto-object.c: Add gimple.h to include list.
- * lto/lto-partition.c: Likewise.
+ * lto-object.c: Add gimple.h to include list.
+ * lto-partition.c: Likewise.
2013-10-18 Andrew MacLeod <amacleod@redhat.com>
@@ -1918,7 +1939,7 @@
2013-08-31 Jan Hubicka <jh@suse.cz>
- * lto.c (mentions_vars_p_field_decl, lto_fixup_prevailing_decls):
+ * lto.c (mentions_vars_p_field_decl, lto_fixup_prevailing_decls):
DECL_FIELD_OFFSET can contain an reference to variable.
2013-08-31 Jan Hubicka <jh@suse.cz>
@@ -1980,7 +2001,7 @@
2013-08-06 Jan Hubicka <jh@suse.cz>
Martin Liska <marxin.liska@gmail.com>
- * lto-partition.c (lto_balanced_map): Always base order on
+ * lto-partition.c (lto_balanced_map): Always base order on
source file order.
2013-08-06 Jan Hubicka <jh@suse.cz>
@@ -2216,7 +2237,7 @@
2012-10-08 Jan Hubicka <jh@suse.cz>
- * lto/lto.c (remember_with_vars): Also fixup INTEGER_CST.
+ * lto.c (remember_with_vars): Also fixup INTEGER_CST.
(fixup_integer_cst): New functoin.
(lto_ft_type): Fixup BASETYPE of methods and offsets.
@@ -2228,7 +2249,7 @@
2012-10-06 Jan Hubicka <jh@suse.cz>
- PR lto/54790
+ PR lto/54790
* lto.c (resolution_map): New static var.
(register_resolution): New function.
(lto_register_var_decl_in_symtab): Use it.
@@ -2241,7 +2262,7 @@
2012-09-19 Dehao Chen <dehao@google.com>
- * lto/lto.c (lto_fixup_prevailing_decls): Remove tree.exp.block field.
+ * lto.c (lto_fixup_prevailing_decls): Remove tree.exp.block field.
2012-09-19 Jan Hubicka <jh@suse.cz>
@@ -2372,10 +2393,10 @@
2012-06-18 Lawrence Crowl <crowl@google.com>
- * lto.c (do_whole_program_analysis): Rename use of TV_PHASE_CGRAPH to
+ * lto.c (do_whole_program_analysis): Rename use of TV_PHASE_CGRAPH to
TV_PHASE_OPT_GEN. Use new timevar TV_PHASE_STREAM_OUT around the call
to lto_wpa_write_files.
- (lto_main): Rename use of TV_PHASE_CGRAPH to TV_PHASE_OPT_GEN. Move
+ (lto_main): Rename use of TV_PHASE_CGRAPH to TV_PHASE_OPT_GEN. Move
start of TV_PHASE_OPT_GEN to include call to materialize_cgraph. Use
TV_PHASE_SETUP for the call to lto_init. Use new timevar
TV_PHASE_STREAM_IN around the call to read_cgraph_and_symbols.
@@ -2619,7 +2640,6 @@
(promote_fn): Likewise.
(lto_promote_cross_file_statics): Update comment.
-
2011-06-07 Diego Novillo <dnovillo@google.com>
* lto.c (uniquify_nodes): Move code to register decls to
@@ -2803,7 +2823,7 @@
2011-03-25 Jeff Law <law@redhat.com>
- * lto/lto-lang.c (def_fn_type): Add missing va_end.
+ * lto-lang.c (def_fn_type): Add missing va_end.
2011-03-21 Kai Tietz <ktietz@redhat.com>
@@ -2971,7 +2991,7 @@
2010-10-05 Jan Hubicka <jh@suse.cz>
- * lto.c: Include params.h.
+ * lto.c: Include params.h.
(add_cgraph_node_to_partition, add_varpool_node_to_partition): Do
refcounting in aux field.
(undo_partition, partition_cgraph_node_p, partition_varpool_node_p):
@@ -3025,7 +3045,7 @@
2010-09-16 Jan Hubicka <jh@suse.cz>
* lto.c (lto_materialize_function): Do not tamper with STATIC and
- EXTERNAL flags.
+ EXTERNAL flags.
2010-09-15 Laurynas Biveinis <laurynas.biveinis@gmail.com>
@@ -3152,7 +3172,7 @@
2010-06-09 Kai Tietz <kai.tietz@onevision.com>
- * lto.c (lto_resolution_read): Pre-initialize local variable r.
+ * lto.c (lto_resolution_read): Pre-initialize local variable r.
* lto-coff.c (coff_write_object_file): Add braces to if.
2010-06-08 Laurynas Biveinis <laurynas.biveinis@gmail.com>
@@ -3306,7 +3326,6 @@
'long long unsigned int' for x64-windows.
(lto_init): Likewise.
-
2010-05-07 Steven Bosscher <steven@gcc.gnu.org>
* lto.h (struct lto_file_struct): Document offset member.
@@ -3358,12 +3377,12 @@
2010-04-28 Jan Hubicka <jh@suse.cz>
- * lto/lto.c (lto_read_in_decl_state): Use GGC.
+ * lto.c (lto_read_in_decl_state): Use GGC.
(lto_wpa_write_files): Announce what we are writting.
(all_file_decl_data): New.
(read_cgraph_and_symbols): Use GGC; correct timevars.
(do_whole_program_analysis): Collect.
- * lto/Make-lang.in (lto.o): Fix dependency.
+ * Make-lang.in (lto.o): Fix dependency.
* Makefile.in (GTFILES): Add lto-streamer.h.
* varpool.c (varpool_analyze_pending_decls): Use TV_VARPOOL.
(varpool_assemble_pending_decls): Use VAROUT.
@@ -3484,7 +3503,7 @@
* lto.c (O_BINARY): Define.
(lto_read_section_data): Open file in binary mode.
* lto-elf.c (O_BINARY): Define.
- (lto_elf_file_open): Open file in binary mode.
+ (lto_elf_file_open): Open file in binary mode.
2010-01-08 Richard Guenther <rguenther@suse.de>
@@ -4044,7 +4063,7 @@
2009-01-29 Ramana Radhakrishnan <ramana.r@gmail.com>
- * Make-lang.in (LTO_EXE): Link with all
+ * Make-lang.in (LTO_EXE): Link with all
BACKENDLIBS and not only GMPLIBS
2009-01-28 H.J. Lu <hongjiu.lu@intel.com>
@@ -4168,17 +4187,17 @@
2008-11-09 Diego Novillo <dnovillo@google.com>
- * lto/lto.c (lto_fixup_tree): Change error message locus
+ * lto.c (lto_fixup_tree): Change error message locus
information to include location of mismatching
declaration.
Use TREE_NO_WARNING to avoid repeated messages.
(lto_main): If lto_fixup_decls emitted any errors, exit.
- * lto/lto-lang.c: Don't include libfuncs.h and except.h
+ * lto-lang.c: Don't include libfuncs.h and except.h
(lto_init_options): Don't enable exceptions by default.
(lto_eh_runtime_type): Move to lto-function-in.c
(lto_init_eh): Likewise.
(lto_init): Don't call lto_init_eh.
- * lto/Make-lang.in (lto-lang.o): Remove dependency on
+ * Make-lang.in (lto-lang.o): Remove dependency on
libfuncs.h and except.h.
2008-10-30 Diego Novillo <dnovillo@google.com>
@@ -4211,16 +4230,16 @@
input_cgraph): Move to lto-cgraph.c in gcc directory above.
(LANG_HOOKS_INPUT_CGRAPH): Remove use of macro.
-2008-10-24 Rafael Espindola <espindola@google.com>
+2008-10-24 Rafael Espindola <espindola@google.com>
* lto-function-in.c (get_resolution): Return LDPR_PREEMPTED_IR for
non prevailing weak symbols.
-2008-10-24 Rafael Espindola <espindola@google.com>
+2008-10-24 Rafael Espindola <espindola@google.com>
* lto-lang.c (input_cgraph_1): Iterate over nodes, not cgraph_nodes.
-2008-10-24 Rafael Espindola <espindola@google.com>
+2008-10-24 Rafael Espindola <espindola@google.com>
* lto-lang.c (input_node): Avoid casts from pointers to ints of
different types.
@@ -4244,7 +4263,7 @@
exceptions flag is given.
* lto-lang.c: (lto_init_options) Set default exceptions flag.
(lto_init_eh): Remove exceptions flag initialization.
- (lto_init): Only call lto_init_eh if exceptions flag is set.
+ (lto_init): Only call lto_init_eh if exceptions flag is set.
2008-10-21 Diego Novillo <dnovillo@google.com>
@@ -4309,7 +4328,7 @@
walking of nodes except for DECLs to be replaced. Pass an
lto_fixup_data_t object to tree-walker.
-2008-10-08 Rafael Espindola <espindola@google.com>
+2008-10-08 Rafael Espindola <espindola@google.com>
* lto-symtab.c (lto_symtab_set_resolution): New.
(lto_symtab_merge_decl): Use lto_symtab_set_resolution and
@@ -4318,18 +4337,18 @@
(lto_symtab_get_resolution): New.
* lto.c (lto_fixup_tree, lto_fixup_state): Remove unecessary checks.
-2008-10-06 Rafael Espindola <espindola@google.com>
+2008-10-06 Rafael Espindola <espindola@google.com>
* lto-lang.c: Include cgraph.h.
(input_overwrite_node, input_node, input_edge, input_cgraph_1,
input_cgraph): Moved from lto-cgraph.c.
(LANG_HOOKS_INPUT_CGRAPH): New.
-2008-10-03 Rafael Espindola <espindola@google.com>
+2008-10-03 Rafael Espindola <espindola@google.com>
* lto.c (lto_fixup_tree, lto_fixup_state): Fix the FIXME.
-2008-10-03 Rafael Espindola <espindola@google.com>
+2008-10-03 Rafael Espindola <espindola@google.com>
* lto-symtab.c (lto_symtab_overwrite_decl): Remove. Remove all calls.
(lto_symtab_merge_decl): Update LTO_IDENTIFIER_DECL the reflect the
@@ -4349,13 +4368,13 @@
* lto-lang.c (lto_post_options): Add validation and fixups for
-fltrans and -fwpa.
-2008-10-02 Rafael Espindola <espindola@google.com>
+2008-10-02 Rafael Espindola <espindola@google.com>
* lto-symtab.c (lto_symtab_merge_var, lto_symtab_merge_fn,
lto_symtab_merge_decl): Return void.
(lto_symtab_prevailing_decl): New.
-2008-09-30 Rafael Espindola <espindola@google.com>
+2008-09-30 Rafael Espindola <espindola@google.com>
* lto-symtab.c (lto_symtab_compatible): Remove the check for already
defined symbols.
@@ -4366,7 +4385,7 @@
(LTO_IDENTIFIER_RESOLUTION): Remove.
(LTO_DECL_RESOLUTION): New.
-2008-09-30 Rafael Espindola <espindola@google.com>
+2008-09-30 Rafael Espindola <espindola@google.com>
* lto.c (lto_read_decls): Use new input_tree signature.
@@ -4375,7 +4394,7 @@
* lto.c (lto_main): Call lto_fixup_nothrow_decls to fix up function
bodies affected by exception attribute merging of DECLs.
* lto-symtab.c (lto_symtab_merge_decl): Handle exception attribute
- merging.
+ merging.
2008-09-25 Rafael Espindola <espindola@google.com>
@@ -4394,7 +4413,7 @@
* lang.opt (fltrans-output-list=): New option.
* lto.c (lto_execute_ltrans): Output file names to ltrans_output_list.
-2008-09-25 Rafael Espindola <espindola@google.com>
+2008-09-25 Rafael Espindola <espindola@google.com>
* lto.c (lto_resolution_read): Initialize ret;
@@ -4413,7 +4432,7 @@
* Make-lang.in (LTRANS_DRIVER_INSTALL_NAME): New variable.
(lto.install-common): Add lto/ltrans-driver.
-2008-09-24 Rafael Espindola <espindola@google.com>
+2008-09-24 Rafael Espindola <espindola@google.com>
* Make-lang.in (LTO_OBJS): Add lto/common.o.
(lto/lto.o): Depend on lto/common.h.
@@ -4434,12 +4453,12 @@
Read resolution.
* lto.h (resolution_file_name): New.
-2008-09-23 Rafael Espindola <espindola@google.com>
+2008-09-23 Rafael Espindola <espindola@google.com>
* common.c: Update description.
* common.h: Update description.
-2008-09-23 Rafael Espindola <espindola@google.com>
+2008-09-23 Rafael Espindola <espindola@google.com>
* common.c: Moved from lto-plugin.
* common.h: Moved from lto-plugin.
@@ -4494,10 +4513,10 @@
* lto-lang.c: Include header file expr.h.
(COMPOUND_LITERAL_EXPR_DECL_STMT,
COMPOUND_LITERAL_EXPR_DECL): Copied from c-common.h.
- (emit_local_var): Copied from c-semantics.c.
+ (emit_local_var): Copied from c-semantics.c.
(lto_expand_expr, lto_staticp): Copied from c_expand_expr
and c_staticp in c-common.c.
- (LANG_HOOKS_EXPAND_EXPR,LANG_HOOKS_STATICP): Redefined.
+ (LANG_HOOKS_EXPAND_EXPR,LANG_HOOKS_STATICP): Redefined.
2008-09-08 Diego Novillo <dnovillo@google.com>
@@ -4511,7 +4530,7 @@
2008-08-04 Bill Maddox <maddox@google.com>
* lto-symtab.c (lto_symtab_merge_decl): Add comment.
-
+
2008-09-03 Doug Kwan <dougkwan@google.com>
lto.c (lto_add_all_inlinees): Reset FAILED_REASON of edges to
@@ -4567,7 +4586,7 @@
(lto_1_to_1_map, lto_add_all_inlinees, lto_wpa_write_files):
New functions.
(lto_main): Initialize bitmap obstack. Add code to handle WPA mode.
- * Make-lang.in (LTO_H): Replace filename lto-section-in.h with
+ * Make-lang.in (LTO_H): Replace filename lto-section-in.h with
variable LTO_SECTION_IN_H.
(lto/lto.o): Include gt-lto-lto-c.h ggc.h ,VEC_H, BITMAP_H,
pointer-set.h and IPA_PROP_H. Also replace filename lto-section-in.h
@@ -4583,12 +4602,12 @@
asserting.
(lto_post_options): Suppress debug info generation.
* Make-lang.in: Add dependency of lto-lang.o on tree-gimple.h.
-
+
2008-08-25 Bill Maddox <maddox@google.com>
* lto-symtab.c (lto_symtab_merge_decl): Remove a suspect
assertion and leave an explanatory comment in its place.
-
+
2008-08-21 Doug Kwan <dougkwan@google.com>
* lto.c (preload_common_nodes): Call lto_get_common_nodes to get a list
@@ -4618,21 +4637,21 @@
* lto.h (struct lto_file_struct): Remove GTY marker.
* config-lang.in: Remove lto/lto.h and lto/lto.c from
gtfiles.
-
+
2008-08-20 Bill Maddox <maddox@google.com>
* lto.c (lto_read_decls): Provide dummy argument to input_tree
to conform to its new signature.
* lto-symtab.c (lto_symtab_merge_decl): Do not invoke ggc_free
on discarded node here, now called in global_vector_fixup.
-
+
2008-08-09 Bill Maddox <maddox@google.com>
* lto.c (preload_common_nodes): Verify that fileptr_type_node
has not been set to a front-end-specific value.
-
+
2008-08-05 Doug Kwan <dougkwan@google.com>
-
+
* Make-lang.in (lto-symtab.o): Add missing dependencies to fix
build breakage.
@@ -4670,14 +4689,14 @@
* lto.c (lto_read_decls): Fix C++ compatibility warnings.
Make code const-correct.
(lto_file_read): Fix C++ compatibility warnings.
- (lto_read_section_data): Fix C++ compatibility warnings.
+ (lto_read_section_data): Fix C++ compatibility warnings.
(lto_get_section_data): Use CONST_CAST to avoid warning when
const pointer passed to free.
* lto-elf.c (lto_elf_build_section_table): Fix C++
compatibility warnings.
- (lto_elf_append_data): Fix C++ compatibility warnings. Use CONST_CAST
+ (lto_elf_append_data): Fix C++ compatibility warnings. Use CONST_CAST
to avoid warning assigning const pointer to d_buf field of Elf_Data.
- (lto_get_current_out_file): Fix C++ compatibility warnings.
+ (lto_get_current_out_file): Fix C++ compatibility warnings.
2008-07-11 Diego Novillo <dnovillo@google.com>
@@ -4851,7 +4870,7 @@
2008-06-07 Kenneth Zadeck <zadeck@naturalbridge.com>
Jan Hubicka <jh@suse.cz>
-
+
* lto.c (sys/mman.h, tree-pass.h): New includes.
(lto_materialize_constructors_and_inits,
lto_materialize_function): Keeps length of section.
@@ -4863,12 +4882,12 @@
(lto_read_section_data, get_section_data, free_section_data): New
functions.
(lto_main): Now calls pass manager, sets the hooks so that the ipa
- passes can get the section data.
-
+ passes can get the section data.
+
2008-05-27 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto.h (lto_read_decls): Made local.
- (lto_input_function_body, lto_input_constructors_and_inits,
+ (lto_input_function_body, lto_input_constructors_and_inits,
lto_input_cgraph): Declarations moved to lto-section-in.h.
* lto-section-in.c: Moved to .. .
* lto-cgraph-in.c: Ditto.
@@ -4879,7 +4898,7 @@
(LANG_HOOKS_INSERT_BLOCK): Removed.
* Make-lang.in (lto-cgraph-in.o, lto-function-in.o,
lto-section-in.o): Rules moved to lto/Makefile.in.
-
+
2008-05-16 Ollie Wild <aaw@google.com>
@@ -4960,7 +4979,7 @@
(lto_file_read): Made local and initialize dictionary so that
other lto sections can be read without reprocessing the elf file.
(lto_main): Read all functions after all files have been processed
- for their types, globals and cgraph.
+ for their types, globals and cgraph.
* Make-lang.in (lto.o, lto-cgraph-in.c, lto-section-in): Changed
dependencies.
* lto-elf.c (lto_elf_file): Removed strtab, symtab fields.
@@ -4970,7 +4989,7 @@
* lto.h (lto_info_fd_struct): Removed unmaterialized_fndecls.
(lto_file_read): Made local.
(lto_get_file_name, lto_elf_build_section_table,
- lto_input_cgraph):
+ lto_input_cgraph):
New function.
* lto-section-in.c (lto_read_section_data, lto_get_section_data):
New functions.
@@ -4985,7 +5004,6 @@
* lto_section_in.h (lto_section_slot): New structure.
(section_hash_table.lto_file_decl_data): New field.
-
2008-02-09 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto.c (lto_read_variable_formal_parameter_const): Remove code to
@@ -5001,10 +5019,10 @@
differently.
* Make-lang.in (LTO_H, lto/lto-function-in.o,
lto/lto-section-in.o): Update dependencies.
- * lto/lto-elf.c (lto_elf_map_optional_lto_section): Add
+ * lto-elf.c (lto_elf_map_optional_lto_section): Add
lto_section_type parameter.
(lto_elf_unmap_fn_body): Renamed to lto_elf_unmap_section.
- * lto.h (lto_file_vtable_struct): Removed two of the fields and
+ * lto.h (lto_file_vtable_struct): Removed two of the fields and
renamed the other two so that there is only one map function and
one unmap function and each takes a section type parameter.
(lto_read_function_body): Renamed to lto_input_function_body and
@@ -5022,7 +5040,7 @@
(lto_read_function_body, lto_input_constructors_and_inits):
Renamed to lto_input_function_body and takes file_data parameter.
* lto-section-in.h (lto_file_decl_data): New structure.
-
+
2008-01-28 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto-function-in.c (input_globals.c): Changed input type to
@@ -5031,8 +5049,8 @@
(input_function): Renumber all stmts after they are input.
(lto_read_body, lto_read_function_body, lto_read_var_init):
Changed to used new header format and enum section_type.
- *lto-lang.c (success): Removed.
-
+ *lto-lang.c (success): Removed.
+
2008-01-28 Nathan Froyd <froydnj@codesourcery.com>
* lto-elf.c (lto_elf_lookup_sym): Remove unused function.
@@ -5064,7 +5082,7 @@
* lto-section-in.c: New file with changes from above.
* Make-lang.in (lto-read.o): Renamed lto-function-in.c.
(lto-section-in.o): New rule.
-
+
2007-12-29 Nathan Froyd <froydnj@codesourcery.com>
* lto-read.c (input_expr_operand): Mark static and external
@@ -5187,7 +5205,7 @@
* lto.h (struct lto_str_fd_struct): New struct.
(struct lto_file_struct): Added new field DEBUG_STR
to hold the file descriptor for the debug string table.
-
+
2007-12-07 Bill Maddox <maddox@google.com>
* lto.c (lto_str_fd_init): New function.
@@ -5303,14 +5321,14 @@
2007-11-16 Kenneth Zadeck <zadeck@naturalbridge.com>
- * lto-read.c (input_expr_operand): Get types right
+ * lto-read.c (input_expr_operand): Get types right
for COMPLEX_CST.
2007-11-16 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto-read.c (make_new_block, input_cfg): Properly set
n_basic_blocks.
-
+
2007-11-16 Nathan Froyd <froydnj@codesourcery.com>
* lto.c (lto_read_array_type_DIE): Handle DIEs with DW_AT_GNU_vector
@@ -5330,7 +5348,7 @@
(input_expr_operand): Keeps track locally if current node needs a loc.
(input_local_var): Added code to handle DECL_INITIAL for
static local vars. Only set loc if necessary.
-
+
2007-11-15 Nathan Froyd <froydnj@codesourcery.com>
* lto.c (lto_read_subroutine_type_subprogram_DIE): Fix thinko'd
@@ -5355,14 +5373,14 @@
registered_builtin_fndecls.
2007-11-15 Kenneth Zadeck <zadeck@naturalbridge.com>
-
+
* lto-read.c (process_tree_flags, lto_static_init_local):
Renamed to ADD_CLASS_EXPR_FLAG. ADD_CLASS_DECL_FLAG New Macro.
(input_line_info, clear_line_info): Fixed new line number code.
(input_expr_operand): Added type to SWITCH_EXPR.
(lto_read_body): Properly initialized data_in.
Clear line info when leaving.
-
+
2007-11-13 Diego Novillo <dnovillo@google.com>
* lto.c (lto_read_variable_formal_parameter_constant_DIE):
@@ -5375,11 +5393,11 @@
2007-11-13 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto-read.c (input_type_ref): Renamed from get_type_ref.
- (input_expr_operand, input_local_var): Renamed get_type_ref to
+ (input_expr_operand, input_local_var): Renamed get_type_ref to
input_type_ref.
- (input_expr_operand): Get the types correct for
+ (input_expr_operand): Get the types correct for
vector-cst. Get SSA_NAME_DEF_STMT correct for return_exprs.
-
+
2007-11-13 Doug Kwan <dougkwan@google.com>
* lto-read.c (input_widest_uint_uleb128): New function.
@@ -5397,7 +5415,7 @@
DW_AT_static_link and DW_AT_specification. Return the
specification if present.
(lto_read_base_type_DIE): Handle DW_ATE_complex_float.
-
+
2007-11-13 Nathan Froyd <froydnj@codesourcery.com>
* lto-lang.c: Include target.h.
@@ -5413,7 +5431,7 @@
* lto-read.c (input_expr_operand): Added code to properly handle
index filed. Added new RANGE_EXPR case.
-
+
2007-11-11 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto-read.c (ADD_FUNC_FLAG): Deleted macro.
@@ -5474,14 +5492,14 @@
(struct lto_file_struct): Declare.
(lto_file_vtable): Use it instead of lto_file.
-2007-11-06 Alon Dayan <alond@il.ibm.com>
- Kenneth Zadeck <zadeck@naturalbridge.com>
+2007-11-06 Alon Dayan <alond@il.ibm.com>
+ Kenneth Zadeck <zadeck@naturalbridge.com>
* lto-read.c (process_flags, lto_static_init_local):
read flags of VAR_DECL and FUNCTION_DECL of size>1.
change global array num_flags_for_code to flags_length_for_code.
(set_line_info): Make decls work in USE_MAPPED_LOCATION mode.
-
+
2007-11-05 Nathan Froyd <froydnj@codesourcery.com>
* lto.c (lto_read_structure_union_class_type_DIE): Use proper record
@@ -5527,10 +5545,10 @@
* lto-read.c (data_in): Added type_decls and current_col fields.
(string_slot): New type to hold canonized file name.
- (hash_string_slot_node, eq_string_slot_node, canon_file_name,
+ (hash_string_slot_node, eq_string_slot_node, canon_file_name,
input_line_info, set_line_info, clear_line_info): New functions.
(file_name_hash_table): New hash table.
- (input_local_var, input_labels, input_local_vars_index,
+ (input_local_var, input_labels, input_local_vars_index,
input_local_var, input_local_vars, input_ssa_names): Reorganized parameters.
(input_uleb128): Changed type of byte var.
(input_expr_operand): Large number of changes to get line numbers
@@ -5544,7 +5562,6 @@
(lto_read_body): Added code to get TYPE_DECLS read and to change
parameters to the calls above that had their parms reorganized.
-
2007-10-29 Nathan Froyd <froydnj@codesourcery.com>
* lto.h (lto_resolve_typedecl_ref): Declare.
@@ -5566,7 +5583,7 @@
* lto-read.c (input_expr_operand): Give label_values the proper
context and provide switch statements with a default type.
-
+
2007-10-23 Nathan Froyd <froydnj@codesourcery.com>
* lto-read.c (lto_read_body): Move call to init_ssa_operands...
@@ -5600,7 +5617,7 @@
(input_ssa_names): Now calls input_tree_flags.
(lto_read_body): Now sets cfun.
(lto_read_function_body): Now sets current_function_pointer.
-
+
2007-10-19 Nathan Froyd <froydnj@codesourcery.com>
* lto.c (lto_read_variable_formal_parameter_constant_DIE): Check
@@ -5675,8 +5692,7 @@
(input_expr_operand): Make asm operands use input_tree_list.
(input_local_var): Now uses input_tree_list.
(lto_read_body): Change placement for setting context of debug_labels.
-
-
+
2007-10-16 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto-read.c (input_real): Output debugging in proper order.
@@ -5688,7 +5704,7 @@
written.
(dump_debug_stream): Also print char in hex.
(debug_out_fun): Fix signed unsigned mismatch.
-
+
2007-10-10 Nathan Froyd <froydnj@codesourcery.com>
* lto.c (lto_read_form): Handle DW_AT_MIPS_linkage_name and
@@ -5726,7 +5742,7 @@
2007-09-11 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto-read.c (input_expr_operand): Added type for STRING_CST.
-
+
2007-09-10 Nathan Froyd <froydnj@codesourcery.com>
* lto-read.c (lto_read): Set the type of the newly created CALL_EXPR.
@@ -5760,33 +5776,32 @@
* lto-read.c (fun_in): Renamed to data_in.
(input_expr_operand, input_local_var, input_string_internal,
- input_string, input_real, input_list, get_label_decl,
+ input_string, input_real, input_list, get_label_decl,
get_type_ref, input_expr_operand, input_globals, input_labels,
- input_local_vars_index, input_local_var, input_local_vars,
+ input_local_vars_index, input_local_var, input_local_vars,
input_cfg, input_phi, input_ssa_names, input_bb, ): Renamed fun_in to data_in.
(input_constructor): New function.
(lto_read_function_body): Renamed to lto_read_body and generalized
to handle both functions and constructors.
(lto_read_function_body, lto_read_var_init): New function.
-
-
+
2007-08-28 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto-read.c (input_expr_operand): Assert that there really is a
FUNCTION_DECL.
(input_globals): Removed checks on 0 section.
-
+
2007-08-28 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto-read.c (fun_in): Added local_decls_index and
- local_decls_index_d.
+ local_decls_index_d.
(input_expr_operand): Changed inputting of PARM_DECLs and VAR_DECLs.
(input_globals): Enabled code to handle FIELD_DECLs.
(input_local_vars_index, input_local_vars): New function.
(input_local_var): Changed to allow locals to be input randomly.
(lto_read_function_body): Added code to input the
local_decls_index and to free various structures.
-
+
2007-08-17 Jim Blandy <jimb@codesourcery.com>
* lto.c (lto_read_variable_formal_parameter_constant_DIE): Remove
@@ -5817,7 +5832,7 @@
* lto.c (lto_read_form): Complete attr_classes table.
(DWARF2_form_data): Doc fix.
-
+
2007-08-05 Mark Mitchell <mark@codesourcery.com>
* lto.h (lto_file_vtable): Remove read_var_init. Add map_var_init
@@ -5836,7 +5851,7 @@
* lto-read.c (lto_read_function_body): Moved declaration of fn
outside of ifdef.
-
+
2007-08-01 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto-read.c (input_uleb128, input_string_internal, input_real,
@@ -5845,7 +5860,7 @@
input_expr_operand, input_local_vars, input_cfg, input_phi,
input_ssa_names, input_bb, input_function): Added semicolons.
-
+
2007-07-31 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto-read.c (input_globals): Remove debugging.
@@ -5860,8 +5875,8 @@
(input_ssa_names): Initialize SSA_NAME_DEF_STMT to empty stmt.
(input_flags): New function.
* lto-lang.c (lto_init): Changed state of in_lto_p.
-
-
+
+
2007-07-24 Mark Mitchell <mark@codesourcery.com>
* lto-tree.h (lto_varargs_cookie): Remove.
@@ -5910,9 +5925,9 @@
(input_function): Now builds both the cfg and ssa_names table.
(lto_read_function_body): Processes new header fields to construct
streams for the ssa_names and cfg and their debugging.
- * lto/lto-lang.c (lto_init): Set in_lto_p.
-
-
+ * lto-lang.c (lto_init): Set in_lto_p.
+
+
2007-06-28 Mark Mitchell <mark@codesourcery.com>
* lto.h (lto_file_vtable): Add read_var_init.
@@ -5939,11 +5954,11 @@
* lto-read (make_new_block): Initialize the stmt_list.
(lto_static_init_local): Add debugging for missing codes.
-
+
2007-06-26 Mark Mitchell <mark@codesourcery.com>
* lto.c (lto_read_subroutine_type_subprogram_DIE): Handle
- unprototyped functions.
+ unprototyped functions.
2007-06-23 Mark Mitchell <mark@codesourcery.com>
@@ -5955,20 +5970,19 @@
* lto-symbtab.c: Build function types out of TREE_LISTs.
* lto-elf.c (<libelf>): Check for HAVE_LIBELF_H.
-
+
* Make-lang.in (LTO_OBJS): Depend on attribs.o.
-
+
2007-06-21 Kenneth Zadeck <zadeck@naturalbridge.com>
- * lto/lto-tree.h (lang_decl, lang_type, language_function): Added
+ * lto-tree.h (lang_decl, lang_type, language_function): Added
dummy since ggc does not like empty structs.
- * lto/lto-elf.c (libelf.h): Changed to libelf/libelf.h.
- * lto/lto-read.c (ADD_CLASS_FLAG, ADD_EXPR_FLAG): Changed
+ * lto-elf.c (libelf.h): Changed to libelf/libelf.h.
+ * lto-read.c (ADD_CLASS_FLAG, ADD_EXPR_FLAG): Changed
expr->common to expr->base.
(make_new_block): Moved stmt_list to proper place.
-
-2007-03-14 Robert Kennedy <jimbob@google.com>
+2007-03-14 Robert Kennedy <jimbob@google.com>
Eliminate use of lang_hooks.set_decl_assembler_name from LTO
* lto.c (lto_read_subroutine_type_subprogram_DIE) Get DECL
@@ -6081,7 +6095,7 @@
(lto_read_form): Change first argument to lto_info_fd *.
Add FORM_CONTEXT argument.
Handle DW_FORM_ref_addr.
- (lto_read_tag_DIE): Change first argument to lto_info_fd *.
+ (lto_read_tag_DIE): Change first argument to lto_info_fd *.
(LTO_BEGIN_READ_ATTRS_UNCHECKED): Save old context.
Swap contexts if necessary for form.
(LTO_BEGIN_READ_ATTRS): Cast fd to right type for
@@ -6104,7 +6118,7 @@
* lto.h (DWARF2_CompUnit): New structure.
(lto_info_fd): Ditto.
(lto_file): Change debug_info to be an lto_info_fd.
-
+
2006-06-25 Mark Mitchell <mark@codesourcery.com>
* lto.c (toplev.h): Include it.
@@ -6163,7 +6177,7 @@
(lto_file): Use new types.
(lto_file_close): Declare.
* lto-lang.c (lto_init): Always use unit-at-a-time mode.
-
+
2006-06-18 Mark Mitchell <mark@codesourcery.com>
* lto.h: New file.
@@ -6173,7 +6187,7 @@
(lto.h): Likewise.
(lto_init): New function.
(lto_write_globals): Remove.
- (LANG_HOOKS_WRITE_GLOBALS): Define to lhd_do_nothing.
+ (LANG_HOOKS_WRITE_GLOBALS): Define to lhd_do_nothing.
(LANG_HOOKS_INIT): Define.
(LANG_HOOKS_PARSE_FILE): Likewise.
* Make-lang.in (LTO_OBJS): Add lto.o and lto-elf.o.
diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in
index afcfc98..00701ae 100644
--- a/gcc/lto/Make-lang.in
+++ b/gcc/lto/Make-lang.in
@@ -49,7 +49,7 @@ lto.rest.encap:
lto.tags:
lto.install-common: installdirs
$(INSTALL_PROGRAM) $(LTO_DUMP_EXE) \
- $(DESTDIR)/$(bindir)/$(LTO_DUMP_INSTALL_NAME)$(exeext)
+ $(DESTDIR)$(bindir)/$(LTO_DUMP_INSTALL_NAME)$(exeext)
lto.install-man:
lto.install-info:
diff --git a/gcc/lto/lto-common.c b/gcc/lto/lto-common.c
index ef2d02a..9a17933 100644
--- a/gcc/lto/lto-common.c
+++ b/gcc/lto/lto-common.c
@@ -1228,7 +1228,7 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
compare_values (DECL_IS_NOVOPS);
compare_values (DECL_IS_RETURNS_TWICE);
compare_values (DECL_IS_MALLOC);
- compare_values (DECL_IS_OPERATOR_NEW);
+ compare_values (DECL_IS_OPERATOR_NEW_P);
compare_values (DECL_DECLARED_INLINE_P);
compare_values (DECL_STATIC_CHAIN);
compare_values (DECL_NO_INLINE_WARNING_P);
@@ -1241,7 +1241,7 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
compare_values (DECL_CXX_CONSTRUCTOR_P);
compare_values (DECL_CXX_DESTRUCTOR_P);
if (DECL_BUILT_IN_CLASS (t1) != NOT_BUILT_IN)
- compare_values (DECL_FUNCTION_CODE);
+ compare_values (DECL_UNCHECKED_FUNCTION_CODE);
}
if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index d573ea7..37fa572 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -556,7 +556,8 @@ lto_symtab_merge_p (tree prevailing, tree decl)
}
if (fndecl_built_in_p (prevailing)
&& (DECL_BUILT_IN_CLASS (prevailing) != DECL_BUILT_IN_CLASS (decl)
- || DECL_FUNCTION_CODE (prevailing) != DECL_FUNCTION_CODE (decl)))
+ || (DECL_UNCHECKED_FUNCTION_CODE (prevailing)
+ != DECL_UNCHECKED_FUNCTION_CODE (decl))))
{
if (dump_file)
fprintf (dump_file, "Not merging decls; "
diff --git a/gcc/machmode.h b/gcc/machmode.h
index 3a7cee8..005ec80 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -251,7 +251,8 @@ public:
ALWAYS_INLINE opt_mode (from_int m) : m_mode (machine_mode (m)) {}
machine_mode else_void () const;
- machine_mode else_blk () const;
+ machine_mode else_blk () const { return else_mode (BLKmode); }
+ machine_mode else_mode (machine_mode) const;
T require () const;
bool exists () const;
@@ -271,13 +272,13 @@ opt_mode<T>::else_void () const
return m_mode;
}
-/* If the T exists, return its enum value, otherwise return E_BLKmode. */
+/* If the T exists, return its enum value, otherwise return FALLBACK. */
template<typename T>
inline machine_mode
-opt_mode<T>::else_blk () const
+opt_mode<T>::else_mode (machine_mode fallback) const
{
- return m_mode == E_VOIDmode ? E_BLKmode : m_mode;
+ return m_mode == E_VOIDmode ? fallback : m_mode;
}
/* Assert that the object contains a T and return it. */
diff --git a/gcc/match.pd b/gcc/match.pd
index 4a7aa01..93dcef9 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -36,7 +36,8 @@ along with GCC; see the file COPYING3. If not see
integer_valued_real_p
integer_pow2p
uniform_integer_cst_p
- HONOR_NANS)
+ HONOR_NANS
+ uniform_vector_p)
/* Operator lists. */
(define_operator_list tcc_comparison
@@ -82,12 +83,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
plus minus
mult trunc_div trunc_mod rdiv
min max
- bit_and bit_ior bit_xor)
+ bit_and bit_ior bit_xor
+ lshift rshift)
(define_operator_list COND_BINARY
IFN_COND_ADD IFN_COND_SUB
IFN_COND_MUL IFN_COND_DIV IFN_COND_MOD IFN_COND_RDIV
IFN_COND_MIN IFN_COND_MAX
- IFN_COND_AND IFN_COND_IOR IFN_COND_XOR)
+ IFN_COND_AND IFN_COND_IOR IFN_COND_XOR
+ IFN_COND_SHL IFN_COND_SHR)
/* Same for ternary operations. */
(define_operator_list UNCOND_TERNARY
@@ -4937,37 +4940,109 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
the C/C++ front-ends by shorten_binary_op and shorten_compare. Long
term we want to move all that code out of the front-ends into here. */
-/* If we have a narrowing conversion of an arithmetic operation where
- both operands are widening conversions from the same type as the outer
- narrowing conversion. Then convert the innermost operands to a suitable
- unsigned type (to avoid introducing undefined behavior), perform the
- operation and convert the result to the desired type. */
-(for op (plus minus)
- (simplify
- (convert (op:s (convert@2 @0) (convert?@3 @1)))
- (if (INTEGRAL_TYPE_P (type)
- /* We check for type compatibility between @0 and @1 below,
- so there's no need to check that @1/@3 are integral types. */
- && INTEGRAL_TYPE_P (TREE_TYPE (@0))
- && INTEGRAL_TYPE_P (TREE_TYPE (@2))
- /* The precision of the type of each operand must match the
- precision of the mode of each operand, similarly for the
- result. */
- && type_has_mode_precision_p (TREE_TYPE (@0))
- && type_has_mode_precision_p (TREE_TYPE (@1))
- && type_has_mode_precision_p (type)
- /* The inner conversion must be a widening conversion. */
- && TYPE_PRECISION (TREE_TYPE (@2)) > TYPE_PRECISION (TREE_TYPE (@0))
- && types_match (@0, type)
- && (types_match (@0, @1)
- /* Or the second operand is const integer or converted const
- integer from valueize. */
- || TREE_CODE (@1) == INTEGER_CST))
- (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@0)))
- (op @0 (convert @1))
- (with { tree utype = unsigned_type_for (TREE_TYPE (@0)); }
- (convert (op (convert:utype @0)
- (convert:utype @1))))))))
+/* Convert (outertype)((innertype0)a+(innertype1)b)
+ into ((newtype)a+(newtype)b) where newtype
+ is the widest mode from all of these. */
+(for op (plus minus mult rdiv)
+ (simplify
+ (convert (op:s@0 (convert1?@3 @1) (convert2?@4 @2)))
+ /* If we have a narrowing conversion of an arithmetic operation where
+ both operands are widening conversions from the same type as the outer
+ narrowing conversion. Then convert the innermost operands to a
+ suitable unsigned type (to avoid introducing undefined behavior),
+ perform the operation and convert the result to the desired type. */
+ (if (INTEGRAL_TYPE_P (type)
+ && op != MULT_EXPR
+ && op != RDIV_EXPR
+ /* We check for type compatibility between @0 and @1 below,
+ so there's no need to check that @2/@4 are integral types. */
+ && INTEGRAL_TYPE_P (TREE_TYPE (@1))
+ && INTEGRAL_TYPE_P (TREE_TYPE (@3))
+ /* The precision of the type of each operand must match the
+ precision of the mode of each operand, similarly for the
+ result. */
+ && type_has_mode_precision_p (TREE_TYPE (@1))
+ && type_has_mode_precision_p (TREE_TYPE (@2))
+ && type_has_mode_precision_p (type)
+ /* The inner conversion must be a widening conversion. */
+ && TYPE_PRECISION (TREE_TYPE (@3)) > TYPE_PRECISION (TREE_TYPE (@1))
+ && types_match (@1, type)
+ && (types_match (@1, @2)
+ /* Or the second operand is const integer or converted const
+ integer from valueize. */
+ || TREE_CODE (@2) == INTEGER_CST))
+ (if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (@1)))
+ (op @1 (convert @2))
+ (with { tree utype = unsigned_type_for (TREE_TYPE (@1)); }
+ (convert (op (convert:utype @1)
+ (convert:utype @2)))))
+ (if (FLOAT_TYPE_P (type)
+ && DECIMAL_FLOAT_TYPE_P (TREE_TYPE (@0))
+ == DECIMAL_FLOAT_TYPE_P (type))
+ (with { tree arg0 = strip_float_extensions (@1);
+ tree arg1 = strip_float_extensions (@2);
+ tree itype = TREE_TYPE (@0);
+ tree ty1 = TREE_TYPE (arg0);
+ tree ty2 = TREE_TYPE (arg1);
+ enum tree_code code = TREE_CODE (itype); }
+ (if (FLOAT_TYPE_P (ty1)
+ && FLOAT_TYPE_P (ty2))
+ (with { tree newtype = type;
+ if (TYPE_MODE (ty1) == SDmode
+ || TYPE_MODE (ty2) == SDmode
+ || TYPE_MODE (type) == SDmode)
+ newtype = dfloat32_type_node;
+ if (TYPE_MODE (ty1) == DDmode
+ || TYPE_MODE (ty2) == DDmode
+ || TYPE_MODE (type) == DDmode)
+ newtype = dfloat64_type_node;
+ if (TYPE_MODE (ty1) == TDmode
+ || TYPE_MODE (ty2) == TDmode
+ || TYPE_MODE (type) == TDmode)
+ newtype = dfloat128_type_node; }
+ (if ((newtype == dfloat32_type_node
+ || newtype == dfloat64_type_node
+ || newtype == dfloat128_type_node)
+ && newtype == type
+ && types_match (newtype, type))
+ (op (convert:newtype @1) (convert:newtype @2))
+ (with { if (TYPE_PRECISION (ty1) > TYPE_PRECISION (newtype))
+ newtype = ty1;
+ if (TYPE_PRECISION (ty2) > TYPE_PRECISION (newtype))
+ newtype = ty2; }
+ /* Sometimes this transformation is safe (cannot
+ change results through affecting double rounding
+ cases) and sometimes it is not. If NEWTYPE is
+ wider than TYPE, e.g. (float)((long double)double
+ + (long double)double) converted to
+ (float)(double + double), the transformation is
+ unsafe regardless of the details of the types
+ involved; double rounding can arise if the result
+ of NEWTYPE arithmetic is a NEWTYPE value half way
+ between two representable TYPE values but the
+ exact value is sufficiently different (in the
+ right direction) for this difference to be
+ visible in ITYPE arithmetic. If NEWTYPE is the
+ same as TYPE, however, the transformation may be
+ safe depending on the types involved: it is safe
+ if the ITYPE has strictly more than twice as many
+ mantissa bits as TYPE, can represent infinities
+ and NaNs if the TYPE can, and has sufficient
+ exponent range for the product or ratio of two
+ values representable in the TYPE to be within the
+ range of normal values of ITYPE. */
+ (if (TYPE_PRECISION (newtype) < TYPE_PRECISION (itype)
+ && (flag_unsafe_math_optimizations
+ || (TYPE_PRECISION (newtype) == TYPE_PRECISION (type)
+ && real_can_shorten_arithmetic (TYPE_MODE (itype),
+ TYPE_MODE (type))
+ && !excess_precision_type (newtype)))
+ && !types_match (itype, newtype))
+ (convert:type (op (convert:newtype @1)
+ (convert:newtype @2)))
+ )))) )
+ ))
+)))
/* This is another case of narrowing, specifically when there's an outer
BIT_AND_EXPR which masks off bits outside the type of the innermost
@@ -5568,3 +5643,16 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
{ bitsize_int (at * tree_to_uhwi (TYPE_SIZE (TREE_TYPE (type)))); })
(if (changed)
(vec_perm { op0; } { op1; } { op2; }))))))))))
+
+/* VEC_PERM_EXPR (v, v, mask) -> v where v contains same element. */
+
+(match vec_same_elem_p
+ @0
+ (if (uniform_vector_p (@0))))
+
+(match vec_same_elem_p
+ (vec_duplicate @0))
+
+(simplify
+ (vec_perm vec_same_elem_p@0 @0 @1)
+ @0)
diff --git a/gcc/objc/ChangeLog b/gcc/objc/ChangeLog
index d001a50..2b8f889 100644
--- a/gcc/objc/ChangeLog
+++ b/gcc/objc/ChangeLog
@@ -5,23 +5,23 @@
2019-05-18 Iain Sandoe <iain@sandoe.co.uk>
- * objc/objc-act.h (OCTI_INSTANCE_TYPE, OCTI_INSTANCETYPE_NAME): New.
+ * objc-act.h (OCTI_INSTANCE_TYPE, OCTI_INSTANCETYPE_NAME): New.
(objc_global_trees): Add instance type and name.
(INSTANCE_TYPEDEF_NAME): New.
- * objc/objc-act.c (synth_module_prologue): Build decls for
+ * objc-act.c (synth_module_prologue): Build decls for
objc_instancetype_type and objc_instancetype_name.
2019-05-16 Martin Sebor <msebor@redhat.com>
- * objc-act.c (objc_begin_catch_clause): Quote keywords and options
- in diagnostics.
- (objc_build_throw_stmt): Same.
- (objc_finish_message_expr): Same.
- (get_super_receiver): Same.
- * objc-next-runtime-abi-01.c (objc_next_runtime_abi_01_init): Spell
- out "less than" in English./
- * objc-next-runtime-abi-02.c (objc_next_runtime_abi_02_init): Spell
- out "greater" in English.
+ * objc-act.c (objc_begin_catch_clause): Quote keywords and options
+ in diagnostics.
+ (objc_build_throw_stmt): Same.
+ (objc_finish_message_expr): Same.
+ (get_super_receiver): Same.
+ * objc-next-runtime-abi-01.c (objc_next_runtime_abi_01_init): Spell
+ out "less than" in English./
+ * objc-next-runtime-abi-02.c (objc_next_runtime_abi_02_init): Spell
+ out "greater" in English.
2019-05-10 Jakub Jelinek <jakub@redhat.com>
@@ -422,7 +422,7 @@
2013-11-22 Andrew MacLeod <amacleod@redhat.com>
- * objc/objc-act.c: Add required include files from gimple.h.
+ * objc-act.c: Add required include files from gimple.h.
2013-11-18 Richard Sandiford <rdsandiford@googlemail.com>
@@ -535,7 +535,7 @@
Include c-family/c-target.h.
(handle_next_class_ref): Rewrite to emit top-level asm statements.
(handle_next_impent): Likewise.
- * objc/Make-lang.in: Fix dependencies for objc-next-runtime-abi-01.o.
+ * Make-lang.in: Fix dependencies for objc-next-runtime-abi-01.o.
2012-05-31 Steven Bosscher <steven@gcc.gnu.org>
@@ -1199,7 +1199,7 @@
2010-12-18 Iain Sandoe <iains@gcc.gnu.org>
- * objc/objc-act.c (objc_eh_personality): Select personality name on
+ * objc-act.c (objc_eh_personality): Select personality name on
runtime.
(objc_init_exceptions): New.
(objc_begin_try_stmt): Use objc_init_exceptions.
@@ -1773,7 +1773,7 @@
Based on the CFString implementation in FSF apple/trunk branch.
- * objc/objc-act.c (objc_build_string_object): Handle CFStrings.
+ * objc-act.c (objc_build_string_object): Handle CFStrings.
2010-10-21 Nicola Pero <nicola.pero@meta-innovation.com>
@@ -1825,10 +1825,10 @@
to gcc_alloc_xxx calls in hash_init and hash_class_name_enter to
get it to compile in the current trunk.
- 2006-01-27 Fariborz Jahanian <fjahanian@apple.com>
+ 2006-01-27 Fariborz Jahanian <fjahanian@apple.com>
Radar 4345837
- * objc/objc-act.c (hash_class_name_enter): New.
+ * objc-act.c (hash_class_name_enter): New.
(hash_class_name_lookup): New.
(objc_declare_alias): Enter alias name into hash table.
(objc_declare_class): Enter class name into hash table.
@@ -1867,7 +1867,7 @@
2006-03-10 Fariborz Jahanian <fjahanian@apple.com>
Radar 4407151
- * objc/objc-act.c (objc_is_class_name): template parameter is not
+ * objc-act.c (objc_is_class_name): template parameter is not
an objective class name.
(objc_generate_cxx_cdtors): Check for the null
objc_implementation_context.
@@ -1879,7 +1879,7 @@
2005-11-08 Fariborz Jahanian <fjahanian@apple.com>
Radar 4330422
- * objc/objc-act.c (objc_non_volatilized_type): New
+ * objc-act.c (objc_non_volatilized_type): New
2005-10-07 Fariborz Jahanian <fjahanian@apple.com>
@@ -1895,7 +1895,7 @@
Merge from 'apple/trunk' branch on FSF servers.
- 2006-03-27 Fariborz Jahanian <fjahanian@apple.com>
+ 2006-03-27 Fariborz Jahanian <fjahanian@apple.com>
Radar 4133425
* objc-act.c (objc_diagnose_private_ivar): New.
@@ -1966,10 +1966,10 @@
merge from FSF apple 'trunk' branch.
- 2006-04-26 Fariborz Jahanian <fjahanian@apple.com>
+ 2006-04-26 Fariborz Jahanian <fjahanian@apple.com>
Radar 3803157 (method attributes)
- * objc/objc-act.h (METHOD_TYPE_ATTRIBUTES): New macro.
- * objc/objc-act.c (objc_decl_method_attributes): New.
+ * objc-act.h (METHOD_TYPE_ATTRIBUTES): New macro.
+ * objc-act.c (objc_decl_method_attributes): New.
(objc_add_method_declaration): Process method's attribute.
(objc_start_method_definition): Ditto.
(build_objc_method_call): Inject method attribute into
@@ -1997,7 +1997,7 @@
2010-10-07 Iain Sandoe <iains@gcc.gnu.org>
- * objc-act.c (objc_build_message_expr): Call mark_exp_read () to
+ * objc-act.c (objc_build_message_expr): Call mark_exp_read () to
signal that the receiver has been used.
2010-10-06 Nicola Pero <nicola.pero@meta-innovation.com>
@@ -2024,7 +2024,7 @@
Merge from 'apple/trunk' branch on FSF servers.
- 2006-04-12 Fariborz Jahanian <fjahanian@apple.com>
+ 2006-04-12 Fariborz Jahanian <fjahanian@apple.com>
Radar 4507230
* objc-act.c (objc_type_valid_for_messaging): New routine to check
@@ -2052,14 +2052,14 @@
2006-01-30 Fariborz Jahanian <fjahanian@apple.com>
Radar 4386773
- * objc/objc-act.c (objc_set_method_opt): New function.
+ * objc-act.c (objc_set_method_opt): New function.
(objc_start_protocol, objc_finish_interface): Reset
objc_method_optional_flag flag.
(objc_add_method_declaration): Pass on the new
flag to objc_add_method.
(objc_add_method): Add optional methods to new chain in
the protocol class.
- * objc/objc-act.h (CLASS_OPTIONAL_CLS_METHODS)
+ * objc-act.h (CLASS_OPTIONAL_CLS_METHODS)
(CLASS_OPTIONAL_NST_METHODS): New macros accessing a protocol
class's optional method chains.
@@ -2230,16 +2230,16 @@
Merge from 'apple/trunk' branch on FSF servers.
- 2006-03-09 Fariborz Jahanian <fjahanian@apple.com>
+ 2006-03-09 Fariborz Jahanian <fjahanian@apple.com>
Radar 4457381
- * objc/objc-act.c (objc_finish_message_expr): Look for message in
+ * objc-act.c (objc_finish_message_expr): Look for message in
@class's protocol list.
2006-02-07 Fariborz Jahanian <fjahanian@apple.com>
Radar 4219590
- * objc/objc-act.c (objc_start_method_definition): Initialize
+ * objc-act.c (objc_start_method_definition): Initialize
break/continue labels.
2005-08-22 Ziemowit Laski <zlaski@apple.com>
@@ -2259,7 +2259,7 @@
2010-09-10 Nicola Pero <nicola.pero@meta-innovation.com>
- * objc/objc-act.c (objc_begin_try_stmt): Generate an error if
+ * objc-act.c (objc_begin_try_stmt): Generate an error if
-fobjc-exceptions was not used. (objc_build_throw_stmt): Same
change.
@@ -2293,7 +2293,7 @@
to be extracted within the routine. Do not start new vars,
but finish the ones collcted during parsing.
(generate_shared_structures): Likewise.
- (finish_objc): Reorder code so that we finish variables before
+ (finish_objc): Reorder code so that we finish variables before
referencing them. Save the global data before calling meta-data
creation routines, and pass the current reference to the two
main routines. Only call generate_objc_image_info () for the
@@ -2471,7 +2471,7 @@
(objc_build_exc_ptr): Use __builtin_eh_pointer.
2009-09-13 Richard Guenther <rguenther@suse.de>
- Rafael Avila de Espindola <espindola@google.com>
+ Rafael Avila de Espindola <espindola@google.com>
* objc-act.c (objc_eh_runtime_type): Export.
(objc_init_exceptions): Remove. Move warning code ...
@@ -2652,8 +2652,8 @@
2009-04-21 Taras Glek <tglek@mozilla.com>
- * objc-act.c: Update GTY annotations to new syntax
- * objc-act.h: Likewise
+ * objc-act.c: Update GTY annotations to new syntax.
+ * objc-act.h: Likewise.
2009-04-21 Joseph Myers <joseph@codesourcery.com>
@@ -2728,7 +2728,7 @@
2008-09-17 Jan Hubicka <jh@suse.cz>
PR c++/18071
- * objc/objc-act.c (objc_finish_method_definition): Do not set
+ * objc-act.c (objc_finish_method_definition): Do not set
DECL_INLINE.
2008-09-01 Aldy Hernandez <aldyh@redhat.com>
@@ -2866,7 +2866,7 @@
2007-04-04 Stuart Hastings <stuart@apple.com>
PR 31281
- * objc/objc-act.c (next_sjlj_build_catch_list): Delete volatile from rethrow decl.
+ * objc-act.c (next_sjlj_build_catch_list): Delete volatile from rethrow decl.
2007-03-01 Brooks Moses <brooks.moses@codesourcery.com>
@@ -2874,7 +2874,7 @@
2007-02-18 Kazu Hirata <kazu@codesourcery.com>
- * objc/objc-act.c: Fix comment typos.
+ * objc-act.c: Fix comment typos.
2007-02-15 Sandra Loosemore <sandra@codesourcery.com>
Brooks Moses <brooks.moses@codesourcery.com>
@@ -2908,7 +2908,7 @@
* objc-act.c (objc_finish_file): Remove ifdef clause for OBJCPLUS and
content where we called cp_finish_file.
-2006-10-23 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
+2006-10-23 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
* objc-act.c (synth_module_prologue): Replace calls to
builtin_function with add_builtin_function.
@@ -2955,7 +2955,7 @@
PR objc/27240
* objc-act.c (objc_is_public): Return early on invalid type.
-2006-03-02 Fariborz Jahanian <fjahanian@apple.com>
+2006-03-02 Fariborz Jahanian <fjahanian@apple.com>
* objc-act.c (init_module_descriptor): Remove file name from
module descriptor.
@@ -2963,15 +2963,15 @@
2006-02-20 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
- * Make-lang.in (OBJC): Remove
- (OBJECTIVE-C): Remove
- (objective-c): Remove
- (.PHONY): Remove objective-c and ObjC
+ * Make-lang.in (OBJC): Remove.
+ (OBJECTIVE-C): Remove.
+ (objective-c): Remove.
+ (.PHONY): Remove objective-c and ObjC.
2005-12-14 Andrew Pinski <pinskia@physics.uc.edu>
PR objc/25360
- * objc/objc-act.c (encode_type): Encode Complex types as 'j' followed
+ * objc-act.c (encode_type): Encode Complex types as 'j' followed
by the inner type.
2005-12-12 Andrew Pinski <pinskia@physics.uc.edu>
@@ -3322,7 +3322,7 @@
2005-02-25 Joseph S. Myers <joseph@codesourcery.com>
* Make-lang.in (objc/objc-parse.o-warn, objc/objc-parse.o,
- objc/objc-parse.c, objc/objc-parse.y): Remove
+ objc/objc-parse.c, objc/objc-parse.y): Remove.
(OBJC_OBJS, objc.srcextra, objc.tags, objc.mostlyclean,
objc.distclean, objc.maintainer-clean): Update for new parser.
* config-lang.in (gtfiles): Update for new parser.
diff --git a/gcc/objcp/ChangeLog b/gcc/objcp/ChangeLog
index 02e2130..b54fda8 100644
--- a/gcc/objcp/ChangeLog
+++ b/gcc/objcp/ChangeLog
@@ -149,7 +149,7 @@
(objcp/objcp-act.o): Reordered dependencies. Added dependency on
objc-encoding.h.
(objcp/objc-encoding.o): New rule.
-
+
2011-04-15 Nicola Pero <nicola.pero@meta-innovation.com>
* objcp-decl.c (objcp_finish_struct): Use
@@ -169,7 +169,7 @@
* config-lang.in (gtfiles): Added cp/parser.h and reorganized list
so that it is more obvious that it is identical to the C++ one
with the addition of some files at the end.
-
+
2011-03-06 Joseph Myers <joseph@codesourcery.com>
* lang-specs.h: Match -save-temps* instead of -save-temps.
@@ -194,7 +194,7 @@
(LANG_HOOKS_EH_PERSONALITY): Removed.
(LANG_HOOKS_EH_RUNTIME_TYPE): Removed.
(objcp_eh_personality_decl): Removed.
-
+
2011-02-07 Mike Stump <mikestump@comcast.net>
* Make-lang.in (obj-c++.tags): Don't include *.y.
@@ -234,9 +234,9 @@
2010-10-14 Iain Sandoe <iains@gcc.gnu.org>
- merge from FSF apple 'trunk' branch.
+ merge from FSF apple 'trunk' branch.
2006 Fariborz Jahanian <fjahanian@apple.com>
-
+
Radars 4436866, 4505126, 4506903, 4517826
* objcp-lang.c (objcxx_init_ts): Update for property_decl.
@@ -268,7 +268,7 @@
2010-09-21 Nicola Pero <nicola.pero@meta-innovation.com>
- PR objc/25965
+ PR objc/25965
* objcp-decl.c (objcp_finish_struct): Call
objc_get_interface_ivars() and check for duplicate ivars.
@@ -402,13 +402,13 @@
2008-02-07 Andreas Tobler <andreast-list@fgznet.ch>
Douglas Gregor <doug.gregor@gmail.com>
-
+
PR bootstrap/35115
* objcp-decl.c (objcp_comptypes): Call cp_comptypes, not comptypes.
2008-02-07 Andreas Tobler <andreast-list@fgznet.ch>
Douglas Gregor <doug.gregor@gmail.com>
-
+
PR bootstrap/35115
* objcp-decl.c (objcp_comptypes): Call cp_comptypes, not comptypes.
@@ -429,7 +429,7 @@
* Make-lang.in: Add dummy lang.install-pdf target.
-2006-10-23 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
+2006-10-23 Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
* objcp-decl.h (objcp_builtin_function): Remove.
@@ -533,7 +533,7 @@
Mike Stump <mrs@apple.com>
Yet more Objective-C++...
-
+
* Make-lang.in (objcp/objcp-lang.o): Add tree-gimple.h
(objcp/objcp-decl.o): Likewise.
(objcp/objcp-act.o): Likewise.
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index d8756c0..444610b 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -162,6 +162,7 @@ static splay_tree all_contexts;
static int taskreg_nesting_level;
static int target_nesting_level;
static bitmap task_shared_vars;
+static bitmap global_nonaddressable_vars;
static vec<omp_context *> taskreg_contexts;
static void scan_omp (gimple_seq *, omp_context *);
@@ -426,7 +427,26 @@ use_pointer_for_field (tree decl, omp_context *shared_ctx)
/* Do not use copy-in/copy-out for variables that have their
address taken. */
- if (TREE_ADDRESSABLE (decl))
+ if (is_global_var (decl))
+ {
+ /* For file scope vars, track whether we've seen them as
+ non-addressable initially and in that case, keep the same
+ answer for the duration of the pass, even when they are made
+ addressable later on e.g. through reduction expansion. Global
+ variables which weren't addressable before the pass will not
+ have their privatized copies address taken. See PR91216. */
+ if (!TREE_ADDRESSABLE (decl))
+ {
+ if (!global_nonaddressable_vars)
+ global_nonaddressable_vars = BITMAP_ALLOC (NULL);
+ bitmap_set_bit (global_nonaddressable_vars, DECL_UID (decl));
+ }
+ else if (!global_nonaddressable_vars
+ || !bitmap_bit_p (global_nonaddressable_vars,
+ DECL_UID (decl)))
+ return true;
+ }
+ else if (TREE_ADDRESSABLE (decl))
return true;
/* lower_send_shared_vars only uses copy-in, but not copy-out
@@ -504,8 +524,10 @@ omp_copy_decl_2 (tree var, tree name, tree type, omp_context *ctx)
it's address. But we don't need to take address of privatizations
from that var. */
if (TREE_ADDRESSABLE (var)
- && task_shared_vars
- && bitmap_bit_p (task_shared_vars, DECL_UID (var)))
+ && ((task_shared_vars
+ && bitmap_bit_p (task_shared_vars, DECL_UID (var)))
+ || (global_nonaddressable_vars
+ && bitmap_bit_p (global_nonaddressable_vars, DECL_UID (var)))))
TREE_ADDRESSABLE (copy) = 0;
ctx->block_vars = copy;
@@ -1216,11 +1238,14 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
break;
case OMP_CLAUSE_USE_DEVICE_PTR:
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
decl = OMP_CLAUSE_DECL (c);
- if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
- install_var_field (decl, true, 3, ctx);
+ if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
+ && !omp_is_reference (decl))
+ || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE)
+ install_var_field (decl, true, 11, ctx);
else
- install_var_field (decl, false, 3, ctx);
+ install_var_field (decl, false, 11, ctx);
if (DECL_SIZE (decl)
&& TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)
{
@@ -1613,6 +1638,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_ORDER:
case OMP_CLAUSE_BIND:
case OMP_CLAUSE_USE_DEVICE_PTR:
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
case OMP_CLAUSE_NONTEMPORAL:
case OMP_CLAUSE_ASYNC:
case OMP_CLAUSE_WAIT:
@@ -5117,8 +5143,17 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
x = NULL;
do_private:
tree nx;
- nx = lang_hooks.decls.omp_clause_default_ctor
- (c, unshare_expr (new_var), x);
+ bool copy_ctor;
+ copy_ctor = false;
+ nx = unshare_expr (new_var);
+ if (is_simd
+ && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c))
+ copy_ctor = true;
+ if (copy_ctor)
+ nx = lang_hooks.decls.omp_clause_copy_ctor (c, nx, x);
+ else
+ nx = lang_hooks.decls.omp_clause_default_ctor (c, nx, x);
if (is_simd)
{
tree y = lang_hooks.decls.omp_clause_dtor (c, new_var);
@@ -5143,8 +5178,16 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
if (nx)
- x = lang_hooks.decls.omp_clause_default_ctor
- (c, unshare_expr (ivar), x);
+ {
+ tree iv = unshare_expr (ivar);
+ if (copy_ctor)
+ x = lang_hooks.decls.omp_clause_copy_ctor (c, iv,
+ x);
+ else
+ x = lang_hooks.decls.omp_clause_default_ctor (c,
+ iv,
+ x);
+ }
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE__CONDTEMP_)
{
x = build2 (MODIFY_EXPR, TREE_TYPE (ivar),
@@ -6447,9 +6490,9 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *body_p,
x = NULL_TREE;
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
- && OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV (c))
+ && OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)
+ && is_taskloop_ctx (ctx))
{
- gcc_checking_assert (is_taskloop_ctx (ctx));
tree ovar = maybe_lookup_decl_in_outer_ctx (var,
ctx->outer->outer);
if (is_global_var (ovar))
@@ -11426,6 +11469,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
break;
case OMP_CLAUSE_USE_DEVICE_PTR:
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
case OMP_CLAUSE_IS_DEVICE_PTR:
var = OMP_CLAUSE_DECL (c);
map_cnt++;
@@ -11442,7 +11486,9 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
SET_DECL_VALUE_EXPR (new_var, x);
DECL_HAS_VALUE_EXPR_P (new_var) = 1;
}
- else if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
+ else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
+ && !omp_is_reference (var))
+ || TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
{
tree new_var = lookup_decl (var, ctx);
tree type = build_pointer_type (TREE_TYPE (var));
@@ -11807,23 +11853,32 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
break;
case OMP_CLAUSE_USE_DEVICE_PTR:
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
case OMP_CLAUSE_IS_DEVICE_PTR:
ovar = OMP_CLAUSE_DECL (c);
var = lookup_decl_in_outer_ctx (ovar, ctx);
- x = build_sender_ref (ovar, ctx);
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
- tkind = GOMP_MAP_USE_DEVICE_PTR;
+ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IS_DEVICE_PTR)
+ {
+ tkind = GOMP_MAP_USE_DEVICE_PTR;
+ x = build_sender_ref ((splay_tree_key) &DECL_UID (ovar), ctx);
+ }
else
- tkind = GOMP_MAP_FIRSTPRIVATE_INT;
+ {
+ tkind = GOMP_MAP_FIRSTPRIVATE_INT;
+ x = build_sender_ref (ovar, ctx);
+ }
type = TREE_TYPE (ovar);
- if (TREE_CODE (type) == ARRAY_TYPE)
+ if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
+ && !omp_is_reference (ovar))
+ || TREE_CODE (type) == ARRAY_TYPE)
var = build_fold_addr_expr (var);
else
{
if (omp_is_reference (ovar))
{
type = TREE_TYPE (type);
- if (TREE_CODE (type) != ARRAY_TYPE)
+ if (TREE_CODE (type) != ARRAY_TYPE
+ && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_USE_DEVICE_ADDR)
var = build_simple_mem_ref (var);
var = fold_convert (TREE_TYPE (x), var);
}
@@ -11978,10 +12033,11 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
}
break;
case OMP_CLAUSE_USE_DEVICE_PTR:
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
case OMP_CLAUSE_IS_DEVICE_PTR:
var = OMP_CLAUSE_DECL (c);
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_PTR)
- x = build_sender_ref (var, ctx);
+ if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_IS_DEVICE_PTR)
+ x = build_sender_ref ((splay_tree_key) &DECL_UID (var), ctx);
else
x = build_receiver_ref (var, false, ctx);
if (is_variable_sized (var))
@@ -11995,7 +12051,9 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
gimple_seq_add_stmt (&new_body,
gimple_build_assign (new_var, x));
}
- else if (TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
+ else if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_USE_DEVICE_ADDR
+ && !omp_is_reference (var))
+ || TREE_CODE (TREE_TYPE (var)) == ARRAY_TYPE)
{
tree new_var = lookup_decl (var, ctx);
new_var = DECL_VALUE_EXPR (new_var);
@@ -12013,7 +12071,8 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx)
if (omp_is_reference (var))
{
type = TREE_TYPE (type);
- if (TREE_CODE (type) != ARRAY_TYPE)
+ if (TREE_CODE (type) != ARRAY_TYPE
+ && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_USE_DEVICE_ADDR)
{
tree v = create_tmp_var_raw (type, get_name (var));
gimple_add_tmp_var (v);
@@ -12730,6 +12789,7 @@ execute_lower_omp (void)
all_contexts = NULL;
}
BITMAP_FREE (task_shared_vars);
+ BITMAP_FREE (global_nonaddressable_vars);
/* If current function is a method, remove artificial dummy VAR_DECL created
for non-static data member privatization, they aren't needed for
diff --git a/gcc/omp-simd-clone.c b/gcc/omp-simd-clone.c
index caa8da3..a078033 100644
--- a/gcc/omp-simd-clone.c
+++ b/gcc/omp-simd-clone.c
@@ -461,8 +461,7 @@ simd_clone_create (struct cgraph_node *old_node)
if (new_node == NULL)
return new_node;
- DECL_BUILT_IN_CLASS (new_node->decl) = NOT_BUILT_IN;
- DECL_FUNCTION_CODE (new_node->decl) = (enum built_in_function) 0;
+ set_decl_built_in_function (new_node->decl, NOT_BUILT_IN, 0);
TREE_PUBLIC (new_node->decl) = TREE_PUBLIC (old_node->decl);
DECL_COMDAT (new_node->decl) = DECL_COMDAT (old_node->decl);
DECL_WEAK (new_node->decl) = DECL_WEAK (old_node->decl);
@@ -498,7 +497,6 @@ simd_clone_adjust_return_type (struct cgraph_node *node)
/* Adjust the function return type. */
if (orig_rettype == void_type_node)
return NULL_TREE;
- TREE_TYPE (fndecl) = build_distinct_type_copy (TREE_TYPE (fndecl));
t = TREE_TYPE (TREE_TYPE (fndecl));
if (INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
veclen = node->simdclone->vecsize_int;
@@ -724,11 +722,7 @@ simd_clone_adjust_argument_types (struct cgraph_node *node)
else
new_reversed = void_list_node;
}
-
- tree new_type = build_distinct_type_copy (TREE_TYPE (node->decl));
- TYPE_ARG_TYPES (new_type) = new_reversed;
- TREE_TYPE (node->decl) = new_type;
-
+ TYPE_ARG_TYPES (TREE_TYPE (node->decl)) = new_reversed;
adjustments.release ();
}
args.release ();
@@ -1164,6 +1158,7 @@ simd_clone_adjust (struct cgraph_node *node)
{
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
+ TREE_TYPE (node->decl) = build_distinct_type_copy (TREE_TYPE (node->decl));
targetm.simd_clone.adjust (node);
tree retval = simd_clone_adjust_return_type (node);
@@ -1737,6 +1732,8 @@ expand_simd_clones (struct cgraph_node *node)
simd_clone_adjust (n);
else
{
+ TREE_TYPE (n->decl)
+ = build_distinct_type_copy (TREE_TYPE (n->decl));
targetm.simd_clone.adjust (n);
simd_clone_adjust_return_type (n);
simd_clone_adjust_argument_types (n);
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 06bcaab..9e54dda 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -7212,7 +7212,7 @@ static bool
maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
class expand_operand *op)
{
- machine_mode mode, imode;
+ machine_mode mode, imode, tmode;
mode = op->mode;
switch (op->type)
@@ -7259,9 +7259,17 @@ maybe_legitimize_operand (enum insn_code icode, unsigned int opno,
gcc_assert (mode != VOIDmode);
imode = insn_data[(int) icode].operand[opno].mode;
+ tmode = (VECTOR_MODE_P (imode) && !VECTOR_MODE_P (mode)
+ ? GET_MODE_INNER (imode) : imode);
+ if (tmode != VOIDmode && tmode != mode)
+ {
+ op->value = convert_modes (tmode, mode, op->value, op->unsigned_p);
+ mode = tmode;
+ }
if (imode != VOIDmode && imode != mode)
{
- op->value = convert_modes (imode, mode, op->value, op->unsigned_p);
+ gcc_assert (VECTOR_MODE_P (imode) && !VECTOR_MODE_P (mode));
+ op->value = expand_vector_broadcast (imode, op->value);
mode = imode;
}
goto input;
diff --git a/gcc/optabs.def b/gcc/optabs.def
index 4ffd0f3..5283e67 100644
--- a/gcc/optabs.def
+++ b/gcc/optabs.def
@@ -230,6 +230,9 @@ OPTAB_D (cond_umod_optab, "cond_umod$a")
OPTAB_D (cond_and_optab, "cond_and$a")
OPTAB_D (cond_ior_optab, "cond_ior$a")
OPTAB_D (cond_xor_optab, "cond_xor$a")
+OPTAB_D (cond_ashl_optab, "cond_ashl$a")
+OPTAB_D (cond_ashr_optab, "cond_ashr$a")
+OPTAB_D (cond_lshr_optab, "cond_lshr$a")
OPTAB_D (cond_smin_optab, "cond_smin$a")
OPTAB_D (cond_smax_optab, "cond_smax$a")
OPTAB_D (cond_umin_optab, "cond_umin$a")
diff --git a/gcc/optabs.h b/gcc/optabs.h
index 0654107..897bb5d 100644
--- a/gcc/optabs.h
+++ b/gcc/optabs.h
@@ -129,7 +129,11 @@ create_convert_operand_to (class expand_operand *op, rtx value,
/* Make OP describe an input operand that should have the same value
as VALUE, after any mode conversion that the backend might request.
If VALUE is a CONST_INT, it should be treated as having mode MODE.
- UNSIGNED_P says whether VALUE is unsigned. */
+ UNSIGNED_P says whether VALUE is unsigned.
+
+ The conversion of VALUE can include a combination of numerical
+ conversion (as for convert_modes) and duplicating a scalar to fill
+ a vector (if VALUE is a scalar but the operand is a vector). */
static inline void
create_convert_operand_from (class expand_operand *op, rtx value,
diff --git a/gcc/opts-common.c b/gcc/opts-common.c
index e3f9c54..e2a315b 100644
--- a/gcc/opts-common.c
+++ b/gcc/opts-common.c
@@ -1526,9 +1526,15 @@ option_flag_var (int opt_index, struct gcc_options *opts)
or -1 if it isn't a simple on-off switch. */
int
-option_enabled (int opt_idx, void *opts)
+option_enabled (int opt_idx, unsigned lang_mask, void *opts)
{
const struct cl_option *option = &(cl_options[opt_idx]);
+
+ /* A language-specific option can only be considered enabled when it's
+ valid for the current language. */
+ if (option->flags & CL_LANG_ALL && !(option->flags | lang_mask))
+ return 0;
+
struct gcc_options *optsg = (struct gcc_options *) opts;
void *flag_var = option_flag_var (opt_idx, optsg);
@@ -1598,7 +1604,7 @@ get_option_state (struct gcc_options *opts, int option,
case CLVC_BIT_CLEAR:
case CLVC_BIT_SET:
- state->ch = option_enabled (option, opts);
+ state->ch = option_enabled (option, -1, opts);
state->data = &state->ch;
state->size = 1;
break;
diff --git a/gcc/opts.c b/gcc/opts.c
index 46a19a2..bb0d8b5 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "common/common-target.h"
#include "spellcheck.h"
#include "opt-suggestions.h"
+#include "diagnostic-color.h"
static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
@@ -262,6 +263,8 @@ add_comma_separated_to_vector (void **pvec, const char *arg)
else
*w++ = *r++;
}
+
+ *w = '\0';
if (*token_start != '\0')
v->safe_push (token_start);
@@ -466,7 +469,6 @@ static const struct default_options default_options_table[] =
{ OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_ftree_dce, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_ftree_dominator_opts, NULL, 1 },
- { OPT_LEVELS_1_PLUS, OPT_ftree_dse, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_ftree_sink, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_ftree_slsr, NULL, 1 },
@@ -477,14 +479,16 @@ static const struct default_options default_options_table[] =
#if DELAY_SLOTS
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fdelayed_branch, NULL, 1 },
#endif
+ { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fdse, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_invariants, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fssa_phiopt, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_bit_ccp, NULL, 1 },
- { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_sra, NULL, 1 },
+ { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_dse, NULL, 1 },
{ OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_pta, NULL, 1 },
+ { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_sra, NULL, 1 },
/* -O2 and -Os optimizations. */
{ OPT_LEVELS_2_PLUS, OPT_fcaller_saves, NULL, 1 },
@@ -1458,10 +1462,37 @@ print_filtered_help (unsigned int include_flags,
else
strcpy (new_help, "\t");
+ /* Set to print whether the option is enabled or disabled,
+ or, if it's an alias for another option, the name of
+ the aliased option. */
+ bool print_state = false;
+
if (flag_var != NULL
&& option->var_type != CLVC_DEFER)
{
- if (option->flags & CL_JOINED)
+ /* If OPTION is only available for a specific subset
+ of languages other than this one, mention them. */
+ bool avail_for_lang = true;
+ if (unsigned langset = option->flags & CL_LANG_ALL)
+ {
+ if (!(langset & lang_mask))
+ {
+ avail_for_lang = false;
+ strcat (new_help, _("[available in "));
+ for (unsigned i = 0, n = 0; (1U << i) < CL_LANG_ALL; ++i)
+ if (langset & (1U << i))
+ {
+ if (n++)
+ strcat (new_help, ", ");
+ strcat (new_help, lang_names[i]);
+ }
+ strcat (new_help, "]");
+ }
+ }
+ if (!avail_for_lang)
+ ; /* Print nothing else if the option is not available
+ in the current language. */
+ else if (option->flags & CL_JOINED)
{
if (option->var_type == CLVC_STRING)
{
@@ -1485,12 +1516,50 @@ print_filtered_help (unsigned int include_flags,
"%s", arg);
}
else
- sprintf (new_help + strlen (new_help),
- "%d", * (int *) flag_var);
+ {
+ if (option->cl_host_wide_int)
+ sprintf (new_help + strlen (new_help),
+ _("%llu bytes"), (unsigned long long)
+ *(unsigned HOST_WIDE_INT *) flag_var);
+ else
+ sprintf (new_help + strlen (new_help),
+ "%i", * (int *) flag_var);
+ }
+ }
+ else
+ print_state = true;
+ }
+ else
+ /* When there is no argument, print the option state only
+ if the option takes no argument. */
+ print_state = !(option->flags & CL_JOINED);
+
+ if (print_state)
+ {
+ if (option->alias_target < N_OPTS
+ && option->alias_target != OPT_SPECIAL_deprecated
+ && option->alias_target != OPT_SPECIAL_ignore
+ && option->alias_target != OPT_SPECIAL_input_file
+ && option->alias_target != OPT_SPECIAL_program_name
+ && option->alias_target != OPT_SPECIAL_unknown)
+ {
+ const struct cl_option *target
+ = &cl_options[option->alias_target];
+ sprintf (new_help + strlen (new_help), "%s%s",
+ target->opt_text,
+ option->alias_arg ? option->alias_arg : "");
}
+ else if (option->alias_target == OPT_SPECIAL_ignore)
+ strcat (new_help, ("[ignored]"));
else
- strcat (new_help, option_enabled (i, opts)
- ? _("[enabled]") : _("[disabled]"));
+ {
+ /* Print the state for an on/off option. */
+ int ena = option_enabled (i, lang_mask, opts);
+ if (ena > 0)
+ strcat (new_help, _("[enabled]"));
+ else if (ena == 0)
+ strcat (new_help, _("[disabled]"));
+ }
}
help = new_help;
@@ -2753,6 +2822,15 @@ common_handle_option (struct gcc_options *opts,
opts->x_flag_lto = value ? "" : NULL;
break;
+ case OPT_flto_:
+ if (strcmp (arg, "none") != 0
+ && strcmp (arg, "jobserver") != 0
+ && strcmp (arg, "auto") != 0
+ && atoi (arg) == 0)
+ error_at (loc,
+ "unrecognized argument to %<-flto=%> option: %qs", arg);
+ break;
+
case OPT_w:
dc->dc_inhibit_warnings = true;
break;
diff --git a/gcc/opts.h b/gcc/opts.h
index e5723a9..4722322 100644
--- a/gcc/opts.h
+++ b/gcc/opts.h
@@ -359,7 +359,8 @@ extern void decode_options (struct gcc_options *opts,
location_t loc,
diagnostic_context *dc,
void (*target_option_override_hook) (void));
-extern int option_enabled (int opt_idx, void *opts);
+extern int option_enabled (int opt_idx, unsigned lang_mask, void *opts);
+
extern bool get_option_state (struct gcc_options *, int,
struct cl_option_state *);
extern void set_option (struct gcc_options *opts,
diff --git a/gcc/params.def b/gcc/params.def
index 7d0dcae..13001a7 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -427,23 +427,31 @@ DEFPARAM(PARAM_SMS_LOOP_AVERAGE_COUNT_THRESHOLD,
DEFPARAM(HOT_BB_COUNT_FRACTION,
"hot-bb-count-fraction",
- "Select fraction of the maximal count of repetitions of basic block in program given basic "
- "block needs to have to be considered hot (used in non-LTO mode).",
+ "The denominator n of fraction 1/n of the maximal execution count of "
+ "a basic block in the entire program that a basic block needs to at "
+ "least have in order to be considered hot (used in non-LTO mode).",
10000, 0, 0)
+
DEFPARAM(HOT_BB_COUNT_WS_PERMILLE,
"hot-bb-count-ws-permille",
- "A basic block profile count is considered hot if it contributes to "
- "the given permillage of the entire profiled execution (used in LTO mode).",
+ "The number of most executed permilles of the profiled execution of "
+ "the entire program to which the execution count of a basic block "
+ "must be part of in order to be considered hot (used in LTO mode).",
990, 0, 1000)
+
DEFPARAM(HOT_BB_FREQUENCY_FRACTION,
"hot-bb-frequency-fraction",
- "Select fraction of the maximal frequency of executions of basic block in function given basic block needs to have to be considered hot.",
+ "The denominator n of fraction 1/n of the execution frequency of the "
+ "entry block of a function that a basic block of this function needs "
+ "to at least have in order to be considered hot.",
1000, 0, 0)
DEFPARAM(UNLIKELY_BB_COUNT_FRACTION,
"unlikely-bb-count-fraction",
- "The minimum fraction of profile runs a given basic block execution count must be not to be considered unlikely.",
- 20, 1, 10000)
+ "The denominator n of fraction 1/n of the number of profiled runs of "
+ "the entire program below which the execution count of a basic block "
+ "must be in order for the basic block to be considered unlikely.",
+ 20, 0, 0)
DEFPARAM (PARAM_ALIGN_THRESHOLD,
"align-threshold",
diff --git a/gcc/passes.c b/gcc/passes.c
index bd56004..f715c67 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -1646,24 +1646,39 @@ do_per_function (void (*callback) (function *, void *data), void *data)
}
}
-/* Because inlining might remove no-longer reachable nodes, we need to
- keep the array visible to garbage collector to avoid reading collected
- out nodes. */
-static int nnodes;
-static GTY ((length ("nnodes"))) cgraph_node **order;
-
-#define uid_hash_t hash_set<int_hash <int, 0, -1> >
-
/* Hook called when NODE is removed and therefore should be
excluded from order vector. DATA is a hash set with removed nodes. */
static void
remove_cgraph_node_from_order (cgraph_node *node, void *data)
{
- uid_hash_t *removed_nodes = (uid_hash_t *)data;
- removed_nodes->add (node->get_uid ());
+ hash_set<cgraph_node *> *removed_nodes = (hash_set<cgraph_node *> *)data;
+ removed_nodes->add (node);
+}
+
+/* Hook called when NODE is insert and therefore should be
+ excluded from removed_nodes. DATA is a hash set with removed nodes. */
+
+static void
+insert_cgraph_node_to_order (cgraph_node *node, void *data)
+{
+ hash_set<cgraph_node *> *removed_nodes = (hash_set<cgraph_node *> *)data;
+ removed_nodes->remove (node);
}
+/* Hook called when NODE is duplicated and therefore should be
+ excluded from removed_nodes. DATA is a hash set with removed nodes. */
+
+static void
+duplicate_cgraph_node_to_order (cgraph_node *node, cgraph_node *node2,
+ void *data)
+{
+ hash_set<cgraph_node *> *removed_nodes = (hash_set<cgraph_node *> *)data;
+ gcc_checking_assert (!removed_nodes->contains (node));
+ removed_nodes->remove (node2);
+}
+
+
/* If we are in IPA mode (i.e., current_function_decl is NULL), call
function CALLBACK for every function in the call graph. Otherwise,
call CALLBACK on the current function.
@@ -1677,26 +1692,30 @@ do_per_function_toporder (void (*callback) (function *, void *data), void *data)
callback (cfun, data);
else
{
- cgraph_node_hook_list *hook;
- uid_hash_t removed_nodes;
- gcc_assert (!order);
- order = ggc_vec_alloc<cgraph_node *> (symtab->cgraph_count);
+ hash_set<cgraph_node *> removed_nodes;
+ unsigned nnodes = symtab->cgraph_count;
+ cgraph_node **order = XNEWVEC (cgraph_node *, nnodes);
nnodes = ipa_reverse_postorder (order);
for (i = nnodes - 1; i >= 0; i--)
order[i]->process = 1;
- hook = symtab->add_cgraph_removal_hook (remove_cgraph_node_from_order,
- &removed_nodes);
+ cgraph_node_hook_list *removal_hook
+ = symtab->add_cgraph_removal_hook (remove_cgraph_node_from_order,
+ &removed_nodes);
+ cgraph_node_hook_list *insertion_hook
+ = symtab->add_cgraph_insertion_hook (insert_cgraph_node_to_order,
+ &removed_nodes);
+ cgraph_2node_hook_list *duplication_hook
+ = symtab->add_cgraph_duplication_hook (duplicate_cgraph_node_to_order,
+ &removed_nodes);
for (i = nnodes - 1; i >= 0; i--)
{
cgraph_node *node = order[i];
/* Function could be inlined and removed as unreachable. */
- if (node == NULL || removed_nodes.contains (node->get_uid ()))
+ if (node == NULL || removed_nodes.contains (node))
continue;
- /* Allow possibly removed nodes to be garbage collected. */
- order[i] = NULL;
node->process = 0;
if (node->has_gimple_body_p ())
{
@@ -1706,11 +1725,12 @@ do_per_function_toporder (void (*callback) (function *, void *data), void *data)
pop_cfun ();
}
}
- symtab->remove_cgraph_removal_hook (hook);
+ symtab->remove_cgraph_removal_hook (removal_hook);
+ symtab->remove_cgraph_insertion_hook (insertion_hook);
+ symtab->remove_cgraph_duplication_hook (duplication_hook);
+
+ free (order);
}
- ggc_free (order);
- order = NULL;
- nnodes = 0;
}
/* Helper function to perform function body dump. */
@@ -3046,5 +3066,3 @@ function_called_by_processed_nodes_p (void)
}
return e != NULL;
}
-
-#include "gt-passes.h"
diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog
index 5d34705..c904eeb 100644
--- a/gcc/po/ChangeLog
+++ b/gcc/po/ChangeLog
@@ -1,3 +1,7 @@
+2019-08-09 Joseph Myers <joseph@codesourcery.com>
+
+ * uk.po: Update.
+
2019-06-06 Joseph Myers <joseph@codesourcery.com>
* sv.po: Update.
@@ -1576,7 +1580,7 @@
2010-01-11 Joseph Myers <joseph@codesourcery.com>
Shujing Zhao <pearly.zhao@oracle.com>
-
+
PR translation/42467
* exgettext: Keep the text before tab character in the option help
string at *.opt file.
@@ -3626,7 +3630,7 @@ notice and this notice are preserved.
2010-01-11 Joseph Myers <joseph@codesourcery.com>
Shujing Zhao <pearly.zhao@oracle.com>
-
+
PR translation/42467
* exgettext: Keep the text before tab character in the option help
string at *.opt file.
diff --git a/gcc/po/uk.po b/gcc/po/uk.po
index 14cb43d..11729c6 100644
--- a/gcc/po/uk.po
+++ b/gcc/po/uk.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: gcc 9.1.0\n"
"Report-Msgid-Bugs-To: https://gcc.gnu.org/bugs/\n"
"POT-Creation-Date: 2019-05-02 20:28+0000\n"
-"PO-Revision-Date: 2019-05-07 20:56+0300\n"
+"PO-Revision-Date: 2019-07-04 20:43+0300\n"
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
"Language-Team: Ukrainian <trans-uk@lists.fedoraproject.org>\n"
"Language: uk\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"X-Bugs: Report translation errors to the Language-Team address.\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-"X-Generator: Lokalize 19.03.70\n"
+"X-Generator: Lokalize 19.07.70\n"
#: cfgrtl.c:2705
msgid "flow control insn inside a basic block"
@@ -1182,7 +1182,7 @@ msgstr ""
#: langhooks.c:380
msgid "At top level:"
-msgstr ""
+msgstr "На верхньому рівні:"
#: langhooks.c:396 cp/error.c:3458
#, c-format
@@ -1192,7 +1192,7 @@ msgstr "У функції-члені %qs"
#: langhooks.c:400 cp/error.c:3461
#, c-format
msgid "In function %qs"
-msgstr ""
+msgstr "У функції %qs"
#: langhooks.c:445 cp/error.c:3411
msgid " inlined from %qs at %r%s:%d:%d%R"
@@ -1209,7 +1209,7 @@ msgstr ""
#: lra-assigns.c:1841 reload1.c:2078
msgid "this is the insn:"
-msgstr ""
+msgstr "це інструкція:"
#: lra-constraints.c:2971
msgid "unable to generate reloads for impossible constraints:"
@@ -2308,7 +2308,7 @@ msgstr ""
#: params.def:938
#, no-c-format
msgid "The maximum ratio between array size and switch branches for a switch conversion to take place."
-msgstr ""
+msgstr "Максимальне значення відношення розміру масиву до кількості відгалужень перемикання для перетворення на перемикання."
#: params.def:946
#, no-c-format
@@ -3692,7 +3692,7 @@ msgstr ""
#: config/ia64/ia64.c:11242
msgid "invalid conversion to %<__fpreg%>"
-msgstr ""
+msgstr "некоректне перетворення до %<__fpreg%>"
#: config/ia64/ia64.c:11255 config/ia64/ia64.c:11266
msgid "invalid operation on %<__fpreg%>"
@@ -4732,7 +4732,7 @@ msgstr ""
#: cp/error.c:3456
msgid "In lambda function"
-msgstr ""
+msgstr "У лямбда-функції"
#: cp/error.c:3476
#, c-format
@@ -5483,7 +5483,7 @@ msgstr ""
#: fortran/trans.c:901
#, c-format
msgid "Attempting to allocate already allocated variable '%s'"
-msgstr ""
+msgstr "Спроба розмістити у пам'яті вже розміщену змінну «%s»"
#: fortran/trans.c:907
msgid "Attempting to allocate already allocated variable"
@@ -17671,7 +17671,7 @@ msgstr ""
#: cgraph.c:3252
#, gcc-internal-format
msgid "inlined_to pointer is set but no predecessors found"
-msgstr ""
+msgstr "встановлено вказівник inlined_to, але не виявлено попередників"
#: cgraph.c:3257
#, gcc-internal-format
@@ -18063,7 +18063,7 @@ msgstr ""
#: convert.c:557
#, gcc-internal-format
msgid "conversion to incomplete type"
-msgstr ""
+msgstr "перетворення до неповного типу"
#: convert.c:1032
#, gcc-internal-format
@@ -22091,7 +22091,7 @@ msgstr ""
#: symtab.c:1158
#, gcc-internal-format
msgid "implicit_section flag is set but section isn%'t"
-msgstr ""
+msgstr "встановлено прапорець implicit_section, але розділ не є"
#: symtab.c:1165
#, gcc-internal-format
@@ -22727,22 +22727,22 @@ msgstr ""
#: tree-cfg.c:3581
#, gcc-internal-format
msgid "invalid types in address space conversion"
-msgstr ""
+msgstr "некоректні типи у перетворенні простору адрес"
#: tree-cfg.c:3595
#, gcc-internal-format
msgid "invalid types in fixed-point conversion"
-msgstr ""
+msgstr "некоректні типи у перетворенні із фіксованою крапкою"
#: tree-cfg.c:3610
#, gcc-internal-format
msgid "invalid types in conversion to floating point"
-msgstr ""
+msgstr "некоректні типи у перетворенні до значення із рухомою крапкою"
#: tree-cfg.c:3625
#, gcc-internal-format
msgid "invalid types in conversion to integer"
-msgstr ""
+msgstr "некоректні типи у перетворенні до цілого значення"
#: tree-cfg.c:3665
#, gcc-internal-format
@@ -23052,7 +23052,7 @@ msgstr ""
#: tree-cfg.c:4791
#, gcc-internal-format
msgid "incorrect entry in label_to_block_map"
-msgstr ""
+msgstr "некоректний запис у label_to_block_map"
#: tree-cfg.c:4801
#, gcc-internal-format
@@ -25105,7 +25105,7 @@ msgstr ""
#: c-family/c-common.c:1530 c-family/c-common.c:1592
#, gcc-internal-format
msgid "conversion to %qT from %qT may change the sign of the result"
-msgstr ""
+msgstr "перетворення з %qT до %qT може змінити знак результату"
#: c-family/c-common.c:1778
#, gcc-internal-format
@@ -26971,7 +26971,7 @@ msgstr ""
#: c-family/c-warn.c:1196
#, gcc-internal-format
msgid "conversion to %qT from boolean expression"
-msgstr ""
+msgstr "перетворення до %qT з булевого виразу"
#: c-family/c-warn.c:1214 c-family/c-warn.c:1289
#, gcc-internal-format
@@ -27372,7 +27372,7 @@ msgstr ""
#: c-family/c-warn.c:2182
#, gcc-internal-format
msgid "comparison of integer expressions of different signedness: %qT and %qT"
-msgstr ""
+msgstr "порівняння цілочисельних виразів невід'ємного і різнознакового діапазонів: %qT і %qT"
#: c-family/c-warn.c:2235
#, gcc-internal-format
@@ -33484,7 +33484,7 @@ msgstr ""
#: c/c-convert.c:168
#, gcc-internal-format
msgid "conversion to non-scalar type requested"
-msgstr ""
+msgstr "запит на перетворення до нечислового типу"
#: c/c-decl.c:828
#, gcc-internal-format
@@ -33524,12 +33524,12 @@ msgstr ""
#: c/c-decl.c:1299
#, gcc-internal-format
msgid "unused variable %q+D"
-msgstr ""
+msgstr "невикористана змінна %q+D"
#: c/c-decl.c:1303 cp/decl.c:686
#, gcc-internal-format
msgid "variable %qD set but not used"
-msgstr ""
+msgstr "змінній %qD надано значення, але цю змінну ніде не використано"
#: c/c-decl.c:1308
#, gcc-internal-format
@@ -33999,7 +33999,7 @@ msgstr ""
#: c/c-decl.c:4920 c/c-decl.c:4935 c/c-typeck.c:7973
#, gcc-internal-format
msgid "variable-sized object may not be initialized"
-msgstr ""
+msgstr "об'єкт розмірності змінної може бути не ініціалізовано"
#: c/c-decl.c:4926
#, gcc-internal-format
@@ -34019,7 +34019,7 @@ msgstr ""
#: c/c-decl.c:5067
#, gcc-internal-format
msgid "%qD should be initialized"
-msgstr ""
+msgstr "%qD має бути ініціалізовано"
#: c/c-decl.c:5148
#, gcc-internal-format
@@ -34971,7 +34971,7 @@ msgstr ""
#: c/c-decl.c:9708 cp/decl.c:16244
#, gcc-internal-format
msgid "parameter %qD set but not used"
-msgstr ""
+msgstr "встановлено значення параметра %qD, але сам параметр ніде не використано"
#. If we get here, declarations have been used in a for loop without
#. the C99 for loop scope. This doesn't make much sense, so don't
@@ -37543,7 +37543,7 @@ msgstr ""
#: c/c-typeck.c:6933
#, gcc-internal-format
msgid "ISO C prohibits argument conversion to union type"
-msgstr ""
+msgstr "У ISO C заборонено перетворення аргументу до типу об'єднання"
#: c/c-typeck.c:7001
#, gcc-internal-format
@@ -37718,7 +37718,7 @@ msgstr ""
#: c/c-typeck.c:7418
#, gcc-internal-format
msgid "incompatible types when initializing type %qT using type %qT"
-msgstr ""
+msgstr "несумісні типи при ініціалізації типу %qT за допомогою %qT"
#: c/c-typeck.c:7428
#, gcc-internal-format
@@ -37779,7 +37779,7 @@ msgstr ""
#: c/c-typeck.c:8255 cp/decl.c:6477
#, gcc-internal-format
msgid "opaque vector types cannot be initialized"
-msgstr ""
+msgstr "непрозорі типи векторів не може бути ініціалізовано"
#: c/c-typeck.c:8475
#, gcc-internal-format
@@ -39980,7 +39980,7 @@ msgstr ""
#: cp/constexpr.c:837
#, gcc-internal-format
msgid "member %qD must be initialized by mem-initializer in %<constexpr%> constructor"
-msgstr ""
+msgstr "член %qD має бути ініціалізовано ініціалізатором mem у конструкторі %<constexpr%>"
#: cp/constexpr.c:878
#, gcc-internal-format
@@ -40711,7 +40711,7 @@ msgstr ""
#: cp/decl.c:672
#, gcc-internal-format
msgid "unused variable %qD"
-msgstr ""
+msgstr "невикористана змінна %qD"
#: cp/decl.c:681
#, gcc-internal-format
@@ -41497,7 +41497,7 @@ msgstr ""
#: cp/decl.c:6471
#, gcc-internal-format
msgid "in C++98 %qD must be initialized by constructor, not by %<{...}%>"
-msgstr ""
+msgstr "у C++98 %qD має бути ініціалізовано конструктором, а не за допомогою %<{...}%>"
#: cp/decl.c:6578
#, gcc-internal-format
@@ -44063,7 +44063,7 @@ msgstr ""
#: cp/init.c:780
#, gcc-internal-format
msgid "%qD should be initialized in the member initialization list"
-msgstr ""
+msgstr "%qD має бути ініціалізовано у списку ініціалізації членів"
#: cp/init.c:801
#, gcc-internal-format
@@ -44084,7 +44084,7 @@ msgstr ""
#: cp/method.c:1393 cp/method.c:1404
#, gcc-internal-format
msgid "%q#D should be initialized"
-msgstr ""
+msgstr "%q#D має бути ініціалізовано"
#: cp/init.c:945 cp/init.c:2466 cp/method.c:1401
#, gcc-internal-format
@@ -44094,12 +44094,12 @@ msgstr ""
#: cp/init.c:1127
#, gcc-internal-format
msgid "%qD will be initialized after"
-msgstr ""
+msgstr "%qD буде ініціалізовано після"
#: cp/init.c:1130
#, gcc-internal-format
msgid "base %qT will be initialized after"
-msgstr ""
+msgstr "базове %qT буде ініціалізовано після"
#: cp/init.c:1134
#, gcc-internal-format
@@ -44114,7 +44114,7 @@ msgstr ""
#: cp/init.c:1138
#, gcc-internal-format
msgid " when initialized here"
-msgstr ""
+msgstr " коли ініціалізовано тут"
#: cp/init.c:1155
#, gcc-internal-format
@@ -44179,7 +44179,7 @@ msgstr ""
#: cp/init.c:1798 cp/init.c:4515 cp/typeck2.c:1263
#, gcc-internal-format
msgid "array must be initialized with a brace-enclosed initializer"
-msgstr ""
+msgstr "масив має бути ініціалізовано за допомогою взятого у фігурні дужки ініціалізатора"
#: cp/init.c:2108 cp/semantics.c:3353
#, gcc-internal-format
@@ -45556,7 +45556,7 @@ msgstr ""
#: cp/parser.c:10593 cp/parser.c:10614 cp/parser.c:10785
#, gcc-internal-format
msgid "already captured %qD in lambda expression"
-msgstr ""
+msgstr "вже захоплене %qD у лямбда-виразі"
#: cp/parser.c:10608
#, gcc-internal-format
@@ -45596,7 +45596,7 @@ msgstr ""
#: cp/parser.c:10747
#, gcc-internal-format
msgid "too many %<...%> in lambda capture"
-msgstr ""
+msgstr "забагато %<...%> у лямбда-захопленні"
#: cp/parser.c:10758
#, gcc-internal-format
@@ -45918,12 +45918,12 @@ msgstr ""
#: cp/parser.c:15513
#, gcc-internal-format
msgid "invalid encoding prefix in literal operator"
-msgstr ""
+msgstr "некоректний префікс кодування у буквальному операторі"
#: cp/parser.c:15549
#, gcc-internal-format
msgid "expected operator"
-msgstr ""
+msgstr "мало бути вказано оператор"
#. Warn that we do not support `export'.
#: cp/parser.c:15595
@@ -45999,7 +45999,7 @@ msgstr ""
#: cp/parser.c:16540
#, gcc-internal-format
msgid "parse error in template argument list"
-msgstr ""
+msgstr "помилка обробки у списку аргументів шаблона"
#. The name does not name a template.
#: cp/parser.c:16608 cp/parser.c:16764 cp/parser.c:16973
@@ -46046,12 +46046,12 @@ msgstr ""
#: cp/parser.c:17294
#, gcc-internal-format
msgid "template specialization with C linkage"
-msgstr ""
+msgstr "спеціалізація шаблона із C-компонуванням"
#: cp/parser.c:17515
#, gcc-internal-format
msgid "expected type specifier"
-msgstr ""
+msgstr "мало бути вказано специфікатор типу"
#: cp/parser.c:17702
#, gcc-internal-format
@@ -48227,7 +48227,7 @@ msgstr ""
#: cp/pt.c:15137
#, gcc-internal-format
msgid "empty initializer in lambda init-capture"
-msgstr ""
+msgstr "порожній ініціалізатор у захопленні під час ініціалізації лямбди"
#: cp/pt.c:15212
#, gcc-internal-format
@@ -50044,7 +50044,7 @@ msgstr ""
#: cp/typeck.c:8697
#, gcc-internal-format
msgid "invalid conversion to type %qT from type %qT"
-msgstr ""
+msgstr "некоректне перетворення з типу %qT до типу %qT"
#: cp/typeck.c:9012
msgid "cannot convert %qH to %qI in default argument"
@@ -62796,7 +62796,7 @@ msgstr ""
#: fortran/trans-decl.c:5809
#, gcc-internal-format
msgid "Unused variable %qs declared at %L"
-msgstr ""
+msgstr "Невикористану змінну %qs оголошено у рядку %L"
#: fortran/trans-decl.c:5858
#, gcc-internal-format
diff --git a/gcc/predict.c b/gcc/predict.c
index 07f66aa..915f080 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -132,11 +132,15 @@ get_hot_bb_threshold ()
{
if (min_count == -1)
{
- gcov_type t = profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION);
- set_hot_bb_threshold (t);
+ const int hot_frac = PARAM_VALUE (HOT_BB_COUNT_FRACTION);
+ const gcov_type min_hot_count
+ = hot_frac
+ ? profile_info->sum_max / hot_frac
+ : (gcov_type)profile_count::max_count;
+ set_hot_bb_threshold (min_hot_count);
if (dump_file)
fprintf (dump_file, "Setting hotness threshold to %" PRId64 ".\n",
- min_count);
+ min_hot_count);
}
return min_count;
}
@@ -149,7 +153,7 @@ set_hot_bb_threshold (gcov_type min)
min_count = min;
}
-/* Return TRUE if frequency FREQ is considered to be hot. */
+/* Return TRUE if COUNT is considered to be hot in function FUN. */
bool
maybe_hot_count_p (struct function *fun, profile_count count)
@@ -173,8 +177,6 @@ maybe_hot_count_p (struct function *fun, profile_count count)
if (node->frequency == NODE_FREQUENCY_EXECUTED_ONCE
&& count < (ENTRY_BLOCK_PTR_FOR_FN (fun)->count.apply_scale (2, 3)))
return false;
- if (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION) == 0)
- return false;
if (count.apply_scale (PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION), 1)
< ENTRY_BLOCK_PTR_FOR_FN (fun)->count)
return false;
@@ -186,8 +188,8 @@ maybe_hot_count_p (struct function *fun, profile_count count)
return (count.to_gcov_type () >= get_hot_bb_threshold ());
}
-/* Return true in case BB can be CPU intensive and should be optimized
- for maximal performance. */
+/* Return true if basic block BB of function FUN can be CPU intensive
+ and should thus be optimized for maximum performance. */
bool
maybe_hot_bb_p (struct function *fun, const_basic_block bb)
@@ -196,8 +198,8 @@ maybe_hot_bb_p (struct function *fun, const_basic_block bb)
return maybe_hot_count_p (fun, bb->count);
}
-/* Return true in case BB can be CPU intensive and should be optimized
- for maximal performance. */
+/* Return true if edge E can be CPU intensive and should thus be optimized
+ for maximum performance. */
bool
maybe_hot_edge_p (edge e)
@@ -205,12 +207,11 @@ maybe_hot_edge_p (edge e)
return maybe_hot_count_p (cfun, e->count ());
}
-/* Return true if profile COUNT and FREQUENCY, or function FUN static
- node frequency reflects never being executed. */
+/* Return true if COUNT is considered to be never executed in function FUN
+ or if function FUN is considered so in the static profile. */
static bool
-probably_never_executed (struct function *fun,
- profile_count count)
+probably_never_executed (struct function *fun, profile_count count)
{
gcc_checking_assert (fun);
if (count.ipa () == profile_count::zero ())
@@ -222,8 +223,8 @@ probably_never_executed (struct function *fun,
desirable. */
if (count.precise_p () && profile_status_for_fn (fun) == PROFILE_READ)
{
- int unlikely_count_fraction = PARAM_VALUE (UNLIKELY_BB_COUNT_FRACTION);
- if (count.apply_scale (unlikely_count_fraction, 1) >= profile_info->runs)
+ const int unlikely_frac = PARAM_VALUE (UNLIKELY_BB_COUNT_FRACTION);
+ if (count.apply_scale (unlikely_frac, 1) >= profile_info->runs)
return false;
return true;
}
@@ -234,8 +235,7 @@ probably_never_executed (struct function *fun,
return false;
}
-
-/* Return true in case BB is probably never executed. */
+/* Return true if basic block BB of function FUN is probably never executed. */
bool
probably_never_executed_bb_p (struct function *fun, const_basic_block bb)
@@ -243,8 +243,7 @@ probably_never_executed_bb_p (struct function *fun, const_basic_block bb)
return probably_never_executed (fun, bb->count);
}
-
-/* Return true if E is unlikely executed for obvious reasons. */
+/* Return true if edge E is unlikely executed for obvious reasons. */
static bool
unlikely_executed_edge_p (edge e)
@@ -254,7 +253,7 @@ unlikely_executed_edge_p (edge e)
|| (e->flags & (EDGE_EH | EDGE_FAKE));
}
-/* Return true in case edge E is probably never executed. */
+/* Return true if edge E of function FUN is probably never executed. */
bool
probably_never_executed_edge_p (struct function *fun, edge e)
@@ -264,7 +263,7 @@ probably_never_executed_edge_p (struct function *fun, edge e)
return probably_never_executed (fun, e->count ());
}
-/* Return true when current function should always be optimized for size. */
+/* Return true if function FUN should always be optimized for size. */
bool
optimize_function_for_size_p (struct function *fun)
@@ -275,7 +274,7 @@ optimize_function_for_size_p (struct function *fun)
return n && n->optimize_for_size_p ();
}
-/* Return true when current function should always be optimized for speed. */
+/* Return true if function FUN should always be optimized for speed. */
bool
optimize_function_for_speed_p (struct function *fun)
@@ -283,7 +282,7 @@ optimize_function_for_speed_p (struct function *fun)
return !optimize_function_for_size_p (fun);
}
-/* Return the optimization type that should be used for the function FUN. */
+/* Return the optimization type that should be used for function FUN. */
optimization_type
function_optimization_type (struct function *fun)
@@ -293,7 +292,7 @@ function_optimization_type (struct function *fun)
: OPTIMIZE_FOR_SIZE);
}
-/* Return TRUE when BB should be optimized for size. */
+/* Return TRUE if basic block BB should be optimized for size. */
bool
optimize_bb_for_size_p (const_basic_block bb)
@@ -302,7 +301,7 @@ optimize_bb_for_size_p (const_basic_block bb)
|| (bb && !maybe_hot_bb_p (cfun, bb)));
}
-/* Return TRUE when BB should be optimized for speed. */
+/* Return TRUE if basic block BB should be optimized for speed. */
bool
optimize_bb_for_speed_p (const_basic_block bb)
@@ -310,7 +309,7 @@ optimize_bb_for_speed_p (const_basic_block bb)
return !optimize_bb_for_size_p (bb);
}
-/* Return the optimization type that should be used for block BB. */
+/* Return the optimization type that should be used for basic block BB. */
optimization_type
bb_optimization_type (const_basic_block bb)
@@ -320,7 +319,7 @@ bb_optimization_type (const_basic_block bb)
: OPTIMIZE_FOR_SIZE);
}
-/* Return TRUE when BB should be optimized for size. */
+/* Return TRUE if edge E should be optimized for size. */
bool
optimize_edge_for_size_p (edge e)
@@ -328,7 +327,7 @@ optimize_edge_for_size_p (edge e)
return optimize_function_for_size_p (cfun) || !maybe_hot_edge_p (e);
}
-/* Return TRUE when BB should be optimized for speed. */
+/* Return TRUE if edge E should be optimized for speed. */
bool
optimize_edge_for_speed_p (edge e)
@@ -336,7 +335,7 @@ optimize_edge_for_speed_p (edge e)
return !optimize_edge_for_size_p (e);
}
-/* Return TRUE when BB should be optimized for size. */
+/* Return TRUE if the current function is optimized for size. */
bool
optimize_insn_for_size_p (void)
@@ -344,7 +343,7 @@ optimize_insn_for_size_p (void)
return optimize_function_for_size_p (cfun) || !crtl->maybe_hot_insn_p;
}
-/* Return TRUE when BB should be optimized for speed. */
+/* Return TRUE if the current function is optimized for speed. */
bool
optimize_insn_for_speed_p (void)
@@ -352,7 +351,7 @@ optimize_insn_for_speed_p (void)
return !optimize_insn_for_size_p ();
}
-/* Return TRUE when LOOP should be optimized for size. */
+/* Return TRUE if LOOP should be optimized for size. */
bool
optimize_loop_for_size_p (class loop *loop)
@@ -360,7 +359,7 @@ optimize_loop_for_size_p (class loop *loop)
return optimize_bb_for_size_p (loop->header);
}
-/* Return TRUE when LOOP should be optimized for speed. */
+/* Return TRUE if LOOP should be optimized for speed. */
bool
optimize_loop_for_speed_p (class loop *loop)
@@ -368,7 +367,7 @@ optimize_loop_for_speed_p (class loop *loop)
return optimize_bb_for_speed_p (loop->header);
}
-/* Return TRUE when LOOP nest should be optimized for speed. */
+/* Return TRUE if nest rooted at LOOP should be optimized for speed. */
bool
optimize_loop_nest_for_speed_p (class loop *loop)
@@ -396,7 +395,7 @@ optimize_loop_nest_for_speed_p (class loop *loop)
return false;
}
-/* Return TRUE when LOOP nest should be optimized for size. */
+/* Return TRUE if nest rooted at LOOP should be optimized for size. */
bool
optimize_loop_nest_for_size_p (class loop *loop)
@@ -404,7 +403,7 @@ optimize_loop_nest_for_size_p (class loop *loop)
return !optimize_loop_nest_for_speed_p (loop);
}
-/* Return true when edge E is likely to be well predictable by branch
+/* Return true if edge E is likely to be well predictable by branch
predictor. */
bool
@@ -2450,7 +2449,7 @@ expr_expected_value_1 (tree type, tree op0, enum tree_code code,
return NULL;
}
- if (DECL_IS_MALLOC (decl) || DECL_IS_OPERATOR_NEW (decl))
+ if (DECL_IS_MALLOC (decl) || DECL_IS_OPERATOR_NEW_P (decl))
{
if (predictor)
*predictor = PRED_MALLOC_NONNULL;
@@ -3532,8 +3531,8 @@ drop_profile (struct cgraph_node *node, profile_count call_count)
void
handle_missing_profiles (void)
{
+ const int unlikely_frac = PARAM_VALUE (UNLIKELY_BB_COUNT_FRACTION);
struct cgraph_node *node;
- int unlikely_count_fraction = PARAM_VALUE (UNLIKELY_BB_COUNT_FRACTION);
auto_vec<struct cgraph_node *, 64> worklist;
/* See if 0 count function has non-0 count callers. In this case we
@@ -3563,8 +3562,7 @@ handle_missing_profiles (void)
if (call_count > 0
&& fn && fn->cfg
- && (call_count.apply_scale (unlikely_count_fraction, 1)
- >= profile_info->runs))
+ && call_count.apply_scale (unlikely_frac, 1) >= profile_info->runs)
{
drop_profile (node, call_count);
worklist.safe_push (node);
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index debea2b..6dcbb2d 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -519,7 +519,11 @@ print_node (FILE *file, const char *prefix, tree node, int indent,
if (code == FUNCTION_DECL && fndecl_built_in_p (node))
{
if (DECL_BUILT_IN_CLASS (node) == BUILT_IN_MD)
- fprintf (file, " built-in: BUILT_IN_MD:%d", DECL_FUNCTION_CODE (node));
+ fprintf (file, " built-in: BUILT_IN_MD:%d",
+ DECL_MD_FUNCTION_CODE (node));
+ else if (DECL_BUILT_IN_CLASS (node) == BUILT_IN_FRONTEND)
+ fprintf (file, " built-in: BUILT_IN_FRONTEND:%d",
+ DECL_FE_FUNCTION_CODE (node));
else
fprintf (file, " built-in: %s:%s",
built_in_class_names[(int) DECL_BUILT_IN_CLASS (node)],
diff --git a/gcc/profile.c b/gcc/profile.c
index 441cb8e..6c8127a 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -743,6 +743,42 @@ compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum)
free_aux_for_blocks ();
}
+/* Sort the histogram value and count for TOPN and INDIR_CALL type. */
+
+static void
+sort_hist_values (histogram_value hist)
+{
+ /* counters[2] equal to -1 means that all counters are invalidated. */
+ if (hist->hvalue.counters[2] == -1)
+ return;
+
+ gcc_assert (hist->type == HIST_TYPE_TOPN_VALUES
+ || hist->type == HIST_TYPE_INDIR_CALL);
+
+ gcc_assert (hist->n_counters == GCOV_TOPN_VALUES_COUNTERS);
+
+ /* Hist value is organized as:
+ [total_executions, value1, counter1, ..., value4, counter4]
+ Use decrease bubble sort to rearrange it. The sort starts from <value1,
+ counter1> and compares counter first. If counter is same, compares the
+ value, exchange it if small to keep stable. */
+ for (unsigned i = 0; i < GCOV_TOPN_VALUES - 1; i++)
+ {
+ bool swapped = false;
+ for (unsigned j = 0; j < GCOV_TOPN_VALUES - 1 - i; j++)
+ {
+ gcov_type *p = &hist->hvalue.counters[2 * j + 1];
+ if (p[1] < p[3] || (p[1] == p[3] && p[0] < p[2]))
+ {
+ std::swap (p[0], p[2]);
+ std::swap (p[1], p[3]);
+ swapped = true;
+ }
+ }
+ if (!swapped)
+ break;
+ }
+}
/* Load value histograms values whose description is stored in VALUES array
from .gcda file.
@@ -808,6 +844,10 @@ compute_value_histograms (histogram_values values, unsigned cfg_checksum,
else
hist->hvalue.counters[j] = 0;
+ if (hist->type == HIST_TYPE_TOPN_VALUES
+ || hist->type == HIST_TYPE_INDIR_CALL)
+ sort_hist_values (hist);
+
/* Time profiler counter is not related to any statement,
so that we have to read the counter and set the value to
the corresponding call graph node. */
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 38ee356..70a308e 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -4225,13 +4225,8 @@ finish_spills (int global)
spill_reg_order[i] = -1;
EXECUTE_IF_SET_IN_REG_SET (&spilled_pseudos, FIRST_PSEUDO_REGISTER, i, rsi)
- if (! ira_conflicts_p || reg_renumber[i] >= 0)
+ if (reg_renumber[i] >= 0)
{
- /* Record the current hard register the pseudo is allocated to
- in pseudo_previous_regs so we avoid reallocating it to the
- same hard reg in a later pass. */
- gcc_assert (reg_renumber[i] >= 0);
-
SET_HARD_REG_BIT (pseudo_previous_regs[i], reg_renumber[i]);
/* Mark it as no longer having a hard register home. */
reg_renumber[i] = -1;
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 039ab05..efb9b3c 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3481,6 +3481,7 @@ extern void replace_label (rtx *, rtx, rtx, bool);
extern void replace_label_in_insn (rtx_insn *, rtx_insn *, rtx_insn *, bool);
extern bool rtx_referenced_p (const_rtx, const_rtx);
extern bool tablejump_p (const rtx_insn *, rtx_insn **, rtx_jump_table_data **);
+extern rtx tablejump_casesi_pattern (const rtx_insn *insn);
extern int computed_jump_p (const rtx_insn *);
extern bool tls_referenced_p (const_rtx);
extern bool contains_mem_rtx_p (rtx x);
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 268a387..3c5a64e 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -3272,6 +3272,23 @@ tablejump_p (const rtx_insn *insn, rtx_insn **labelp,
return true;
}
+/* For INSN known to satisfy tablejump_p, determine if it actually is a
+ CASESI. Return the insn pattern if so, NULL_RTX otherwise. */
+
+rtx
+tablejump_casesi_pattern (const rtx_insn *insn)
+{
+ rtx tmp;
+
+ if ((tmp = single_set (insn)) != NULL
+ && SET_DEST (tmp) == pc_rtx
+ && GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE
+ && GET_CODE (XEXP (SET_SRC (tmp), 2)) == LABEL_REF)
+ return tmp;
+
+ return NULL_RTX;
+}
+
/* A subroutine of computed_jump_p, return 1 if X contains a REG or MEM or
constant that is not in the constant pool and not in the condition
of an IF_THEN_ELSE. */
diff --git a/gcc/rtx-vector-builder.h b/gcc/rtx-vector-builder.h
index d5950e2..08b55dd 100644
--- a/gcc/rtx-vector-builder.h
+++ b/gcc/rtx-vector-builder.h
@@ -24,10 +24,11 @@ along with GCC; see the file COPYING3. If not see
/* This class is used to build VECTOR_CSTs from a sequence of elements.
See vector_builder for more details. */
-class rtx_vector_builder : public vector_builder<rtx, rtx_vector_builder>
+class rtx_vector_builder : public vector_builder<rtx, machine_mode,
+ rtx_vector_builder>
{
- typedef vector_builder<rtx, rtx_vector_builder> parent;
- friend class vector_builder<rtx, rtx_vector_builder>;
+ typedef vector_builder<rtx, machine_mode, rtx_vector_builder> parent;
+ friend class vector_builder<rtx, machine_mode, rtx_vector_builder>;
public:
rtx_vector_builder () : m_mode (VOIDmode) {}
@@ -48,6 +49,15 @@ private:
bool can_elide_p (rtx) const { return true; }
void note_representative (rtx *, rtx) {}
+ static poly_uint64 shape_nelts (machine_mode mode)
+ { return GET_MODE_NUNITS (mode); }
+ static poly_uint64 nelts_of (const_rtx x)
+ { return CONST_VECTOR_NUNITS (x); }
+ static unsigned int npatterns_of (const_rtx x)
+ { return CONST_VECTOR_NPATTERNS (x); }
+ static unsigned int nelts_per_pattern_of (const_rtx x)
+ { return CONST_VECTOR_NELTS_PER_PATTERN (x); }
+
rtx find_cached_value ();
machine_mode m_mode;
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 4892c49..9359a3c 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "selftest.h"
#include "selftest-rtl.h"
+#include "rtx-vector-builder.h"
/* Simplification and canonicalization of RTL. */
@@ -1735,45 +1736,42 @@ simplify_const_unary_operation (enum rtx_code code, machine_mode mode,
}
if (CONST_SCALAR_INT_P (op) || CONST_DOUBLE_AS_FLOAT_P (op))
return gen_const_vec_duplicate (mode, op);
- unsigned int n_elts;
if (GET_CODE (op) == CONST_VECTOR
- && GET_MODE_NUNITS (mode).is_constant (&n_elts))
- {
- /* This must be constant if we're duplicating it to a constant
- number of elements. */
- unsigned int in_n_elts = CONST_VECTOR_NUNITS (op).to_constant ();
- gcc_assert (in_n_elts < n_elts);
- gcc_assert ((n_elts % in_n_elts) == 0);
- rtvec v = rtvec_alloc (n_elts);
- for (unsigned i = 0; i < n_elts; i++)
- RTVEC_ELT (v, i) = CONST_VECTOR_ELT (op, i % in_n_elts);
- return gen_rtx_CONST_VECTOR (mode, v);
+ && (CONST_VECTOR_DUPLICATE_P (op)
+ || CONST_VECTOR_NUNITS (op).is_constant ()))
+ {
+ unsigned int npatterns = (CONST_VECTOR_DUPLICATE_P (op)
+ ? CONST_VECTOR_NPATTERNS (op)
+ : CONST_VECTOR_NUNITS (op).to_constant ());
+ gcc_assert (multiple_p (GET_MODE_NUNITS (mode), npatterns));
+ rtx_vector_builder builder (mode, npatterns, 1);
+ for (unsigned i = 0; i < npatterns; i++)
+ builder.quick_push (CONST_VECTOR_ELT (op, i));
+ return builder.build ();
}
}
- if (VECTOR_MODE_P (mode) && GET_CODE (op) == CONST_VECTOR)
+ if (VECTOR_MODE_P (mode)
+ && GET_CODE (op) == CONST_VECTOR
+ && known_eq (GET_MODE_NUNITS (mode), CONST_VECTOR_NUNITS (op)))
{
- unsigned int n_elts;
- if (!CONST_VECTOR_NUNITS (op).is_constant (&n_elts))
- return NULL_RTX;
-
- machine_mode opmode = GET_MODE (op);
- gcc_assert (known_eq (GET_MODE_NUNITS (mode), n_elts));
- gcc_assert (known_eq (GET_MODE_NUNITS (opmode), n_elts));
+ gcc_assert (GET_MODE (op) == op_mode);
- rtvec v = rtvec_alloc (n_elts);
- unsigned int i;
+ rtx_vector_builder builder;
+ if (!builder.new_unary_operation (mode, op, false))
+ return 0;
- for (i = 0; i < n_elts; i++)
+ unsigned int count = builder.encoded_nelts ();
+ for (unsigned int i = 0; i < count; i++)
{
rtx x = simplify_unary_operation (code, GET_MODE_INNER (mode),
CONST_VECTOR_ELT (op, i),
- GET_MODE_INNER (opmode));
+ GET_MODE_INNER (op_mode));
if (!x || !valid_for_const_vector_p (mode, x))
return 0;
- RTVEC_ELT (v, i) = x;
+ builder.quick_push (x);
}
- return gen_rtx_CONST_VECTOR (mode, v);
+ return builder.build ();
}
/* The order of these tests is critical so that, for example, we don't
@@ -4059,6 +4057,27 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
return 0;
}
+/* Return true if binary operation OP distributes over addition in operand
+ OPNO, with the other operand being held constant. OPNO counts from 1. */
+
+static bool
+distributes_over_addition_p (rtx_code op, int opno)
+{
+ switch (op)
+ {
+ case PLUS:
+ case MINUS:
+ case MULT:
+ return true;
+
+ case ASHIFT:
+ return opno == 1;
+
+ default:
+ return false;
+ }
+}
+
rtx
simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
rtx op0, rtx op1)
@@ -4068,26 +4087,45 @@ simplify_const_binary_operation (enum rtx_code code, machine_mode mode,
&& GET_CODE (op0) == CONST_VECTOR
&& GET_CODE (op1) == CONST_VECTOR)
{
- unsigned int n_elts;
- if (!CONST_VECTOR_NUNITS (op0).is_constant (&n_elts))
- return NULL_RTX;
-
- gcc_assert (known_eq (n_elts, CONST_VECTOR_NUNITS (op1)));
- gcc_assert (known_eq (n_elts, GET_MODE_NUNITS (mode)));
- rtvec v = rtvec_alloc (n_elts);
- unsigned int i;
+ bool step_ok_p;
+ if (CONST_VECTOR_STEPPED_P (op0)
+ && CONST_VECTOR_STEPPED_P (op1))
+ /* We can operate directly on the encoding if:
+
+ a3 - a2 == a2 - a1 && b3 - b2 == b2 - b1
+ implies
+ (a3 op b3) - (a2 op b2) == (a2 op b2) - (a1 op b1)
+
+ Addition and subtraction are the supported operators
+ for which this is true. */
+ step_ok_p = (code == PLUS || code == MINUS);
+ else if (CONST_VECTOR_STEPPED_P (op0))
+ /* We can operate directly on stepped encodings if:
+
+ a3 - a2 == a2 - a1
+ implies:
+ (a3 op c) - (a2 op c) == (a2 op c) - (a1 op c)
+
+ which is true if (x -> x op c) distributes over addition. */
+ step_ok_p = distributes_over_addition_p (code, 1);
+ else
+ /* Similarly in reverse. */
+ step_ok_p = distributes_over_addition_p (code, 2);
+ rtx_vector_builder builder;
+ if (!builder.new_binary_operation (mode, op0, op1, step_ok_p))
+ return 0;
- for (i = 0; i < n_elts; i++)
+ unsigned int count = builder.encoded_nelts ();
+ for (unsigned int i = 0; i < count; i++)
{
rtx x = simplify_binary_operation (code, GET_MODE_INNER (mode),
CONST_VECTOR_ELT (op0, i),
CONST_VECTOR_ELT (op1, i));
if (!x || !valid_for_const_vector_p (mode, x))
return 0;
- RTVEC_ELT (v, i) = x;
+ builder.quick_push (x);
}
-
- return gen_rtx_CONST_VECTOR (mode, v);
+ return builder.build ();
}
if (VECTOR_MODE_P (mode)
@@ -6940,6 +6978,18 @@ test_vector_ops_duplicate (machine_mode mode, rtx scalar_reg)
&& mode_for_vector (inner_mode, 2).exists (&narrower_mode)
&& VECTOR_MODE_P (narrower_mode))
{
+ /* Test VEC_DUPLICATE of a vector. */
+ rtx_vector_builder nbuilder (narrower_mode, 2, 1);
+ nbuilder.quick_push (const0_rtx);
+ nbuilder.quick_push (const1_rtx);
+ rtx_vector_builder builder (mode, 2, 1);
+ builder.quick_push (const0_rtx);
+ builder.quick_push (const1_rtx);
+ ASSERT_RTX_EQ (builder.build (),
+ simplify_unary_operation (VEC_DUPLICATE, mode,
+ nbuilder.build (),
+ narrower_mode));
+
/* Test VEC_SELECT of a vector. */
rtx vec_par
= gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, const1_rtx, const0_rtx));
@@ -7012,6 +7062,58 @@ test_vector_ops_series (machine_mode mode, rtx scalar_reg)
ASSERT_RTX_EQ (series_0_m1,
simplify_binary_operation (VEC_SERIES, mode, const0_rtx,
constm1_rtx));
+
+ /* Test NEG on constant vector series. */
+ ASSERT_RTX_EQ (series_0_m1,
+ simplify_unary_operation (NEG, mode, series_0_1, mode));
+ ASSERT_RTX_EQ (series_0_1,
+ simplify_unary_operation (NEG, mode, series_0_m1, mode));
+
+ /* Test PLUS and MINUS on constant vector series. */
+ rtx scalar2 = gen_int_mode (2, inner_mode);
+ rtx scalar3 = gen_int_mode (3, inner_mode);
+ rtx series_1_1 = gen_const_vec_series (mode, const1_rtx, const1_rtx);
+ rtx series_0_2 = gen_const_vec_series (mode, const0_rtx, scalar2);
+ rtx series_1_3 = gen_const_vec_series (mode, const1_rtx, scalar3);
+ ASSERT_RTX_EQ (series_1_1,
+ simplify_binary_operation (PLUS, mode, series_0_1,
+ CONST1_RTX (mode)));
+ ASSERT_RTX_EQ (series_0_m1,
+ simplify_binary_operation (PLUS, mode, CONST0_RTX (mode),
+ series_0_m1));
+ ASSERT_RTX_EQ (series_1_3,
+ simplify_binary_operation (PLUS, mode, series_1_1,
+ series_0_2));
+ ASSERT_RTX_EQ (series_0_1,
+ simplify_binary_operation (MINUS, mode, series_1_1,
+ CONST1_RTX (mode)));
+ ASSERT_RTX_EQ (series_1_1,
+ simplify_binary_operation (MINUS, mode, CONST1_RTX (mode),
+ series_0_m1));
+ ASSERT_RTX_EQ (series_1_1,
+ simplify_binary_operation (MINUS, mode, series_1_3,
+ series_0_2));
+
+ /* Test MULT between constant vectors. */
+ rtx vec2 = gen_const_vec_duplicate (mode, scalar2);
+ rtx vec3 = gen_const_vec_duplicate (mode, scalar3);
+ rtx scalar9 = gen_int_mode (9, inner_mode);
+ rtx series_3_9 = gen_const_vec_series (mode, scalar3, scalar9);
+ ASSERT_RTX_EQ (series_0_2,
+ simplify_binary_operation (MULT, mode, series_0_1, vec2));
+ ASSERT_RTX_EQ (series_3_9,
+ simplify_binary_operation (MULT, mode, vec3, series_1_3));
+ if (!GET_MODE_NUNITS (mode).is_constant ())
+ ASSERT_FALSE (simplify_binary_operation (MULT, mode, series_0_1,
+ series_0_1));
+
+ /* Test ASHIFT between constant vectors. */
+ ASSERT_RTX_EQ (series_0_2,
+ simplify_binary_operation (ASHIFT, mode, series_0_1,
+ CONST1_RTX (mode)));
+ if (!GET_MODE_NUNITS (mode).is_constant ())
+ ASSERT_FALSE (simplify_binary_operation (ASHIFT, mode, CONST1_RTX (mode),
+ series_0_1));
}
/* Verify simplify_merge_mask works correctly. */
diff --git a/gcc/sort.cc b/gcc/sort.cc
index 3e9c032..73a9f7e 100644
--- a/gcc/sort.cc
+++ b/gcc/sort.cc
@@ -58,8 +58,25 @@ struct sort_ctx
size_t nlim; // limit for network sort
};
+/* Like sort_ctx, but for use with qsort_r-style comparators. Several
+ functions in this file are templates that work with either context type. */
+struct sort_r_ctx
+{
+ void *data;
+ sort_r_cmp_fn *cmp_;
+ char *out;
+ size_t n;
+ size_t size;
+ size_t nlim;
+ int cmp (const void *a, const void *b)
+ {
+ return cmp_ (a, b, data);
+ }
+};
+
/* Helper for netsort. Permute, possibly in-place, 2 or 3 elements,
placing E0 to C->OUT, E1 to C->OUT + C->SIZE, and so on. */
+template<typename sort_ctx>
static void
reorder23 (sort_ctx *c, char *e0, char *e1, char *e2)
{
@@ -90,6 +107,7 @@ do { \
}
/* Like reorder23, but permute 4 or 5 elements. */
+template<typename sort_ctx>
static void
reorder45 (sort_ctx *c, char *e0, char *e1, char *e2, char *e3, char *e4)
{
@@ -127,21 +145,23 @@ do { \
Return E0^E1 if E0 compares less than E1, zero otherwise.
This is noinline to avoid code growth and confine invocation
to a single call site, assisting indirect branch prediction. */
+template<typename sort_ctx>
noinline static intptr_t
-cmp1 (char *e0, char *e1, cmp_fn *cmp)
+cmp1 (char *e0, char *e1, sort_ctx *c)
{
intptr_t x = (intptr_t)e0 ^ (intptr_t)e1;
- return x & (cmp (e0, e1) >> 31);
+ return x & (c->cmp (e0, e1) >> 31);
}
/* Execute network sort on 2 to 5 elements from IN, placing them into C->OUT.
IN may be equal to C->OUT, in which case elements are sorted in place. */
+template<typename sort_ctx>
static void
netsort (char *in, sort_ctx *c)
{
#define CMP(e0, e1) \
do { \
- intptr_t x = cmp1 (e1, e0, c->cmp); \
+ intptr_t x = cmp1 (e1, e0, c); \
e0 = (char *)((intptr_t)e0 ^ x); \
e1 = (char *)((intptr_t)e1 ^ x); \
} while (0)
@@ -176,6 +196,7 @@ do { \
/* Execute merge sort on N elements from IN, placing them into OUT,
using TMP as temporary storage if IN is equal to OUT.
This is a stable sort if netsort is used only for 2 or 3 elements. */
+template<typename sort_ctx>
static void
mergesort (char *in, sort_ctx *c, size_t n, char *out, char *tmp)
{
@@ -217,6 +238,17 @@ do { \
memcpy (out, l, r - out);
}
+#if CHECKING_P
+/* Adapter for using two-argument comparators in functions expecting the
+ three-argument sort_r_cmp_fn type. */
+static int
+cmp2to3 (const void *a, const void *b, void *c)
+{
+ return ((cmp_fn *)c) (a, b);
+}
+#endif
+
+/* Replacement for C qsort. */
void
gcc_qsort (void *vbase, size_t n, size_t size, cmp_fn *cmp)
{
@@ -235,10 +267,30 @@ gcc_qsort (void *vbase, size_t n, size_t size, cmp_fn *cmp)
if (buf != scratch)
free (buf);
#if CHECKING_P
- qsort_chk (vbase, n, size, cmp);
+ qsort_chk (vbase, n, size, cmp2to3, (void*)cmp);
+#endif
+}
+
+/* Substitute for Glibc qsort_r. */
+void
+gcc_sort_r (void *vbase, size_t n, size_t size, sort_r_cmp_fn *cmp, void *data)
+{
+ if (n < 2)
+ return;
+ char *base = (char *)vbase;
+ sort_r_ctx c = {data, cmp, base, n, size, 5};
+ long long scratch[32];
+ size_t bufsz = (n / 2) * size;
+ void *buf = bufsz <= sizeof scratch ? scratch : xmalloc (bufsz);
+ mergesort (base, &c, n, base, (char *)buf);
+ if (buf != scratch)
+ free (buf);
+#if CHECKING_P
+ qsort_chk (vbase, n, size, cmp, data);
#endif
}
+/* Stable sort, signature-compatible to C qsort. */
void
gcc_stablesort (void *vbase, size_t n, size_t size, cmp_fn *cmp)
{
diff --git a/gcc/stmt.c b/gcc/stmt.c
index 040899e..17f43d1 100644
--- a/gcc/stmt.c
+++ b/gcc/stmt.c
@@ -885,6 +885,7 @@ expand_case (gswitch *stmt)
tree index_type = TREE_TYPE (index_expr);
tree elt;
basic_block bb = gimple_bb (stmt);
+ gimple *def_stmt;
auto_vec<simple_case_node> case_list;
@@ -918,6 +919,31 @@ expand_case (gswitch *stmt)
else
maxval = fold_convert (index_type, CASE_LOW (elt));
+ /* Try to narrow the index type if it's larger than a word.
+ That is mainly for -O0 where an equivalent optimization
+ done by forward propagation is not run and is aimed at
+ avoiding a call to a comparison routine of libgcc. */
+ if (TYPE_PRECISION (index_type) > BITS_PER_WORD
+ && TREE_CODE (index_expr) == SSA_NAME
+ && (def_stmt = SSA_NAME_DEF_STMT (index_expr))
+ && is_gimple_assign (def_stmt)
+ && gimple_assign_rhs_code (def_stmt) == NOP_EXPR)
+ {
+ tree inner_index_expr = gimple_assign_rhs1 (def_stmt);
+ tree inner_index_type = TREE_TYPE (inner_index_expr);
+
+ if (INTEGRAL_TYPE_P (inner_index_type)
+ && TYPE_PRECISION (inner_index_type) <= BITS_PER_WORD
+ && int_fits_type_p (minval, inner_index_type)
+ && int_fits_type_p (maxval, inner_index_type))
+ {
+ index_expr = inner_index_expr;
+ index_type = inner_index_type;
+ minval = fold_convert (index_type, minval);
+ maxval = fold_convert (index_type, maxval);
+ }
+ }
+
/* Compute span of values. */
range = fold_build2 (MINUS_EXPR, index_type, maxval, minval);
@@ -969,27 +995,22 @@ expand_case (gswitch *stmt)
rtx_insn *before_case = get_last_insn ();
- /* Decide how to expand this switch.
- The two options at this point are a dispatch table (casesi or
- tablejump) or a decision tree. */
-
+ /* If the default case is unreachable, then set default_label to NULL
+ so that we omit the range check when generating the dispatch table.
+ We also remove the edge to the unreachable default case. The block
+ itself will be automatically removed later. */
+ if (EDGE_COUNT (default_edge->dest->succs) == 0
+ && gimple_seq_unreachable_p (bb_seq (default_edge->dest)))
{
- /* If the default case is unreachable, then set default_label to NULL
- so that we omit the range check when generating the dispatch table.
- We also remove the edge to the unreachable default case. The block
- itself will be automatically removed later. */
- if (EDGE_COUNT (default_edge->dest->succs) == 0
- && gimple_seq_unreachable_p (bb_seq (default_edge->dest)))
- {
- default_label = NULL;
- remove_edge (default_edge);
- default_edge = NULL;
- }
- emit_case_dispatch_table (index_expr, index_type,
- case_list, default_label, default_edge,
- minval, maxval, range, bb);
+ default_label = NULL;
+ remove_edge (default_edge);
+ default_edge = NULL;
}
+ emit_case_dispatch_table (index_expr, index_type,
+ case_list, default_label, default_edge,
+ minval, maxval, range, bb);
+
reorder_insns (NEXT_INSN (before_case), get_last_insn (), before_case);
free_temp_slots ();
diff --git a/gcc/symtab.c b/gcc/symtab.c
index 63e2820..ee9723c 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -2375,10 +2375,18 @@ symtab_node::output_to_lto_symbol_table_p (void)
first place. */
if (VAR_P (decl) && DECL_HARD_REGISTER (decl))
return false;
- /* FIXME: Builtins corresponding to real functions probably should have
- symbol table entries. */
- if (TREE_CODE (decl) == FUNCTION_DECL && fndecl_built_in_p (decl))
- return false;
+ if (TREE_CODE (decl) == FUNCTION_DECL && !definition
+ && fndecl_built_in_p (decl))
+ {
+ /* Builtins like those for most math functions have actual implementations
+ in libraries so make sure to output references into the symbol table to
+ make those libraries referenced. Note this is incomplete handling for
+ now and only covers math functions. */
+ if (builtin_with_linkage_p (decl))
+ return true;
+ else
+ return false;
+ }
/* We have real symbol that should be in symbol table. However try to trim
down the refernces to libraries bit more because linker will otherwise
diff --git a/gcc/system.h b/gcc/system.h
index d04f8fd..56af544 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -1197,13 +1197,14 @@ helper_const_non_const_cast (const char *p)
/* Get definitions of HOST_WIDE_INT. */
#include "hwint.h"
-/* GCC qsort API-compatible functions: except in release-checking compilers,
- redirect 4-argument qsort calls to gcc_qsort; keep 1-argument invocations
- corresponding to vec::qsort (cmp): they use C qsort internally anyway. */
-void qsort_chk (void *, size_t, size_t, int (*)(const void *, const void *));
+typedef int sort_r_cmp_fn (const void *, const void *, void *);
+void qsort_chk (void *, size_t, size_t, sort_r_cmp_fn *, void *);
+void gcc_sort_r (void *, size_t, size_t, sort_r_cmp_fn *, void *);
void gcc_qsort (void *, size_t, size_t, int (*)(const void *, const void *));
void gcc_stablesort (void *, size_t, size_t,
int (*)(const void *, const void *));
+/* Redirect four-argument qsort calls to gcc_qsort; one-argument invocations
+ correspond to vec::qsort, and use C qsort internally. */
#define PP_5th(a1, a2, a3, a4, a5, ...) a5
#undef qsort
#define qsort(...) PP_5th (__VA_ARGS__, gcc_qsort, 3, 2, qsort, 0) (__VA_ARGS__)
diff --git a/gcc/target.def b/gcc/target.def
index 7cc0f37..4266b8c 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -2545,14 +2545,14 @@ set via @code{__attribute__}.",
DEFHOOK
(libc_has_function,
"This hook determines whether a function from a class of functions\n\
-@var{fn_class} is present at the runtime.",
+@var{fn_class} is present in the target C library.",
bool, (enum function_class fn_class),
default_libc_has_function)
DEFHOOK
(libc_has_fast_function,
"This hook determines whether a function from a class of functions\n\
-@var{fn_class} has a fast implementation.",
+@code{(enum function_class)}@var{fcode} has a fast implementation.",
bool, (int fcode),
default_libc_has_fast_function)
@@ -4551,15 +4551,6 @@ returned by function call into @var{slot}.",
default_store_returned_bounds)
DEFHOOK
-(setup_incoming_vararg_bounds,
- "Use it to store bounds for anonymous register arguments stored\n\
-into the stack. Arguments meaning is similar to\n\
-@code{TARGET_SETUP_INCOMING_VARARGS}.",
- void, (cumulative_args_t args_so_far, machine_mode mode, tree type,
- int *pretend_args_size, int second_time),
- default_setup_incoming_vararg_bounds)
-
-DEFHOOK
(call_args,
"While generating RTL for a function call, this target hook is invoked once\n\
for each argument passed to the function, either a register returned by\n\
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index fa797b4..111ed2e 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -2274,15 +2274,6 @@ std_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
return build_va_arg_indirect_ref (addr);
}
-void
-default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED,
- tree type ATTRIBUTE_UNUSED,
- int *pretend_arg_size ATTRIBUTE_UNUSED,
- int second_time ATTRIBUTE_UNUSED)
-{
-}
-
/* An implementation of TARGET_CAN_USE_DOLOOP_P for targets that do
not support nested low-overhead loops. */
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index ca2e37d..017a9d2 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -265,11 +265,6 @@ extern rtx default_load_bounds_for_arg (rtx, rtx, rtx);
extern void default_store_bounds_for_arg (rtx, rtx, rtx, rtx);
extern rtx default_load_returned_bounds (rtx);
extern void default_store_returned_bounds (rtx,rtx);
-extern void default_setup_incoming_vararg_bounds (cumulative_args_t ca ATTRIBUTE_UNUSED,
- machine_mode mode ATTRIBUTE_UNUSED,
- tree type ATTRIBUTE_UNUSED,
- int *pretend_arg_size ATTRIBUTE_UNUSED,
- int second_time ATTRIBUTE_UNUSED);
extern bool default_optab_supported_p (int, machine_mode, machine_mode,
optimization_type);
extern unsigned int default_max_noce_ifcvt_seq_cost (edge);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8e6b026..6f0bec8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,1652 @@
+2019-08-19 Joel Hutton <Joel.Hutton@arm.com>
+
+ * gcc.target/aarch64/fmul_scvtf_1.c: New test.
+
+2019-08-19 Marek Polacek <polacek@redhat.com>
+
+ PR c++/91264 - detect modifying const objects in constexpr.
+ * g++.dg/cpp1y/constexpr-tracking-const1.C: New test.
+ * g++.dg/cpp1y/constexpr-tracking-const2.C: New test.
+ * g++.dg/cpp1y/constexpr-tracking-const3.C: New test.
+ * g++.dg/cpp1y/constexpr-tracking-const4.C: New test.
+ * g++.dg/cpp1y/constexpr-tracking-const5.C: New test.
+ * g++.dg/cpp1y/constexpr-tracking-const6.C: New test.
+ * g++.dg/cpp1y/constexpr-tracking-const7.C: New test.
+ * g++.dg/cpp1y/constexpr-tracking-const8.C: New test.
+ * g++.dg/cpp1y/constexpr-tracking-const9.C: New test.
+ * g++.dg/cpp1y/constexpr-tracking-const10.C: New test.
+ * g++.dg/cpp1y/constexpr-tracking-const11.C: New test.
+ * g++.dg/cpp1y/constexpr-tracking-const12.C: New test.
+ * g++.dg/cpp1y/constexpr-tracking-const13.C: New test.
+ * g++.dg/cpp1y/constexpr-tracking-const14.C: New test.
+
+2019-08-19 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/elab8.adb, gnat.dg/elab8_gen.adb,
+ gnat.dg/elab8_gen.ads, gnat.dg/elab8_pkg.adb,
+ gnat.dg/elab8_pkg.ads: New testcase.
+
+2019-08-19 Bob Duff <duff@adacore.com>
+
+ * gnat.dg/warn29.adb, gnat.dg/warn29.ads: New testcase.
+
+2019-08-19 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/expr_func9.adb: New testcase.
+
+2019-08-19 Bob Duff <duff@adacore.com>
+
+ * gnat.dg/valid_scalars2.adb: New testcase.
+
+2019-08-19 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/generic_inst12.adb, gnat.dg/generic_inst12_pkg1.adb,
+ gnat.dg/generic_inst12_pkg1.ads,
+ gnat.dg/generic_inst12_pkg2.ads: New testcase.
+
+2019-08-19 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/warn28.adb, gnat.dg/warn28.ads: New testcase.
+
+2019-08-19 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/rep_clause9.adb: New testcase.
+
+2019-08-19 Olivier Hainque <hainque@adacore.com>
+
+ * gnat.dg/openacc1.adb: New testcase.
+
+2019-08-19 Kito Cheng <kito.cheng@sifive.com>
+
+ PR target/91441
+ * gcc.target/riscv/pr91441.c: New.
+
+2019-08-18 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/91485
+ * gfortran.dg/pr91485.f90: New test.
+
+2019-08-17 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/82992
+ * gfortran.dg/pr71649.f90: Adjust error messages.
+ * gfortran.dg/use_15.f90: Ditto.
+ * gfortran.dg/use_rename_8.f90: Ditto.
+
+2019-08-17 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/78739
+ * fortran.dg/pr78739.f90: New test.
+
+2019-08-17 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/78719
+ * gfortran.dg/pr78719_1.f90: New test.
+ * gfortran.dg/pr78719_2.f90: Ditto.
+ * gfortran.dg/pr78719_3.f90: Ditto.
+
+2019-08-17 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/91471
+ * gfortran.dg/pr91471.f90: New test.
+
+2019-08-16 Marek Polacek <polacek@redhat.com>
+
+ PR c++/85827
+ * g++.dg/cpp1z/constexpr-if29.C: New test.
+
+2019-08-16 Jeff Law <law@redhat.com>
+
+ * gcc.target/sh/pr54236-6.c: Use -fno-tree-forwprop.
+
+2019-08-16 Martin Sebor <msebor@redhat.com>
+
+ * gcc.dg/struct-ret-1.c: Enable on all targets.
+
+2019-08-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/opt81.ad[sb]: New test.
+
+2019-08-16 Martin Sebor <msebor@redhat.com>
+
+ PR testsuite/91458
+ * g++.dg/tree-ssa/pr19807.C: Use the same search pattern
+ unconditionally (correcting r272199, PR middle-end/90676).
+
+2019-08-16 Richard Biener <rguenther@suse.de>
+
+ PR target/91469
+ * gcc.target/i386/pr91469-1.c: New testcase.
+ * gcc.target/i386/pr91469-2.c: Likewise.
+
+2019-08-16 Mark Eggleston <mark.eggleston@codethink.com>
+
+ * gfortran.dg/auto_in_equiv_1.f90: New test.
+ * gfortran.dg/auto_in_equiv_2.f90: New test.
+ * gfortran.dg/auto_in_equiv_3.f90: New test.
+
+2019-08-16 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/forwprop-31.c: Adjust.
+
+2019-08-16 Martin Liska <mliska@suse.cz>
+
+ PR ipa/91447
+ * g++.dg/ipa/ipa-icf-4.C: Add -missed for target that
+ don't have aliases.
+
+2019-08-16 Alexandre Oliva <oliva@adacore.com>
+
+ * gcc.target/i386/pr85044.c: Require support for trampolines.
+
+ * gcc.target/i386/asm-4.c: Use amd64 natural addressing mode
+ on all __LP64__ targets.
+
+ * gcc.target/arc/interrupt-6.c: Use __builtin_alloca, require
+ effective target support for alloca, drop include of alloca.h.
+ * gcc.target/i386/pr80969-3.c: Likewise.
+ * gcc.target/sparc/setjmp-1.c: Likewise.
+ * gcc.target/x86_64/abi/ms-sysv/gen.cc: Likewise.
+ * gcc.target/x86_64/abi/ms-sysv/ms-sysv.c: Likewise.
+
+ * gcc.misc-tests/options.exp: Match /ld and -ld besides
+ /collect2.
+
+2019-08-15 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/91443
+ * gfortran.dg/argument_checking_19.f90: New test.
+ * gfortran.dg/altreturn_10.f90: Change dg-warning to dg-error.
+ * gfortran.dg/dec_union_11.f90: Add -std=legacy.
+ * gfortran.dg/hollerith8.f90: Likewise. Remove warning for
+ Hollerith constant.
+ * gfortran.dg/integer_exponentiation_2.f90: New subroutine gee_i8;
+ use it to avoid type mismatches.
+ * gfortran.dg/pr41011.f: Add -std=legacy.
+ * gfortran.dg/whole_file_1.f90: Change warnings to errors.
+ * gfortran.dg/whole_file_2.f90: Likewise.
+
+2019-08-15 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91445
+ * gcc.dg/torture/pr91445.c: New testcase.
+
+2019-08-15 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/pr80170.c: Adjust to use __SIZETYPE__.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/loop_add_4.c: Expect 10 INCWs and
+ INCDs rather than 8.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/revb_1.c: Restrict to little-endian targets.
+ Avoid including stdint.h.
+ * gcc.target/aarch64/sve/revh_1.c: Likewise.
+ * gcc.target/aarch64/sve/revw_1.c: Likewise.
+ * gcc.target/aarch64/sve/revb_2.c: New big-endian test.
+ * gcc.target/aarch64/sve/revh_2.c: Likewise.
+ * gcc.target/aarch64/sve/revw_2.c: Likewise.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * gcc.target/aarch64/sve/cond_mla_5.c: Allow FMAD as well as FMLA
+ and FMSB as well as FMLS.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/ext_2.c: Expect a MOVPRFX.
+ * gcc.target/aarch64/sve/ext_3.c: New test.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+ Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ * gcc.target/aarch64/sve/shift_1.c: Accept reversed shifts.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * gcc.target/aarch64/sve/cond_mla_1.c: New test.
+ * gcc.target/aarch64/sve/cond_mla_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_mla_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_mla_2_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_mla_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_mla_3_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_mla_4.c: Likewise.
+ * gcc.target/aarch64/sve/cond_mla_4_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_mla_5.c: Likewise.
+ * gcc.target/aarch64/sve/cond_mla_5_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_mla_6.c: Likewise.
+ * gcc.target/aarch64/sve/cond_mla_6_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_mla_7.c: Likewise.
+ * gcc.target/aarch64/sve/cond_mla_7_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_mla_8.c: Likewise.
+ * gcc.target/aarch64/sve/cond_mla_8_run.c: Likewise.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * gcc.target/aarch64/sve/cond_fadd_1.c: New test.
+ * gcc.target/aarch64/sve/cond_fadd_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fadd_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fadd_2_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fadd_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fadd_3_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fadd_4.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fadd_4_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fsubr_1.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fsubr_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fsubr_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fsubr_2_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fsubr_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fsubr_3_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fsubr_4.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fsubr_4_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmaxnm_1.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmaxnm_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmaxnm_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmaxnm_2_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmaxnm_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmaxnm_3_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmaxnm_4.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmaxnm_4_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fminnm_1.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fminnm_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fminnm_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fminnm_2_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fminnm_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fminnm_3_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fminnm_4.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fminnm_4_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmul_1.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmul_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmul_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmul_2_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmul_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmul_3_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmul_4.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fmul_4_run.c: Likewise.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * gcc.target/aarch64/sve/cond_fabd_1.c: New test.
+ * gcc.target/aarch64/sve/cond_fabd_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fabd_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fabd_2_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fabd_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fabd_3_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fabd_4.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fabd_4_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fabd_5.c: Likewise.
+ * gcc.target/aarch64/sve/cond_fabd_5_run.c: Likewise.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * gcc.target/aarch64/sve/cond_abd_1.c: New test.
+ * gcc.target/aarch64/sve/cond_abd_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_abd_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_abd_2_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_abd_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_abd_3_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_abd_4.c: Likewise.
+ * gcc.target/aarch64/sve/cond_abd_4_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_abd_5.c: Likewise.
+ * gcc.target/aarch64/sve/cond_abd_5_run.c: Likewise.
+
+2019-08-15 Richard Sandiford <richard.sandiford@arm.com>
+ Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ * gcc.target/aarch64/sve/cond_shift_1.c: New test.
+ * gcc.target/aarch64/sve/cond_shift_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_2_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_3_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_4.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_4_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_5.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_5_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_6.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_6_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_7.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_7_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_8.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_8_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_9.c: Likewise.
+ * gcc.target/aarch64/sve/cond_shift_9_run.c: Likewise.
+
+2019-08-14 Martin Sebor <msebor@redhat.com>
+
+ PR testsuite/91449
+ * gcc.dg/strlenopt-73.c: Restrict 128-bit tests to i386.
+
+2019-08-14 Jonathan Wakely <jwakely@redhat.com>
+
+ PR c++/91436
+ * g++.dg/lookup/missing-std-include-5.C: Limit test to C++14 and up.
+ * g++.dg/lookup/missing-std-include-6.C: Don't check make_unique in
+ test that runs for C++11.
+ * g++.dg/lookup/missing-std-include-8.C: Check make_unique here.
+
+2019-08-14 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.c-torture/execute/noinit-attribute.c: Fix typo.
+
+2019-08-14 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/91294
+ * gcc.dg/strlenopt-44.c: Adjust tested result.
+ * gcc.dg/strlenopt-70.c: Avoid exercising unimplemnted optimization.
+ * gcc.dg/strlenopt-73.c: New test.
+ * gcc.dg/strlenopt-74.c: New test.
+ * gcc.dg/strlenopt-75.c: New test.
+ * gcc.dg/strlenopt-76.c: New test.
+ * gcc.dg/strlenopt-77.c: New test.
+
+2019-08-14 Jakub Jelinek <jakub@redhat.com>
+ Marek Polacek <polacek@redhat.com>
+
+ PR c++/91391 - bogus -Wcomma-subscript warning.
+ * g++.dg/cpp2a/comma5.C: New test.
+
+2019-08-14 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * lib/target-supports.exp (check_effective_target_noinit): New
+ proc.
+ * gcc.c-torture/execute/noinit-attribute.c: New test.
+
+2019-08-14 Richard Biener <rguenther@suse.de>
+
+ PR target/91154
+ * gcc.target/i386/pr91154.c: New testcase.
+ * gcc.target/i386/minmax-3.c: Likewise.
+ * gcc.target/i386/minmax-4.c: Likewise.
+ * gcc.target/i386/minmax-5.c: Likewise.
+ * gcc.target/i386/minmax-6.c: Likewise.
+ * gcc.target/i386/minmax-1.c: Add -mno-stv.
+ * gcc.target/i386/minmax-2.c: Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * gcc.target/aarch64/sve/cond_logical_1.c: New test.
+ * gcc.target/aarch64/sve/cond_logical_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_logical_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_logical_2_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_logical_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_logical_3_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_logical_4.c: Likewise.
+ * gcc.target/aarch64/sve/cond_logical_4_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_logical_5.c: Likewise.
+ * gcc.target/aarch64/sve/cond_logical_5_run.c: Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/cond_uxt_1.c: New test.
+ * gcc.target/aarch64/sve/cond_uxt_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_uxt_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_uxt_2_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_uxt_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_uxt_3_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_uxt_4.c: Likewise.
+ * gcc.target/aarch64/sve/cond_uxt_4_run.c: Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/cond_convert_1.c: New test.
+ * gcc.target/aarch64/sve/cond_convert_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_convert_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_convert_2_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_convert_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_convert_3_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_convert_4.c: Likewise.
+ * gcc.target/aarch64/sve/cond_convert_4_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_convert_5.c: Likewise.
+ * gcc.target/aarch64/sve/cond_convert_5_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_convert_6.c: Likewise.
+ * gcc.target/aarch64/sve/cond_convert_6_run.c: Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * gcc.target/aarch64/sve/cond_unary_1.c: Add tests for
+ floating-point types.
+ * gcc.target/aarch64/sve/cond_unary_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_unary_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_unary_4.c: Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * gcc.target/aarch64/sve/cond_unary_1.c: New test.
+ * gcc.target/aarch64/sve/cond_unary_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_unary_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_unary_2_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_unary_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_unary_3_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_unary_4.c: Likewise.
+ * gcc.target/aarch64/sve/cond_unary_4_run.c: Likewise.
+
+2019-08-14 Bob Duff <duff@adacore.com>
+
+ * gnat.dg/alignment15.adb: New testcase.
+
+2019-08-14 Bob Duff <duff@adacore.com>
+
+ * gnat.dg/warn27.adb: New testcase.
+
+2019-08-14 Bob Duff <duff@adacore.com>
+
+ * gnat.dg/inline19.adb, gnat.dg/inline19.ads: New testcase.
+
+2019-08-14 Gary Dismukes <dismukes@adacore.com>
+
+ * gnat.dg/equal11.adb, gnat.dg/equal11_interface.ads,
+ gnat.dg/equal11_record.adb, gnat.dg/equal11_record.ads: New
+ testcase.
+
+2019-08-14 Bob Duff <duff@adacore.com>
+
+ * gnat.dg/discr57.adb: New testcase.
+
+2019-08-14 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/generic_inst11.adb, gnat.dg/generic_inst11_pkg.adb,
+ gnat.dg/generic_inst11_pkg.ads: New testcase.
+
+2019-08-14 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/assert2.adb, gnat.dg/assert2.ads: New testcase.
+
+2019-08-14 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/inline18.adb, gnat.dg/inline18.ads,
+ gnat.dg/inline18_gen1-inner_g.ads, gnat.dg/inline18_gen1.adb,
+ gnat.dg/inline18_gen1.ads, gnat.dg/inline18_gen2.adb,
+ gnat.dg/inline18_gen2.ads, gnat.dg/inline18_gen3.adb,
+ gnat.dg/inline18_gen3.ads, gnat.dg/inline18_pkg1.adb,
+ gnat.dg/inline18_pkg1.ads, gnat.dg/inline18_pkg2-child.ads,
+ gnat.dg/inline18_pkg2.ads: New testcase.
+
+2019-08-14 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/predicate12.adb, gnat.dg/predicate12.ads: New
+ testcase.
+
+2019-08-14 Gary Dismukes <dismukes@adacore.com>
+
+ * gnat.dg/task5.adb: New testcase.
+
+2019-08-14 Richard Biener <rguenther@suse.de>
+
+ PR testsuite/91419
+ * lib/target-supports.exp (natural_alignment_32): Amend target
+ list based on BIGGEST_ALIGNMENT.
+ (natural_alignment_64): Targets not natural_alignment_32 cannot
+ be natural_alignment_64.
+ * gcc.dg/tree-ssa/pr91091-2.c: XFAIL for !natural_alignment_32.
+ * gcc.dg/tree-ssa/ssa-fre-77.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-fre-61.c: Require natural_alignment_32.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/vcond_21.c: New test.
+ * gcc.target/aarch64/sve/vcond_21_run.c: Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * g++.target/aarch64/sve/dup_sel_1.C: New test.
+ * g++.target/aarch64/sve/dup_sel_2.C: Likewise.
+ * g++.target/aarch64/sve/dup_sel_3.C: Likewise.
+ * g++.target/aarch64/sve/dup_sel_4.C: Likewise.
+ * g++.target/aarch64/sve/dup_sel_5.C: Likewise.
+ * g++.target/aarch64/sve/dup_sel_6.C: Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+ Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
+
+ * gcc.target/aarch64/sve/vcond_18.c: New test.
+ * gcc.target/aarch64/sve/vcond_18_run.c: Likewise.
+ * gcc.target/aarch64/sve/vcond_19.c: Likewise.
+ * gcc.target/aarch64/sve/vcond_19_run.c: Likewise.
+ * gcc.target/aarch64/sve/vcond_20.c: Likewise.
+ * gcc.target/aarch64/sve/vcond_20_run.c: Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/fmaxnm_1.c: New test.
+ * gcc.target/aarch64/sve/fminnm_1.c: Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/smax_1.c: New test.
+ * gcc.target/aarch64/sve/smin_1.c: Likewise.
+ * gcc.target/aarch64/sve/umax_1.c: Likewise.
+ * gcc.target/aarch64/sve/umin_1.c: Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/cnot_1.c: New test.
+ * gcc.target/aarch64/sve/cond_cnot_1.c: Likewise.
+ * gcc.target/aarch64/sve/cond_cnot_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_cnot_2.c: Likewise.
+ * gcc.target/aarch64/sve/cond_cnot_2_run.c: Likewise.
+ * gcc.target/aarch64/sve/cond_cnot_3.c: Likewise.
+ * gcc.target/aarch64/sve/cond_cnot_3_run.c: Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/vect-clz.c: Force SVE off.
+ * gcc.target/aarch64/sve/clrsb_1.c: New test.
+ * gcc.target/aarch64/sve/clrsb_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/clz_1.c: Likewise.
+ * gcc.target/aarch64/sve/clz_1_run.c: Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/adr_1.c: New test.
+ * gcc.target/aarch64/sve/adr_1_run.c: Likewise.
+ * gcc.target/aarch64/sve/adr_2.c: Likewise.
+ * gcc.target/aarch64/sve/adr_2_run.c: Likewise.
+ * gcc.target/aarch64/sve/adr_3.c: Likewise.
+ * gcc.target/aarch64/sve/adr_3_run.c: Likewise.
+ * gcc.target/aarch64/sve/adr_4.c: Likewise.
+ * gcc.target/aarch64/sve/adr_4_run.c: Likewise.
+ * gcc.target/aarch64/sve/adr_5.c: Likewise.
+ * gcc.target/aarch64/sve/adr_5_run.c: Likewise.
+
+2019-08-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * g++.dg/conversion/simd4.C: Test locations.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/peel_ind_1.c: Look for an inverted .B VL1.
+ * gcc.target/aarch64/sve/peel_ind_2.c: Likewise .S VL7.
+
+2019-08-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * g++.dg/parse/typedef9.C: Test locations too.
+
+2019-08-14 Martin Liska <mliska@suse.cz>
+
+ * c-c++-common/asan/memcmp-1.c: There's a new function in the
+ stack-trace on the top. So shift expected output in stack
+ trace.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/vcond_17.c: New test.
+ * gcc.target/aarch64/sve/vcond_17_run.c: Likewise.
+
+2019-08-14 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/spill_4.c: Expect all ptrues to be .Bs.
+ * gcc.target/aarch64/sve/single_1.c: Likewise.
+ * gcc.target/aarch64/sve/single_2.c: Likewise.
+ * gcc.target/aarch64/sve/single_3.c: Likewise.
+ * gcc.target/aarch64/sve/single_4.c: Likewise.
+
+2019-08-13 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/87991
+ * gfortran.dg/pr87991.f90: New test.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/spill_2.c: Increase iteration counts
+ beyond the range of a PTRUE.
+ * gcc.target/aarch64/sve/while_6.c: New test.
+ * gcc.target/aarch64/sve/while_7.c: Likewise.
+ * gcc.target/aarch64/sve/while_8.c: Likewise.
+ * gcc.target/aarch64/sve/while_9.c: Likewise.
+ * gcc.target/aarch64/sve/while_10.c: Likewise.
+
+2019-08-13 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/88072
+ * gfortran.dg/unlimited_polymorphic_28.f90: Fix error message. Left
+ out of previous commit!
+
+2019-08-13 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/88072
+ * gfortran.dg/pr88072.f90: New test.
+ * gfortran.dg/unlimited_polymorphic_28.f90: Fix error message.
+
+2019-08-13 Iain Sandoe <iain@sandoe.co.uk>
+
+ * obj-c++.dg/stubify-1.mm: Rename symbol stub option.
+ * obj-c++.dg/stubify-2.mm: Likewise.
+ * objc.dg/stubify-1.m: Likewise.
+ * objc.dg/stubify-2.m: Likewise.
+
+2013-08-13 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/90563
+ * gfortran.dg/do_subsript_5.f90: New test.
+
+2019-08-13 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/89647
+ * gfortran.dg/pr89647.f90: New test.
+
+2019-08-13 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/87993
+ * gfortran.dg/pr87993.f90: New test.
+
+2019-08-13 Martin Sebor <msebor@redhat.com>
+
+ PR c/80619
+ * gcc.dg/format/pr80619.c: New test.
+
+2019-08-13 Marek Polacek <polacek@redhat.com>
+
+ PR c++/90473 - wrong code with nullptr in default argument.
+ * g++.dg/cpp0x/nullptr42.C: New test.
+
+2019-08-13 Olivier Hainque <hainque@adacore.com>
+
+ * gnat.dg/casesi.ad[bs], test_casesi.adb: New test.
+
+2019-08-13 Wilco Dijkstra <wdijkstr@arm.com>
+
+ PR target/81800
+ * gcc.target/aarch64/no-inline-lrint_3.c: New test.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/init_2.c: Expect ld1rd to be used
+ instead of a full vector load.
+ * gcc.target/aarch64/sve/init_4.c: Likewise.
+ * gcc.target/aarch64/sve/ld1r_2.c: Remove constants that no longer
+ need to be loaded from memory.
+ * gcc.target/aarch64/sve/slp_2.c: Expect the same output for
+ big and little endian.
+ * gcc.target/aarch64/sve/slp_3.c: Likewise. Expect 3 of the
+ doubles to be moved via integer registers rather than loaded
+ from memory.
+ * gcc.target/aarch64/sve/slp_4.c: Likewise but for 4 doubles.
+ * gcc.target/aarch64/sve/spill_4.c: Expect 16-bit constants to be
+ loaded via an integer register rather than from memory.
+ * gcc.target/aarch64/sve/const_1.c: New test.
+ * gcc.target/aarch64/sve/const_2.c: Likewise.
+ * gcc.target/aarch64/sve/const_3.c: Likewise.
+
+2019-08-13 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * gcc.target/msp430/msp430.exp (msp430_device_permutations_runtest):
+ Handle csv-* and bad-devices-* tests.
+ * gcc.target/msp430/devices/README: Document how bad-devices-* tests
+ work.
+ * gcc.target/msp430/devices/bad-devices-1.c: New test.
+ * gcc.target/msp430/devices/bad-devices-2.c: Likewise.
+ * gcc.target/msp430/devices/bad-devices-3.c: Likewise.
+ * gcc.target/msp430/devices/bad-devices-4.c: Likewise.
+ * gcc.target/msp430/devices/bad-devices-5.c: Likewise.
+ * gcc.target/msp430/devices/bad-devices-6.c: Likewise.
+ * gcc.target/msp430/devices/csv-device-order.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430_00.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430_01.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430_02.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430_04.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430_08.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430_10.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430_11.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430_12.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430_14.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430_18.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430_20.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430_21.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430_22.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430_24.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430_28.c: Likewise.
+ * gcc.target/msp430/devices/csv-msp430fr5969.c: Likewise.
+ * gcc.target/msp430/devices/hard-foo.c: Likewise.
+ * gcc.target/msp430/devices/bad-devices-1.csv: New test support file.
+ * gcc.target/msp430/devices/bad-devices-2.csv: Likewise.
+ * gcc.target/msp430/devices/bad-devices-3.csv: Likewise.
+ * gcc.target/msp430/devices/bad-devices-4.csv: Likewise.
+ * gcc.target/msp430/devices/bad-devices-5.csv: Likewise.
+ * gcc.target/msp430/devices/bad-devices-6.csv: Likewise.
+ * gcc.target/msp430/devices/devices.csv: Likewise.
+
+2019-08-13 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * gcc.target/msp430/msp430.exp
+ (check_effective_target_msp430_430_selected): New.
+ (check_effective_target_msp430_430x_selected): New.
+ (check_effective_target_msp430_mlarge_selected): New.
+ (check_effective_target_msp430_hwmul_not_none): New.
+ (check_effective_target_msp430_hwmul_not_16bit): New.
+ (check_effective_target_msp430_hwmul_not_32bit): New.
+ (check_effective_target_msp430_hwmul_not_f5): New.
+ (msp430_get_opts): New.
+ (msp430_device_permutations_runtest): New.
+ * gcc.target/msp430/devices/README: New file.
+ * gcc.target/msp430/devices-main.c: New test.
+ * gcc.target/msp430/devices/hard-cc430f5123.c: Likewise.
+ * gcc.target/msp430/devices/hard-foo.c: Likewise.
+ * gcc.target/msp430/devices/hard-msp430afe253.c: Likewise.
+ * gcc.target/msp430/devices/hard-msp430cg4616.c: Likewise.
+ * gcc.target/msp430/devices/hard-msp430f4783.c: Likewise.
+ * gcc.target/msp430/devices/hard-rf430frl154h_rom.c: Likewise.
+
+2019-08-13 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/asm-x-constraint-1.c: New test.
+ * gcc.target/aarch64/asm-y-constraint-1.c: Likewise.
+
+2019-08-13 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR fortran/91414
+ * gfortran.dg/random_seed_1.f90: Update to match new seed size.
+
+2019-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/discr56.adb, gnat.dg/discr56.ads,
+ gnat.dg/discr56_pkg1.adb, gnat.dg/discr56_pkg1.ads,
+ gnat.dg/discr56_pkg2.ads: New testcase.
+
+2019-08-13 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/tagged4.adb: New testcase.
+
+2019-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/generic_inst10.adb, gnat.dg/generic_inst10_pkg.ads:
+ New testcase.
+
+2019-08-13 Javier Miranda <miranda@adacore.com>
+
+ * gnat.dg/tagged3.adb, gnat.dg/tagged3_pkg.adb,
+ gnat.dg/tagged3_pkg.ads: New testcase.
+
+2019-08-13 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/aggr27.adb: New testcase.
+
+2019-08-13 Gary Dismukes <dismukes@adacore.com>
+
+ * gnat.dg/aggr26.adb: New testcase.
+
+2019-08-13 Yannick Moy <moy@adacore.com>
+
+ * gnat.dg/allocator2.adb, gnat.dg/allocator2.ads: New testcase.
+
+2019-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/generic_inst9.adb, gnat.dg/generic_inst9.ads,
+ gnat.dg/generic_inst9_pkg1-operator.ads,
+ gnat.dg/generic_inst9_pkg1.ads, gnat.dg/generic_inst9_pkg2.adb,
+ gnat.dg/generic_inst9_pkg2.ads: New testcase.
+
+2019-08-13 Justin Squirek <squirek@adacore.com>
+
+ * gnat.dg/anon3.adb, gnat.dg/anon3.ads: New testcase.
+
+2019-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/generic_inst8.adb, gnat.dg/generic_inst8.ads,
+ gnat.dg/generic_inst8_g.adb, gnat.dg/generic_inst8_g.ads: New
+ testcase.
+
+2019-08-13 Javier Miranda <miranda@adacore.com>
+
+ * gnat.dg/tag2.adb, gnat.dg/tag2_pkg.ads: New testcase.
+
+2019-08-13 Martin Liska <mliska@suse.cz>
+
+ * gcc.dg/tree-prof/ic-misattribution-1.c: Use -fdump-ipa-profile-node.
+
+2019-08-12 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/91424
+ * gfortran.dg/do_subscript_3.f90: New test.
+ * gfortran.dg/do_subscript_4.f90: New test.
+ * gfortran.dg/pr70754.f90: Use indices that to not overflow.
+
+2019-08-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/83250
+ PR target/91340
+ * gcc.target/i386/avx-typecast-1.c: New test.
+ * gcc.target/i386/avx-typecast-2.c: New test.
+ * gcc.target/i386/avx512f-typecast-2.c: New test.
+
+2019-08-12 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/null_check.adb: New testcase.
+
+2019-08-12 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/renaming15.adb: New testcase.
+
+2019-08-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/slice10.adb: New testcase.
+
+2019-08-12 Gary Dismukes <dismukes@adacore.com>
+
+ * gnat.dg/generic_inst7.adb, gnat.dg/generic_inst7_pkg.adb,
+ gnat.dg/generic_inst7_pkg.ads, gnat.dg/generic_inst7_types.ads:
+ New testcase.
+
+2019-08-12 Ed Schonberg <schonberg@adacore.com>
+
+ * gnat.dg/equal10.adb, gnat.dg/equal10.ads: New testcase.
+
+2019-08-12 Gary Dismukes <dismukes@adacore.com>
+
+ * gnat.dg/suppress_initialization2.adb,
+ gnat.dg/suppress_initialization2.ads: New testcase.
+
+2019-08-12 Yannick Moy <moy@adacore.com>
+
+ * gnat.dg/no_caching.adb, gnat.dg/no_caching.ads: New testcase.
+
+2019-08-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/range_check7.adb: New testcase.
+
+2019-08-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/range_check6.adb: New testcase.
+
+2019-08-11 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/90601
+ * gdc.dg/pr90601.d: New test.
+
+2019-08-10 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ * gfortran.dg/boz_8.f90: Adjust error messages.
+ * gfortran.dg/nan_4.f90: Ditto.
+ * gfortran.dg/boz_1.f90: Add -fallow-invalid-boz to dg-options,
+ and test for warnings.
+ * gfortran.dg/boz_3.f90: Ditto.
+ * gfortran.dg/boz_4.f90: Ditto.
+ * gfortran.dg/dec_structure_6.f90: Ditto.
+ * gfortran.dg/ibits.f90: Ditto.
+
+2019-08-10 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/91238
+ * gdc.dg/pr91238.d: New test.
+
+2019-08-10 Jakub Jelinek <jakub@redhat.com>
+
+ * c-c++-common/gomp/declare-target-2.c: Don't expect error for
+ declare target with clauses in between declare target without clauses
+ and end declare target.
+ * c-c++-common/gomp/declare-target-4.c: New test.
+
+ PR target/91408
+ * gcc.target/i386/pr91408.c: New test.
+
+2019-08-09 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * gcc.target/powerpc/vec_rotate-1.c: Rename to ...
+ * gcc.target/powerpc/vec-rotate-1.c: ... this. Add -maltivec option.
+ * gcc.target/powerpc/vec_rotate-2.c: Rename to ...
+ * gcc.target/powerpc/vec-rotate-2.c: ... this.
+ * gcc.target/powerpc/vec_rotate-3.c: Rename to ...
+ * gcc.target/powerpc/vec-rotate-3.c: ... this. Add -maltivec option.
+ * gcc.target/powerpc/vec_rotate-4.c: Rename to ...
+ * gcc.target/powerpc/vec-rotate-4.c: ... this.
+
+2019-08-09 Sam Tebbs <sam.tebbs@arm.com>
+
+ * lib/target-supports.exp
+ (check_effective_target_arm_v8_4a_bkey_directive): New proc.
+ * g++.target/aarch64/return_address_sign_b_exception.C,
+ return_address_sign_ab_exception.C: Add dg-require-effective-target
+ checks.
+
+2019-08-09 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR middle-end/90313
+ * g++.dg/torture/pr90313.cc: New test.
+
+2019-08-09 Martin Liska <mliska@suse.cz>
+
+ * g++.dg/lto/devirt-19_0.C: Add -flto=auto.
+
+2019-08-09 Martin Liska <mliska@suse.cz>
+
+ * gcc.dg/spellcheck-options-21.c: New test.
+
+2019-08-09 Martin Liska <mliska@suse.cz>
+
+ * g++.dg/ipa/ipa-icf-2.C: Add -optimized to -fdump-ipa-icf.
+ * g++.dg/ipa/ipa-icf-3.C: Likewise.
+ * g++.dg/ipa/ipa-icf-4.C: Likewise.
+ * g++.dg/ipa/ipa-icf-6.C: Likewise.
+ * gcc.dg/ipa/ipa-icf-1.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-10.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-11.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-12.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-13.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-16.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-18.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-2.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-20.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-21.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-23.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-25.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-26.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-27.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-3.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-35.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-36.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-37.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-38.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-39.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-5.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-7.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-8.c: Likewise.
+ * gcc.dg/ipa/ipa-icf-merge-1.c: Likewise.
+ * gcc.dg/ipa/pr64307.c: Likewise.
+ * gcc.dg/ipa/pr90555.c: Likewise.
+
+2019-08-09 Martin Liska <mliska@suse.cz>
+
+ * g++.dg/tree-prof/indir-call-prof.C: Add -optimize
+ to -fdump-ipa-profile.
+ * g++.dg/tree-prof/morefunc.C: Likewise.
+ * g++.dg/tree-prof/reorder.C: Likewise.
+ * gcc.dg/tree-prof/ic-misattribution-1.c: Likewise.
+ * gcc.dg/tree-prof/indir-call-prof.c: Likewise.
+ * gcc.dg/tree-prof/stringop-1.c: Likewise.
+ * gcc.dg/tree-prof/stringop-2.c: Likewise.
+ * gcc.dg/tree-prof/val-prof-1.c: Likewise.
+ * gcc.dg/tree-prof/val-prof-2.c: Likewise.
+ * gcc.dg/tree-prof/val-prof-3.c: Likewise.
+ * gcc.dg/tree-prof/val-prof-4.c: Likewise.
+ * gcc.dg/tree-prof/val-prof-5.c: Likewise.
+ * gcc.dg/tree-prof/val-prof-7.c: Likewise.
+
+2019-08-09 Jakub Jelinek <jakub@redhat.com>
+
+ * c-c++-common/gomp/if-4.c: New test.
+ * c-c++-common/gomp/clause-dups-1.c: New test.
+
+ PR c/91401
+ * c-c++-common/gomp/pr91401-1.c: New test.
+ * c-c++-common/gomp/pr91401-2.c: New test.
+
+2019-08-09 Alexandre Oliva <oliva@adacore.com>
+
+ * gcc.target/i386/sse2-mul-1.c: Use rand. Drop fallback.
+ * gcc.target/i386/sse4_1-blendps-2.c: Likewise.
+ * gcc.target/i386/sse4_1-blendps.c: Likewise.
+ * gcc.target/i386/xop-vshift-1.c: Likewise.
+ * gcc.target/powerpc/direct-move.h: Likewise.
+
+2019-08-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * g++.dg/cpp0x/enum20.C: Test location(s) too.
+ * g++.dg/other/friend3.C: Likewise.
+ * g++.dg/parse/dtor5.C: Likewise.
+ * g++.dg/parse/friend7.C: Likewise.
+ * g++.dg/template/error22.C: Likewise.
+ * g++.old-deja/g++.brendan/err-msg5.C: Likewise.
+
+2019-08-08 Jim Wilson <jimw@sifive.com>
+
+ PR target/91229
+ * gcc.target/riscv/flattened-struct-abi-1.c: New test.
+ * gcc.target/riscv/flattened-struct-abi-2.c: New test.
+
+2019-08-08 Marek Polacek <polacek@redhat.com>
+
+ PR c++/79520
+ * g++.dg/cpp1y/constexpr-79520.C: New test.
+
+2019-08-08 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/pr79983.c (enum E): Don't allow an error about nested
+ definitions.
+ * gcc.dg/enum-redef-1.c: New test.
+
+2019-08-08 Marek Polacek <polacek@redhat.com>
+
+ PR c++/87519 - bogus warning with -Wsign-conversion.
+ * g++.dg/warn/Wsign-conversion-5.C: New test.
+
+ * g++.dg/cpp2a/inline-asm3.C: New test.
+
+2019-08-07 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/91359
+ * pr91359_2.f: Fix missing hyphen in dg-do
+ * pr91359_1.f: Ditto. Remove RESULT variable to test actual fix!
+
+2019-08-07 Marek Polacek <polacek@redhat.com>
+
+ PR c++/67533
+ * g++.dg/tls/thread_local-ice5.C: New test.
+
+2019-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/init_13.c: New test.
+
+2019-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/init_12.c: Expect w1 to be moved into
+ a temporary FPR.
+
+2019-08-07 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/clastb_8.c: New test.
+
+2019-08-07 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/91385
+ * gcc.target/i386/pr91385.c: New test.
+
+2019-08-07 Marek Polacek <polacek@redhat.com>
+
+ PR c++/81429 - wrong parsing of constructor with C++11 attribute.
+ * g++.dg/cpp0x/gen-attrs-68.C: New test.
+ * g++.dg/cpp0x/gen-attrs-69.C: New test.
+
+2019-08-07 Marek Polacek <polacek@redhat.com>
+
+ PR c++/91346 - Implement P1668R1, allow unevaluated asm in constexpr.
+ * g++.dg/cpp2a/inline-asm1.C: New test.
+ * g++.dg/cpp2a/inline-asm2.C: New test.
+ * g++.dg/cpp1y/constexpr-neg1.C: Adjust dg-error.
+
+2019-08-07 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR fortran/53796
+ * gfortran.dg/inquire_recl_f2018.f90: Test for unconnected unit
+ with inquire via filename.
+
+2019-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ * c-c++-common/gomp/target-data-1.c (foo): Use use_device_addr clause
+ instead of use_device_ptr clause where required by OpenMP 5.0, add
+ further tests for both use_device_ptr and use_device_addr clauses.
+
+2019-08-07 Kewen Lin <linkw@gcc.gnu.org>
+
+ * gcc.target/powerpc/vec_rotate-1.c: New test.
+ * gcc.target/powerpc/vec_rotate-2.c: New test.
+ * gcc.target/powerpc/vec_rotate-3.c: New test.
+ * gcc.target/powerpc/vec_rotate-4.c: New test.
+
+2019-08-07 Alexandre Oliva <oliva@adacore.com>
+
+ * gcc.target/i386/math_m_pi.h: New.
+ * gcc.target/i386/sse4_1-round.h: Use it.
+ * gcc.target/i386/pr73350.c: Likewise.
+ * gcc.target/i386/avx512f-vfixupimmpd-2.c: Likewise.
+ * gcc.target/i386/avx512f-vfixupimmps-2.c: Likewise.
+ * gcc.target/i386/avx512f-vfixupimmsd-2.c: Likewise.
+ * gcc.target/i386/avx512f-vfixupimmss-2.c: Likewise.
+ * gcc.target/i386/avx512f-vfixupimmss-2.c: Likewise.
+ * gcc.target/i386/avx-ceil-sfix-2-vec.c: Likewise. Drop
+ dg-skip-if "no M_PI".
+ * gcc.target/i386/avx-cvt-2-vec.c: Likewise.
+ * gcc.target/i386/avx-floor-sfix-2-vec.c: Likewise.
+ * gcc.target/i386/avx-rint-sfix-2-vec.c: Likewise.
+ * gcc.target/i386/avx-round-sfix-2-vec.c: Likewise.
+ * gcc.target/i386/avx512f-ceil-sfix-vec-1.c: Likewise.
+ * gcc.target/i386/avx512f-ceil-vec-1.c: Likewise.
+ * gcc.target/i386/avx512f-ceilf-sfix-vec-1.c: Likewise.
+ * gcc.target/i386/avx512f-ceilf-vec-1.c: Likewise.
+ * gcc.target/i386/avx512f-floor-sfix-vec-1.c: Likewise.
+ * gcc.target/i386/avx512f-floor-vec-1.c: Likewise.
+ * gcc.target/i386/avx512f-floorf-sfix-vec-1.c: Likewise.
+ * gcc.target/i386/avx512f-floorf-vec-1.c: Likewise.
+ * gcc.target/i386/avx512f-rint-sfix-vec-1.c: Likewise.
+ * gcc.target/i386/avx512f-rintf-sfix-vec-1.c: Likewise.
+ * gcc.target/i386/avx512f-round-sfix-vec-1.c: Likewise.
+ * gcc.target/i386/avx512f-roundf-sfix-vec-1.c: Likewise.
+ * gcc.target/i386/avx512f-trunc-vec-1.c: Likewise.
+ * gcc.target/i386/avx512f-truncf-vec-1.c: Likewise.
+ * gcc.target/i386/sse2-cvt-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-ceil-sfix-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-ceil-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-ceilf-sfix-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-ceilf-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-floor-sfix-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-floor-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-floorf-sfix-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-floorf-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-rint-sfix-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-rint-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-rintf-sfix-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-rintf-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-round-sfix-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-round-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-roundf-sfix-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-roundf-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-roundsd-4.c: Likewise.
+ * gcc.target/i386/sse4_1-roundss-4.c: Likewise.
+ * gcc.target/i386/sse4_1-trunc-vec.c: Likewise.
+ * gcc.target/i386/sse4_1-truncf-vec.c: Likewise.
+
+2019-08-06 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/91359
+ * gfortran.dg/pr91359_1.f: New test.
+ * gfortran.dg/pr91359_2.f: Ditto.
+
+2019-08-06 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/42546
+ * gfortran.dg/allocated_1.f90: New test.
+ * gfortran.dg/allocated_2.f90: Ditto.
+
+2019-08-06 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.target/i386/avx512vp2intersect-2intersect-1b.c (AVX512F):
+ Remove.
+ (AVX512VP2INTERSECT): Define.
+ * gcc.target/i386/avx512vp2intersect-2intersectvl-1b.c (AVX512F):
+ Remove.
+ (AVX512VP2INTERSECT): Define.
+
+2019-08-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * g++.dg/cpp0x/desig1.C: Check location too.
+
+2019-08-05 Marek Polacek <polacek@redhat.com>
+
+ DR 2413 - typename in conversion-function-ids.
+ * g++.dg/cpp2a/typename17.C: New test.
+
+2019-08-05 Martin Sebor <msebor@redhat.com>
+
+ PR middle-end/50476
+ * gcc.dg/uninit-pr50476.c: New test.
+
+ PR c++/60517
+ * g++.dg/pr60517.C: New test.
+
+2019-08-02 Tom Honermann <tom@honermann.net>
+
+ PR c++/88095
+ * g++.dg/cpp2a/udlit-class-nttp-ctad.C: New test.
+ * g++.dg/cpp2a/udlit-class-nttp-ctad-neg.C: New test.
+ * g++.dg/cpp2a/udlit-class-nttp-ctad-neg2.C: New test.
+ * g++.dg/cpp2a/udlit-class-nttp.C: New test.
+ * g++.dg/cpp2a/udlit-class-nttp-neg.C: New test.
+ * g++.dg/cpp2a/udlit-class-nttp-neg2.C: New test.
+
+2019-08-05 Steven g. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/91372
+ * gfortran.dg/pr91372.f90: New test.
+
+2019-08-05 Marek Polacek <polacek@redhat.com>
+
+ PR c++/91338 - Implement P1161R3: Deprecate a[b,c].
+ * g++.dg/cpp2a/comma1.C: New test.
+ * g++.dg/cpp2a/comma2.C: New test.
+ * g++.dg/cpp2a/comma3.C: New test.
+ * g++.dg/cpp2a/comma4.C: New test.
+
+2019-08-05 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.target/aarch64/sve/mask_load_1.c: New test.
+
+2019-08-05 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * gcc.target/msp430/pr80993.c: Add cleanup-saved-temps to final
+ actions.
+
+2019-08-05 Martin Liska <mliska@suse.cz>
+
+ PR c++/91334
+ * g++.dg/torture/pr91334.C: New test.
+
+2019-08-05 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/91169
+ * gnat.dg/array37.adb: New testcase.
+
+2019-08-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/91341
+ * gcc.target/i386/avx-loadu2-m128-1.c: New test.
+ * gcc.target/i386/avx-loadu2-m128-2.c: New test.
+ * gcc.target/i386/avx-loadu2-m128d-1.c: New test.
+ * gcc.target/i386/avx-loadu2-m128d-2.c: New test.
+ * gcc.target/i386/avx-loadu2-m128i-1.c: New test.
+ * gcc.target/i386/avx-loadu2-m128i-2.c: New test.
+ * gcc.target/i386/avx-storeu2-m128-1.c: New test.
+ * gcc.target/i386/avx-storeu2-m128-2.c: New test.
+ * gcc.target/i386/avx-storeu2-m128d-1.c: New test.
+ * gcc.target/i386/avx-storeu2-m128d-2.c: New test.
+ * gcc.target/i386/avx-storeu2-m128i-1.c: New test.
+ * gcc.target/i386/avx-storeu2-m128i-2.c: New test.
+
+2019-08-05 Kito Cheng <kito.cheng@sifive.com>
+
+ * gcc.target/riscv/promote-type-for-libcall.c: New.
+
+2019-08-02 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/90985
+ * gfortran.dg/pr90985.f90: New test.
+
+2019-08-02 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/90986
+ * gfortran.dg/equiv_10.f90: New test.
+
+2019-08-02 Marek Polacek <polacek@redhat.com>
+
+ PR c++/56428
+ * g++.dg/cpp0x/nontype4.C: New test.
+
+2019-08-02 Marek Polacek <polacek@redhat.com>
+
+ PR c++/53009
+ * g++.dg/cpp0x/nontype3.C: New test.
+
+2019-08-02 Marek Polacek <polacek@redhat.com>
+
+ PR c++/77575
+ * g++.dg/cpp0x/nontype2.C: New test.
+
+2019-08-02 Steve Ellcey <sellcey@marvell.com>
+
+ * gcc.target/aarch64/simd_pcs_attribute.c: New test.
+ * gcc.target/aarch64/simd_pcs_attribute-2.c: Ditto.
+ * gcc.target/aarch64/simd_pcs_attribute-3.c: Ditto.
+
+2019-08-02 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/91201
+ * gcc.target/i386/sse4_1-pr91201.c: New test.
+
+2019-08-02 Marek Polacek <polacek@redhat.com>
+
+ PR c++/91230 - wrong error with __PRETTY_FUNCTION__ and generic lambda.
+ * g++.dg/cpp1y/lambda-generic-pretty1.C: New test.
+
+2019-08-02 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/91323
+ * gcc.dg/torture/pr91323.c: New test.
+
+2019-08-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * g++.dg/cpp1z/nodiscard6.C: New.
+
+2019-08-02 Senthil Kumar Selvaraj <senthilkumar.selvaraj@microchip.com>
+
+ * gcc.dg/torture/ssa-fre-5.c: Add dg-require-effective-target int32.
+ * gcc.dg/torture/ssa-fre-7.c: Likewise.
+
+2019-08-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/91201
+ * gcc.target/i386/sse2-pr91201-3.c: New test.
+ * gcc.target/i386/sse2-pr91201-4.c: New test.
+ * gcc.target/i386/sse2-pr91201-5.c: New test.
+ * gcc.target/i386/sse2-pr91201-6.c: New test.
+
+2019-08-02 Martin Liska <mliska@suse.cz>
+
+ * g++.dg/cpp1y/new2.C: New test.
+
+2019-08-02 Senthil Kumar Selvaraj <senthilkumar.selvaraj@microchip.com>
+
+ * gcc.dg/torture/ssa-fre-6.c: Add dg-require-effective-target int32.
+
+2019-08-02 Kito Cheng <kito.cheng@sifive.com>
+
+ * g++.dg/lto/pr87906_0.C: Add dg-require-effective-target shared check.
+
+2019-08-01 Martin Sebor <msebor@redhat.com>
+
+ PR c++/90947
+ * c-c++-common/array-1.c: New test.
+ * g++.dg/abi/mangle73.C: New test.
+ * g++.dg/cpp2a/nontype-class23.C: New test.
+ * g++.dg/init/array53.C: New test.
+
+2019-08-01 Uroš Bizjak <ubizjak@gmail.com>
+
+ PR target/85693
+ * gcc.target/i386/pr85693-1.c: New test.
+
+2019-08-01 Matthew Beliveau <mbelivea@redhat.com>
+
+ PR c++/90590
+ * c-c++-common/pr90590-1.c: New test.
+ * c-c++-common/pr90590-1.h: New test.
+ * c-c++-common/pr90590-2.c: New test.
+ * c-c++-common/pr90590-2.h: New test.
+
+2019-08-01 Marek Polacek <polacek@redhat.com>
+
+ PR c++/90805 - detect narrowing in case values.
+ * c-c++-common/pr89888.c: Update expected dg-error.
+ * g++.dg/cpp0x/Wnarrowing17.C: New test.
+ * g++.dg/cpp0x/enum28.C: Update expected dg-error.
+
+2019-08-01 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * g++.dg/lto/pr89330_0.C: Add effective-target shared.
+
+2019-08-01 Kito Cheng <kito.cheng@sifive.com>
+
+ * gcc.target/riscv/attribute-10.c: Fix testcase on rv64.
+
+2019-07-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * g++.dg/diagnostic/delete1.C: New.
+
+2019-07-31 Maxim Blinov <maxim.blinov@embecosm.com>
+
+ * gcc.target/riscv/attribute-10.c: New test.
+
+2019-07-31 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91280
+ * g++.dg/torture/pr91280.C: New testcase.
+
+2019-07-31 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91293
+ * gcc.dg/vect/pr91293-1.c: New testcase.
+ * gcc.dg/vect/pr91293-2.c: Likewise.
+ * gcc.dg/vect/pr91293-3.c: Likewise.
+
+2019-07-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/91201
+ * gcc.target/i386/sse2-pr91201-2.c: New test.
+
+2019-07-31 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91178
+ * gcc.dg/torture/pr91178-2.c: New testcase.
+
+2019-07-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/91201
+ * gcc.target/i386/sse2-pr91201.c: New test.
+ * gcc.target/i386/avx2-pr91201.c: New test.
+ * gcc.target/i386/avx512bw-pr91201.c: New test.
+
+2019-07-31 Sudakshina Das <sudi.das@arm.com>
+
+ * gcc.target/aarch64/acle/tme.c: New test.
+ * gcc.target/aarch64/pragma_cpp_predefs_2.c: New test.
+
+2019-07-31 Joel Hutton <Joel.Hutton@arm.com>
+
+ * gcc.target/arm/cmse/cmse-17.c: New test.
+
+2019-07-30 Martin Sebor <msebor@redhat.com>
+
+ PR testsuite/91258
+ * g++.dg/ubsan/vla-1.C: Suppress a valid warning.
+
+2019-07-30 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/91296
+ * gfortran.dg/pr91296.f90: New test.
+
+2019-07-30 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/91270
+ * g++.dg/torture/pr91270.C: New test.
+
+2019-07-30 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/vect/vect-cond-arith-7.c: New test.
+
+2019-07-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/91282
+ * gcc.dg/type-convert-var.c: Add -fexcess-precision=fast to
+ dg-additional-options.
+
+ PR middle-end/91216
+ * gcc.dg/gomp/pr91216.c: New test.
+
+ PR target/91150
+ * gcc.target/i386/avx512bw-pr91150.c: New test.
+
+2019-07-29 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * gcc.target/msp430/pr78818-data-region.c: Add -mlarge to dg-options.
+ * gcc.target/msp430/region-misuse-code.c: New test.
+ * gcc.target/msp430/region-misuse-data.c: Likewise.
+ * gcc.target/msp430/region-misuse-code-data.c: Likewise.
+ * gcc.target/msp430/region-attribute-misuse.c: Likewise.
+
+2019-07-29 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ PR target/70320
+ * gcc.target/msp430/asm-register-names-lower-case.c: New test.
+ * gcc.target/msp430/asm-register-names-upper-case.c: Likewise.
+
+2019-07-29 Martin Liska <mliska@suse.cz>
+
+ * g++.dg/cpp1y/new1.C (test_unused): Add new case that causes
+ ICE.
+
+2019-07-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/91267
+ * gcc.dg/torture/pr91267.c: New testcase.
+
+2019-07-29 Richard Sandiford <richard.sandiford@arm.com>
+
+ * c-c++-common/guality/Og-dce-1.c: New test.
+ * c-c++-common/guality/Og-dce-2.c: Likewise.
+ * c-c++-common/guality/Og-dce-3.c: Likewise.
+
+2019-07-29 Richard Sandiford <richard.sandiford@arm.com>
+
+ * c-c++-common/guality/Og-global-dse-1.c: New test.
+
+2019-07-29 Richard Sandiford <richard.sandiford@arm.com>
+
+ * c-c++-common/guality/Og-static-wo-1.c: New test.
+ * g++.dg/guality/guality.exp: Separate the c-c++-common tests into
+ "Og" and "general" tests. Run the latter at -O0 and -Og only.
+ * gcc.dg/guality/guality.exp: Likewise.
+
+2019-07-29 Richard Sandiford <richard.sandiford@arm.com>
+
+ * lib/scanasm.exp (parse_function_bodies, check_function_body)
+ (check-function-bodies): New procedures.
+ * gcc.target/aarch64/sve/init_1.c: Use check-function-bodies
+ instead of scan-assembler.
+ * gcc.target/aarch64/sve/init_2.c: Likewise.
+ * gcc.target/aarch64/sve/init_3.c: Likewise.
+ * gcc.target/aarch64/sve/init_4.c: Likewise.
+ * gcc.target/aarch64/sve/init_5.c: Likewise.
+ * gcc.target/aarch64/sve/init_6.c: Likewise.
+ * gcc.target/aarch64/sve/init_7.c: Likewise.
+ * gcc.target/aarch64/sve/init_8.c: Likewise.
+ * gcc.target/aarch64/sve/init_9.c: Likewise.
+ * gcc.target/aarch64/sve/init_10.c: Likewise.
+ * gcc.target/aarch64/sve/init_11.c: Likewise.
+ * gcc.target/aarch64/sve/init_12.c: Likewise.
+
+2019-07-28 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * g++.dg/lto/pr89330_0.C (dg-lto-options): Add -fPIC.
+ Require fpic support.
+
+2019-07-27 Iain Sandoe <iain@sandoe.co.uk>
+
+ * gcc.target/powerpc/bmi2-bzhi64-1a.c: Add options to enable altivec
+ and vsx.
+
+2019-07-26 Iain Sandoe <iain@sandoe.co.uk>
+
+ * lib/scanasm.exp (object-size): Handle Darwin's size command.
+
+2018-07-26 Tamar Christina <tamar.christina@arm.com>
+
+ * gcc.dg/type-convert-var.c: New test.
+
+2019-07-26 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/89330
+ * g++.dg/lto/pr89330_[01].C: New test.
+ * g++.dg/tree-prof/devirt.C: Added -fno-profile-values to dg-options.
+
+2019-07-25 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/91183
+ PR tree-optimization/86688
+ * gcc.dg/Wstringop-overflow-14.c: Disable for stricly aligned targets.
+ * gcc.dg/strlenopt-70.c: Fix bugs.
+ * gcc.dg/strlenopt-71.c: Same.
+ * gcc.dg/strlenopt-72.c: Same.
+
+2019-07-25 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/91223
+ * gcc.target/i386/pr91223.c: New test.
+
+2019-07-25 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR gcov-profile/91087
+ * g++.dg/gcov/pr16855.C: Xfail the count lines for the DTORs and the
+ "final" line for the failure summaries. Adjust source layout so that
+ dejagnu xfail expressions work.
+
+2019-07-25 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/65819
+ * gfortran.dg/dependency_54.f90: New test.
+
+2019-07-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/case_optimization3.ad[sb]: New test.
+
+2019-07-25 Martin Liska <mliska@suse.cz>
+ Dominik Infuhr <dominik.infuehr@theobroma-systems.com>
+
+ PR c++/23383
+ * g++.dg/cpp1y/new1.C: New test.
+
+2019-07-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR testsuite/91245
+ * gnat.dg/float_value1.adb: Only run on x86.
+
+2019-07-24 Martin Sebor <msebor@redhat.com>
+
+ PR tree-optimization/91183
+ PR tree-optimization/86688
+ * c-c++-common/ubsan/object-size-9.c: Disable warnings.
+ * gcc.dg/Wstringop-overflow-14.c: New test.
+ * gcc.dg/attr-nonstring-2.c: Remove xfails.
+ * gcc.dg/strlenopt-70.c: New test.
+ * gcc.dg/strlenopt-71.c: New test.
+ * gcc.dg/strlenopt-72.c: New test.
+ * gcc.dg/strlenopt-8.c: Remove xfails.
+
+2019-07-24 Martin Sebor <msebor@redhat.com>
+
+ PR driver/80545
+ * gcc.misc-tests/help.exp: Add tests.
+ * lib/options.exp: Handle C++.
+
+2019-07-24 Claudiu Zissulescu <claziss@synopsys.com>
+
+ * gcc.target/arc/arc.exp (check_effective_target_accregs): New
+ predicate.
+ * gcc.target/arc/builtin_special.c: Update test/
+ * gcc.target/arc/interrupt-1.c: Likewise.
+ * gcc.target/arc/interrupt-10.c: New test.
+ * gcc.target/arc/interrupt-11.c: Likewise.
+ * gcc.target/arc/interrupt-12.c: Likewise.
+
+2019-07-24 Andreas Krebbel <krebbel@linux.ibm.com>
+
+ * gcc.target/s390/addsub-signed-overflow-1.c: New test.
+ * gcc.target/s390/addsub-signed-overflow-2.c: New test.
+ * gcc.target/s390/mul-signed-overflow-1.c: New test.
+ * gcc.target/s390/mul-signed-overflow-2.c: New test.
+
+2019-07-24 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ PR middle-end/91166
+ * gcc.target/aarch64/sve/pr91166.c: New test.
+
+2019-07-23 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ PR fortran/54072
+ * gfortran.dg/illegal_boz_arg_1.f90: New tests.
+
+2019-07-23 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ * gfortran.dg/achar_5.f90: Fix for new BOZ handling.
+ * arithmetic_overflow_1.f90: Ditto.
+ * gfortran.dg/boz_11.f90: Ditto.
+ * gfortran.dg/boz_12.f90: Ditto.
+ * gfortran.dg/boz_4.f90: Ditto.
+ * gfortran.dg/boz_5.f90: Ditto.
+ * gfortran.dg/boz_6.f90: Ditto.
+ * gfortran.dg/boz_7.f90: Ditto.
+ * gfortran.dg/boz_8.f90: Ditto.
+ * gfortran.dg/dec_structure_6.f90: Ditto.
+ * gfortran.dg/dec_union_1.f90: Ditto.
+ * gfortran.dg/dec_union_2.f90: Ditto.
+ * gfortran.dg/dec_union_5.f90: Ditto.
+ * gfortran.dg/dshift_3.f90: Ditto.
+ * gfortran.dg/gnu_logical_2.f90: Ditto.
+ * gfortran.dg/int_conv_1.f90: Ditto.
+ * gfortran.dg/ishft_1.f90: Ditto.
+ * gfortran.dg/nan_4.f90: Ditto.
+ * gfortran.dg/no_range_check_3.f90: Ditto.
+ * gfortran.dg/pr16433.f: Ditto.
+ * gfortran.dg/pr44491.f90: Ditto.
+ * gfortran.dg/pr58027.f90: Ditto.
+ * gfortran.dg/pr81509_2.f90: Ditto.
+ * gfortran.dg/unf_io_convert_1.f90: Ditto.
+ * gfortran.dg/unf_io_convert_2.f90: Ditto.
+ * gfortran.fortran-torture/execute/intrinsic_fraction_exponent.f90:
+ Ditto.
+ * gfortran.fortran-torture/execute/intrinsic_mvbits.f90: Ditto.
+ * gfortran.fortran-torture/execute/intrinsic_nearest.f90: Ditto.
+ * gfortran.fortran-torture/execute/seq_io.f90: Ditto.
+ * gfortran.dg/gnu_logical_1.F: Delete test.
+ * gfortran.dg/merge_bits_3.f90: New test.
+ * gfortran.dg/merge_bits_3.f90: Ditto.
+ * gfortran.dg/boz_int.f90: Ditto.
+ * gfortran.dg/boz_bge.f90: Ditto.
+ * gfortran.dg/boz_complex_1.f90: Ditto.
+ * gfortran.dg/boz_complex_2.f90: Ditto.
+ * gfortran.dg/boz_complex_3.f90: Ditto.
+ * gfortran.dg/boz_dble.f90: Ditto.
+ * gfortran.dg/boz_dshift_1.f90: Ditto.
+ * gfortran.dg/boz_dshift_2.f90: Ditto.
+ * gfortran.dg/boz_float_1.f90: Ditto.
+ * gfortran.dg/boz_float_2.f90: Ditto.
+ * gfortran.dg/boz_float_3.f90: Ditto.
+ * gfortran.dg/boz_iand_1.f90: Ditto.
+ * gfortran.dg/boz_iand_2.f90: Ditto.
+
+2019-07-23 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/86061
+ * gcc.dg/tree-ssa/pr86061.c: New test.
+
2019-07-23 Richard Biener <rguenther@suse.de>
PR tree-optimization/83518
@@ -33,7 +1682,7 @@
* gcc.target/msp430/isr-push-pop-leaf-isr-430.c: Likewise.
* gcc.target/msp430/isr-push-pop-leaf-isr-430x.c: Likewise.
-2019-07-22 Andrea Corallo <andrea.corallo@arm.com>
+2019-07-22 Andrea Corallo <andrea.corallo@arm.com>
* jit.dg/test-error-gcc_jit_context_new_unary_op-bad-res-type.c:
New testcase.
@@ -176,6 +1825,7 @@
2019-07-19 Jeff Law <law@redhat.com>
+ PR tree-optimization/86061
* gcc.dg/tree-ssa/ssa-dse-37.c: New test.
* gcc.dg/tree-ssa/ssa-dse-38.c: New test.
@@ -211,19 +1861,19 @@
2019-07-18 Sylvia Taylor <sylvia.taylor@arm.com>
- PR target/90317
- * gcc.target/arm/crypto-vsha1cq_u32.c (foo): Change return type to
- uint32_t.
- (GET_LANE, TEST_SHA1C_VEC_SELECT): New.
- * gcc.target/arm/crypto-vsha1h_u32.c (foo): Change return type to
- uint32_t.
- (GET_LANE, TEST_SHA1H_VEC_SELECT): New.
- * gcc.target/arm/crypto-vsha1mq_u32.c (foo): Change return type to
- uint32_t.
- (GET_LANE, TEST_SHA1M_VEC_SELECT): New.
- * gcc.target/arm/crypto-vsha1pq_u32.c (foo): Change return type to
- uint32_t.
- (GET_LANE, TEST_SHA1P_VEC_SELECT): New.
+ PR target/90317
+ * gcc.target/arm/crypto-vsha1cq_u32.c (foo): Change return type to
+ uint32_t.
+ (GET_LANE, TEST_SHA1C_VEC_SELECT): New.
+ * gcc.target/arm/crypto-vsha1h_u32.c (foo): Change return type to
+ uint32_t.
+ (GET_LANE, TEST_SHA1H_VEC_SELECT): New.
+ * gcc.target/arm/crypto-vsha1mq_u32.c (foo): Change return type to
+ uint32_t.
+ (GET_LANE, TEST_SHA1M_VEC_SELECT): New.
+ * gcc.target/arm/crypto-vsha1pq_u32.c (foo): Change return type to
+ uint32_t.
+ (GET_LANE, TEST_SHA1P_VEC_SELECT): New.
2019-07-18 Jan Hubicka <hubicka@ucw.cz>
@@ -231,7 +1881,7 @@
* g++.dg/lto/alias-5_1.C: New.
* g++.dg/lto/alias-5_2.c: New.
-2019-07-18 Bin Cheng <bin.linux@linux.alibaba.com>
+2019-07-18 Bin Cheng <bin.cheng@linux.alibaba.com>
PR tree-optimization/91137
* gcc.c-torture/execute/pr91137.c: New test.
@@ -240,7 +1890,7 @@
* c-c++-common/pr53633-2.c: New test.
-2019-07-17 Alexandre Oliva <oliva@adacore.com>
+2019-07-17 Alexandre Oliva <oliva@adacore.com>
PR middle-end/81824
* g++.dg/Wmissing-attributes-1.C: New. Some of its fragments
@@ -470,7 +2120,7 @@
PR tree-optimization/91145
* gcc.dg/torture/pr91145.c: New testcase.
-2019-07-12 Alexandre Oliva <oliva@adacore.com>
+2019-07-12 Alexandre Oliva <oliva@adacore.com>
* gcc.dg/gimplefe-44.c: New.
* gcc.dg/gimplefe-43.c: New.
@@ -720,6 +2370,11 @@
* gcc.target/s390/combine-shift-rotate-add-mod.c: New test.
* gcc.target/s390/vector/combine-shift-vec.c: New test.
+2019-07-08 Joern Rennecke <joern.rennecke@riscy-ip.com>
+
+ Avoid clash with system header declaration.
+ * gcc.dg/vect/slp-reduc-sad.c (uint32_t): Remove unused declaration.
+
2019-07-08 Richard Biener <rguenther@suse.de>
PR tree-optimization/91108
@@ -862,7 +2517,7 @@
PR middle-end/78884
* gcc.dg/gomp/pr78884.c: New test.
-2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
+2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
* jit.dg/test-error-gcc_jit_context_new_binary_op-bad-res-type.c:
New testcase.
@@ -871,7 +2526,7 @@
* gcc.dg/tree-ssa/cunroll-15.c: Remove XFAIL on arm.
-2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
+2019-07-04 Andrea Corallo <andrea.corallo@arm.com>
* jit.dg/all-non-failing-tests.h: Add test-accessing-bitfield.c.
* jit.dg/test-accessing-bitfield.c: New testcase.
@@ -978,6 +2633,11 @@
* gcc.dg/store_merging_29.c: Likewise.
* gcc.dg/tree-ssa/dump-6.c: Likewise.
+2019-07-03 Mark Wielaard <mark@klomp.org>
+
+ PR debug/90981
+ * g++.dg/pr90981.C: New test.
+
2019-07-03 Richard Biener <rguenther@suse.de>
PR middle-end/91069
@@ -1066,6 +2726,12 @@
* g++.dg/tree-ssa/pr90883.c: Add -Os. Check dse2 for the
deleted store on some targets.
+2019-07-02 Joern Rennecke <joern.rennecke@riscy-ip.com>
+
+ PR testsuite/91065
+ * gcc.dg/plugin/start_unit_plugin.c: Register a root tab
+ to reference fake_var.
+
2019-07-02 qing zhao <qing.zhao@oracle.com>
PR preprocessor/90581
@@ -1086,6 +2752,11 @@
PR tree-optimization/58483
* gcc.dg/tree-ssa/ssa-dom-cse-8.c: New testcase.
+2019-07-01 Joern Rennecke <joern.rennecke@riscy-ip.com>
+
+ PR middle-end/66726
+ * gcc.dg/tree-ssa/pr66726-4.c: New testcase.
+
2019-07-01 Andreas Krebbel <krebbel@linux.ibm.com>
* gcc.target/s390/vector/vec-shift-2.c: New test.
@@ -1904,7 +3575,7 @@
PR objc/90709
* obj-c++.dg/proto-lossage-7.mm: Use proxy headers.
* obj-c++.dg/strings/const-cfstring-2.mm: Likewise.
- * obj-c++.dg/strings/const-cfstring-5.mm: Likewise
+ * obj-c++.dg/strings/const-cfstring-5.mm: Likewise.
* obj-c++.dg/strings/const-str-12.mm: Likewise.
* obj-c++.dg/syntax-error-1.mm: Likewise.
* obj-c++.dg/torture/strings/const-cfstring-1.mm: Likewise.
@@ -2479,7 +4150,7 @@
* lib/scanasm.exp (dg-function-on-line): Add pattern for hppa*-*-linux*.
-2019-06-07 Mark Eggleston <mark.eggleston@codethink.com>
+2019-06-07 Mark Eggleston <mark.eggleston@codethink.com>
PR fortran/89100
* gfortran.dg/fmt_f_default_field_width_3.f90: Modify dg-error
@@ -2984,7 +4655,7 @@
2019-05-28 Jeff Law <law@redhat.com>
- * testsuite/gcc.target/sh/pr50749-qihisi-predec-3.c: Disable
+ * gcc.target/sh/pr50749-qihisi-predec-3.c: Disable
loop distribution.
2019-05-28 Segher Boessenkool <segher@kernel.crashing.org>
@@ -3148,18 +4819,18 @@
* lib/target-supports.exp (check_effective_target_mfentry): New.
* gcc.target/i386/fentry-override.c: Require effective target mfentry.
- * gcc/testsuite/gcc.target/i386/fentry.c: Likewise
- * gcc.target/i386/fentryname1.c: Likewise
- * gcc.target/i386/fentryname2.c: Likewise
- * gcc.target/i386/fentryname3.c: Likewise
- * gcc.target/i386/nop-mcount.c: Likewise
- * gcc.target/i386/pr82699-2.c: Likewise
- * gcc.target/i386/pr82699-4.c: Likewise
- * gcc.target/i386/pr82699-5.c: Likewise
- * gcc.target/i386/pr82699-6.c: Likewise
- * gcc.target/i386/returninst1.c: Likewise
- * gcc.target/i386/returninst2.c: Likewise
- * gcc.target/i386/returninst3.c : Likewise
+ * gcc.target/i386/fentry.c: Likewise.
+ * gcc.target/i386/fentryname1.c: Likewise.
+ * gcc.target/i386/fentryname2.c: Likewise.
+ * gcc.target/i386/fentryname3.c: Likewise.
+ * gcc.target/i386/nop-mcount.c: Likewise.
+ * gcc.target/i386/pr82699-2.c: Likewise.
+ * gcc.target/i386/pr82699-4.c: Likewise.
+ * gcc.target/i386/pr82699-5.c: Likewise.
+ * gcc.target/i386/pr82699-6.c: Likewise.
+ * gcc.target/i386/returninst1.c: Likewise.
+ * gcc.target/i386/returninst2.c: Likewise.
+ * gcc.target/i386/returninst3.c : Likewise.
2019-05-23 Bill Schmidt <wschmidt@linux.ibm.com>
@@ -3321,6 +4992,15 @@
* gcc.dg/tree-ssa/ssa-lim-13.c: New testcase.
+2019-05-22 Alan Modra <amodra@gmail.com>
+
+ * gcc.target/powerpc/ppc32-abi-dfp-1.c: Don't use
+ power mnemonics.
+ * gcc.dg/vect/O3-pr70130.c: Disable default options
+ added by check_vect_support_and_set_flags.
+ * gcc.dg/vect/pr48765.c: Likewise.
+ * gfortran.dg/vect/pr45714-b.f: Likewise.
+
2019-05-22 Hans-Peter Nilsson <hp@axis.com>
PR middle-end/90553
@@ -3390,6 +5070,12 @@
* g++.dg/lookup/using53.C: Adjust diagnostic.
+2019-05-21 Alan Modra <amodra@gmail.com>
+
+ PR target/90545
+ * gcc.target/powerpc/fold-vec-splats-floatdouble.c: Correct comments
+ and rename functions to suit parameters.
+
2019-05-21 Richard Biener <rguenther@suse.de>
PR middle-end/90510
@@ -3778,7 +5464,7 @@
* lib/target-supports.exp (check_effective_target_cet): Add the
-fcf-protection flag to the build conditions.
-2019-05-16 Jun Ma <JunMa@linux.alibaba.com>
+2019-05-16 Jun Ma <JunMa@linux.alibaba.com>
PR tree-optimization/90106
* gcc.dg/cdce1.c: Check tailcall code generation after cdce pass.
@@ -4032,7 +5718,7 @@
param.
2019-05-14 Richard Biener <rguenther@suse.de>
- H.J. Lu <hongjiu.lu@intel.com>
+ H.J. Lu <hongjiu.lu@intel.com>
PR tree-optimization/88828
* gcc.target/i386/pr88828-1.c: New test.
@@ -4403,7 +6089,7 @@
systems.
* gcc.dg/tsan/pr88017.c: Likewise.
-2019-05-05 Thomas Koenig <tkoenig@gcc.gnu.org>
+2019-05-05 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/90344
* gfortran.dg/pr90344.f90: New test
@@ -4495,7 +6181,7 @@
PR fortran/60144
* gfortran.dg/block_name_2.f90: Adjust dg-error.
- * gfortran.dg/dec_type_print_3.f90.f90: Likewise
+ * gfortran.dg/dec_type_print_3.f90.f90: Likewise.
* gfortran.dg/pr60144.f90: New test.
2019-05-01 Jeff Law <law@redhat.com>
@@ -4539,7 +6225,7 @@
2019-04-23 Bin Cheng <bin.cheng@linux.alibaba.com>
PR tree-optimization/90078
- * gcc/testsuite/g++.dg/tree-ssa/pr90078.C: New test.
+ * g++.dg/tree-ssa/pr90078.C: New test.
2019-04-29 Vladislav Ivanishin <vlad@ispras.ru>
@@ -4811,7 +6497,7 @@
* g++.dg/lto/pr89358_0.C: Replace dg-* with dg-lto-*.
-2019-04-16 Alexandre Oliva <aoliva@redhat.com>
+2019-04-16 Alexandre Oliva <aoliva@redhat.com>
PR debug/89528
* gcc.dg/guality/pr89528.c: New.
@@ -5121,15 +6807,15 @@
PR c++/89878
PR c++/89833
PR c++/47488
- * gcc/testsuite/g++.dg/abi/mangle69.C: New test.
- * gcc/testsuite/g++.dg/abi/mangle70.C: New test.
- * gcc/testsuite/g++.dg/abi/mangle71.C: New test.
- * gcc/testsuite/g++.dg/abi/mangle72.C: New test.
- * gcc/testsuite/g++.dg/cpp0x/constexpr-array19.C: New test.
- * gcc/testsuite/g++.dg/cpp2a/nontype-class15.C: New test.
- * gcc/testsuite/g++.dg/cpp2a/nontype-class16.C: New test.
- * gcc/testsuite/g++.dg/init/array51.C: New test.
- * gcc/testsuite/g++.dg/template/nontype29.C: New test.
+ * g++.dg/abi/mangle69.C: New test.
+ * g++.dg/abi/mangle70.C: New test.
+ * g++.dg/abi/mangle71.C: New test.
+ * g++.dg/abi/mangle72.C: New test.
+ * g++.dg/cpp0x/constexpr-array19.C: New test.
+ * g++.dg/cpp2a/nontype-class15.C: New test.
+ * g++.dg/cpp2a/nontype-class16.C: New test.
+ * g++.dg/init/array51.C: New test.
+ * g++.dg/template/nontype29.C: New test.
2019-04-04 Martin Sebor <msebor@redhat.com>
@@ -5562,7 +7248,7 @@
PR c/89812
* gcc.dg/attr-aligned-3.c: New test.
-2019-03-25 Johan Karlsson <johan.karlsson@enea.com>
+2019-03-25 Johan Karlsson <johan.karlsson@enea.com>
PR debug/86964
* gcc.dg/debug/dwarf2/pr86964.c: New testcase.
@@ -6029,7 +7715,7 @@
* gcc.target/powerpc/vsx-builtin-9a.c: New test.
* gcc.target/powerpc/vsx-builtin-9b.c: New test.
-2019-03-15 Alexandre Oliva <aoliva@redhat.com>
+2019-03-15 Alexandre Oliva <aoliva@redhat.com>
PR c++/88534
PR c++/88537
@@ -6655,7 +8341,7 @@
2018-03-04 Bin Cheng <bin.cheng@linux.alibaba.com>
PR tree-optimization/89487
- * gcc/testsuite/gcc.dg/tree-ssa/pr89487.c: New test.
+ * gcc.dg/tree-ssa/pr89487.c: New test.
2019-03-03 Harald Anlauf <anlauf@gmx.de>
@@ -7053,7 +8739,7 @@
* gcc.dg/pr69471-2.c: Likewise.
* gcc.target/i386/pr69471-3.c: Likewise.
-2019-02-23 Jerry DeLisle <jvdelisle@gcc.gnu.org>
+2019-02-23 Jerry DeLisle <jvdelisle@gcc.gnu.org>
PR fortran/84387
* gfortran.dg/dtio_34.f90: New test.
@@ -7239,7 +8925,7 @@
* gcc.dg/vect/slp-reduc-sad.c: Update scan string.
* gcc.dg/vect/vect-reduc-sad.c: Likewise.
-2019-02-20 Andre Vieira <andre.simoesdiasvieira@arm.com>
+2019-02-20 Andre Vieira <andre.simoesdiasvieira@arm.com>
PR target/86487
* gcc.target/arm/pr86487.c: New.
@@ -7252,7 +8938,7 @@
2019-02-20 Li Jia He <helijia@linux.ibm.com>
PR target/88100
- * gcc/testsuite/gcc.target/powerpc/pr88100.c: New testcase.
+ * gcc.target/powerpc/pr88100.c: New testcase.
2019-02-19 Wilco Dijkstra <wdijkstr@arm.com>
@@ -7536,7 +9222,7 @@
PR c++/89297 - ICE with OVERLOAD in template.
* g++.dg/cpp0x/initlist113.C: New test.
-2019-02-13 Alexandre Oliva <aoliva@redhat.com>
+2019-02-13 Alexandre Oliva <aoliva@redhat.com>
PR c++/86379
* g++.dg/cpp0x/pr86379.C: New.
@@ -7811,7 +9497,7 @@
PR/target 88850
* gcc.target/arm/pr88850.c: New test.
-2019-02-07 Alexandre Oliva <aoliva@redhat.com>
+2019-02-07 Alexandre Oliva <aoliva@redhat.com>
PR c++/86218
* g++.dg/cpp0x/pr86218.C: New.
@@ -7939,7 +9625,7 @@
PR target/89186
* g++.dg/ext/vector36.C: New test.
-2019-02-05 Alexandre Oliva <aoliva@redhat.com>
+2019-02-05 Alexandre Oliva <aoliva@redhat.com>
PR c++/87770
* g++.dg/pr87770.C: New.
@@ -8572,7 +10258,7 @@
* gfortran.dg/pr77960.f90: New test.
2018-01-19 Thomas Koenig <tkoenig@gcc.gnu.org>
- Paul Thomas <pault@gcc.gnu.org>
+ Paul Thomas <pault@gcc.gnu.org>
PR fortran/56789
* gfortran.dg/contiguous_3.f90: Make code compilant. Remove
@@ -8914,7 +10600,7 @@
* gcc.target/powerpc/altivec_vld_vst_addr.c: New test.
-2019-01-17 Alexandre Oliva <aoliva@redhat.com>
+2019-01-17 Alexandre Oliva <aoliva@redhat.com>
PR c++/87768
* g++.dg/concepts/pr87768.C: New.
@@ -9440,8 +11126,8 @@
* g++.dg/diagnostic/thread1.C: Likewise.
2019-01-07 Thomas Koenig <tkoenig@gcc.gnu.org>
- Harald Anlauf <anlauf@gmx.de>
- Tobias Burnus <burnus@gcc.gnu.org>
+ Harald Anlauf <anlauf@gmx.de>
+ Tobias Burnus <burnus@gcc.gnu.org>
* gfortran.dg/is_contiguous_1.f90: New test.
* gfortran.dg/is_contiguous_2.f90: New test.
diff --git a/gcc/testsuite/ChangeLog-2018 b/gcc/testsuite/ChangeLog-2018
index 1d5d430..d4001b4 100644
--- a/gcc/testsuite/ChangeLog-2018
+++ b/gcc/testsuite/ChangeLog-2018
@@ -107,9 +107,9 @@
* gfortran.dg/ieee/ieee_9.f90: XFAIL on arm*-*-gnueabi[hf].
2018-12-24 Jan Hubicka <hubicka@ucw.cz>
-
+
PR lto/88140
- * gcc.c-torture/pr88140.c: New testcase.
+ * gcc.c-torture/compile/pr88140.c: New testcase.
2018-12-24 Iain Sandoe <iain@sandoe.co.uk>
diff --git a/gcc/testsuite/c-c++-common/array-1.c b/gcc/testsuite/c-c++-common/array-1.c
new file mode 100644
index 0000000..5de9ade
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/array-1.c
@@ -0,0 +1,247 @@
+// PR c++/90947 - Simple lookup table of array of strings is miscompiled
+// { dg-do compile }
+// { dg-options "-O1 -fdump-tree-optimized" }
+
+#define assert(expr) ((expr) ? (void)0 : __builtin_abort ())
+
+void pr90947 (void)
+{
+ int vecsize = 4;
+ int index = 0;
+ static const char *a[4][4] =
+ {
+ { ".x", ".y", ".z", ".w" },
+ { ".xy", ".yz", ".zw", 0 },
+ { ".xyz", ".yzw", 0, 0 },
+ { "", 0, 0, 0 },
+ };
+
+ assert (vecsize >= 1 && vecsize <= 4);
+ assert (index >= 0 && index < 4);
+ assert (a[vecsize - 1][index]);
+}
+
+void f_a1_1 (void)
+{
+ {
+ const char* a[1][1] = { { 0 } };
+ assert (0 == a[0][0]);
+ }
+ {
+ const char* a[1][1] = { { "" } };
+ assert ('\0' == *a[0][0]);
+ }
+}
+
+void f_a2_1 (void)
+{
+ {
+ const char* a[2][1] = { { "" }, { "" } };
+ assert ('\0' == *a[0][0] && '\0' == *a[1][0]);
+ }
+ {
+ const char* a[2][1] = { { 0 }, { "" } };
+ assert (0 == a[0][0] && '\0' == *a[1][0]);
+ }
+ {
+ const char* a[2][1] = { { }, { "" } };
+ assert (0 == a[0][0] && '\0' == *a[1][0]);
+ }
+}
+
+void f_a2_2 (void)
+{
+ {
+ const char* a[2][2] = { { "", "" }, { "", "" } };
+ assert ('\0' == *a[0][0] && '\0' == *a[0][1]);
+ assert ('\0' == *a[1][0] && '\0' == *a[1][1]);
+ }
+ {
+ const char* a[2][2] = { { "", "" }, { "", 0 } };
+ assert ('\0' == *a[0][0] && '\0' == *a[0][1]);
+ assert ('\0' == *a[1][0] && 0 == a[1][1]);
+ }
+ {
+ const char* a[2][2] = { { "", "" }, { "" } };
+ assert ('\0' == *a[0][0] && '\0' == *a[0][1]);
+ assert ('\0' == *a[1][0] && 0 == a[1][1]);
+ }
+ {
+ const char* a[2][2] = { { "", "" }, { 0, "" } };
+ assert ('\0' == *a[0][0] && '\0' == *a[0][1]);
+ assert (0 == a[1][0] && '\0' == *a[1][1]);
+ }
+ {
+ const char* a[2][2] = { { "", 0 }, { 0, "" } };
+ assert ('\0' == *a[0][0] && 0 == a[0][1]);
+ assert (0 == a[1][0] && '\0' == *a[1][1]);
+ }
+ {
+ const char* a[2][2] = { { 0, 0 }, { 0, "" } };
+ assert (0 == a[0][0] && 0 == a[0][1]);
+ assert (0 == a[1][0] && '\0' == *a[1][1]);
+ }
+ {
+ const char* a[2][2] = { { 0 }, { 0, "" } };
+ assert (0 == a[0][0] && 0 == a[0][1]);
+ assert (0 == a[1][0] && '\0' == *a[1][1]);
+ }
+ {
+ const char* a[2][2] = { { }, { 0, "" } };
+ assert (0 == a[0][0] && 0 == a[0][1]);
+ assert (0 == a[1][0] && '\0' == *a[1][1]);
+ }
+}
+
+void f_a2_2_2 (void)
+{
+ {
+ const char* a[2][2][2] =
+ { { { "", "" }, { "", "" } }, { { "", "" }, { "", "" } } };
+
+ assert ('\0' == *a[0][0][0] && '\0' == *a[0][0][1]);
+ assert ('\0' == *a[0][1][0] && '\0' == *a[0][1][1]);
+ assert ('\0' == *a[1][0][0] && '\0' == *a[1][0][1]);
+ assert ('\0' == *a[1][1][0] && '\0' == *a[1][1][1]);
+ }
+
+ {
+ const char* a[2][2][2] =
+ { { { "", "" }, { "", "" } }, { { "", "" }, { 0, "" } } };
+
+ assert ('\0' == *a[0][0][0] && '\0' == *a[0][0][1]);
+ assert ('\0' == *a[0][1][0] && '\0' == *a[0][1][1]);
+ assert ('\0' == *a[1][0][0] && '\0' == *a[1][0][1]);
+ assert (0 == a[1][1][0] && '\0' == *a[1][1][1]);
+ }
+
+ {
+ const char* a[2][2][2] =
+ { { { "", "" }, { "", "" } }, { { 0, 0 }, { 0, "" } } };
+
+ assert ('\0' == *a[0][0][0] && '\0' == *a[0][0][1]);
+ assert ('\0' == *a[0][1][0] && '\0' == *a[0][1][1]);
+ assert (0 == a[1][0][0] && 0 == a[1][0][1]);
+ assert (0 == a[1][1][0] && '\0' == *a[1][1][1]);
+ }
+
+ {
+ const char* a[2][2][2] =
+ { { { "", "" }, { 0, 0 } }, { { 0, 0 }, { 0, "" } } };
+
+ assert ('\0' == *a[0][0][0] && '\0' == *a[0][0][1]);
+ assert (0 == a[0][1][0] && 0 == a[0][1][1]);
+ assert (0 == a[1][0][0] && 0 == a[1][0][1]);
+ assert (0 == a[1][1][0] && '\0' == *a[1][1][1]);
+ }
+
+ {
+ const char* a[2][2][2] =
+ { { { 0, 0 }, { 0, 0 } }, { { 0, 0 }, { 0, "" } } };
+
+ assert (0 == a[0][0][0] && 0 == a[0][0][1]);
+ assert (0 == a[0][1][0] && 0 == a[0][1][1]);
+ assert (0 == a[1][0][0] && 0 == a[1][0][1]);
+ assert (0 == a[1][1][0] && '\0' == *a[1][1][1]);
+ }
+
+ {
+ const char* a[2][2][2] =
+ { { { }, { } }, { { }, { 0, "" } } };
+
+ assert (0 == a[0][0][0] && 0 == a[0][0][1]);
+ assert (0 == a[0][1][0] && 0 == a[0][1][1]);
+ assert (0 == a[1][0][0] && 0 == a[1][0][1]);
+ assert (0 == a[1][1][0] && '\0' == *a[1][1][1]);
+ }
+}
+
+void f_sa2_2_2 (void)
+{
+ struct S { const char a[2], *s, c; };
+
+ {
+ const struct S a[2][2][2] = {
+ { },
+ {
+ { { }, { "", "" } },
+ { }
+ }
+ };
+
+ assert ('\0' == *a[0][0][0].a && 0 == a[0][0][0].s && 0 == a[0][0][0].c);
+ assert ('\0' == *a[0][0][1].a && 0 == a[0][0][1].s && 0 == a[0][0][1].c);
+ assert ('\0' == *a[0][1][0].a && 0 == a[0][1][0].s && 0 == a[0][1][0].c);
+ assert ('\0' == *a[0][1][1].a && 0 == a[0][1][1].s && 0 == a[0][1][1].c);
+
+ assert ('\0' == *a[1][0][0].a && 0 == a[1][0][0].s && 0 == a[1][0][0].c);
+ assert ('\0' == *a[1][0][1].a && '\0' == *a[1][0][1].s && 0 == a[1][0][1].c);
+ assert ('\0' == *a[1][1][0].a && 0 == a[1][1][0].s && 0 == a[1][1][0].c);
+ assert ('\0' == *a[1][1][1].a && 0 == a[1][1][1].s && 0 == a[1][1][1].c);
+ }
+
+ {
+ const struct S a[2][2][2] = {
+ { },
+ {
+ { { } },
+ { { "", "" } }
+ }
+ };
+
+ assert ('\0' == *a[0][0][0].a && 0 == a[0][0][0].s);
+ assert ('\0' == *a[0][0][1].a && 0 == a[0][0][1].s);
+ assert ('\0' == *a[0][1][0].a && 0 == a[0][1][0].s);
+ assert ('\0' == *a[0][1][1].a && 0 == a[0][1][1].s);
+
+ assert ('\0' == *a[1][0][0].a && 0 == a[1][0][0].s);
+ assert ('\0' == *a[1][0][1].a && 0 == a[1][0][1].s);
+ assert ('\0' == *a[1][1][0].a && '\0' == *a[1][1][0].s);
+ assert ('\0' == *a[1][1][1].a && 0 == a[1][1][1].s);
+ }
+
+ {
+ const struct S a[2][2][2] = {
+ { },
+ {
+ { { }, { } },
+ { { }, { "", "", 0 } }
+ }
+ };
+
+ assert ('\0' == *a[0][0][0].a && 0 == a[0][0][0].s);
+ assert ('\0' == *a[0][0][1].a && 0 == a[0][0][1].s);
+ assert ('\0' == *a[0][1][0].a && 0 == a[0][1][0].s);
+ assert ('\0' == *a[0][1][1].a && 0 == a[0][1][1].s);
+
+ assert ('\0' == *a[1][0][0].a && 0 == a[1][0][0].s);
+ assert ('\0' == *a[1][0][1].a && 0 == a[1][0][1].s);
+ assert ('\0' == *a[1][1][0].a && 0 == a[1][1][0].s);
+ assert ('\0' == *a[1][1][1].a && '\0' == *a[1][1][1].s);
+ }
+
+ {
+ const struct S a[2][2][2] = {
+ {
+ { { { 0 }, 0, 0 }, { { 0 } , 0, 0 } },
+ { { { 0 }, 0, 0 }, { { 0 } , 0, 0 } },
+ },
+ {
+ { { { 0 }, 0, 0 }, { { 0 } , 0, 0 } },
+ { { }, { "", "", 0 } }
+ }
+ };
+
+ assert ('\0' == *a[0][0][0].a && 0 == a[0][0][0].s);
+ assert ('\0' == *a[0][0][1].a && 0 == a[0][0][1].s);
+ assert ('\0' == *a[0][1][0].a && 0 == a[0][1][0].s);
+ assert ('\0' == *a[0][1][1].a && 0 == a[0][1][1].s);
+
+ assert ('\0' == *a[1][0][0].a && 0 == a[1][0][0].s);
+ assert ('\0' == *a[1][0][1].a && 0 == a[1][0][1].s);
+ assert ('\0' == *a[1][1][0].a && 0 == a[1][1][0].s);
+ assert ('\0' == *a[1][1][1].a && '\0' == *a[1][1][1].s);
+ }
+}
+
+// { dg-final { scan-tree-dump-not "abort" "optimized" } }
diff --git a/gcc/testsuite/c-c++-common/asan/memcmp-1.c b/gcc/testsuite/c-c++-common/asan/memcmp-1.c
index 5915988..0a513c0 100644
--- a/gcc/testsuite/c-c++-common/asan/memcmp-1.c
+++ b/gcc/testsuite/c-c++-common/asan/memcmp-1.c
@@ -16,5 +16,5 @@ main ()
}
/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow.*(\n|\r\n|\r)" } */
-/* { dg-output " #0 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)memcmp|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
-/* { dg-output " #1 0x\[0-9a-f\]+ +(in _*main|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output " #1 0x\[0-9a-f\]+ +(in _*(interceptor_|wrap_|)memcmp|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
+/* { dg-output " #2 0x\[0-9a-f\]+ +(in _*main|\[(\])\[^\n\r]*(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/gomp/clause-dups-1.c b/gcc/testsuite/c-c++-common/gomp/clause-dups-1.c
new file mode 100644
index 0000000..3dde058
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/clause-dups-1.c
@@ -0,0 +1,222 @@
+void f0 (void);
+
+void
+f1 (int *p)
+{
+ int i;
+ #pragma omp parallel proc_bind (master) proc_bind (master) /* { dg-error "too many 'proc_bind' clauses" } */
+ f0 ();
+ #pragma omp parallel proc_bind (close) proc_bind (spread) /* { dg-error "too many 'proc_bind' clauses" } */
+ f0 ();
+ #pragma omp for schedule(static) schedule(static) /* { dg-error "too many 'schedule' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp for schedule(dynamic,5) schedule(runtime) /* { dg-error "too many 'schedule' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp for collapse(1) collapse(1) /* { dg-error "too many 'collapse' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp for collapse(1) collapse(2) /* { dg-error "too many 'collapse' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp for ordered ordered /* { dg-error "too many 'ordered' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp for ordered(1) ordered(1) /* { dg-error "too many 'ordered' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp for nowait nowait /* { dg-error "too many 'nowait' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp simd collapse(1) collapse(1) /* { dg-error "too many 'collapse' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp simd collapse(1) collapse(2) /* { dg-error "too many 'collapse' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp simd simdlen(1) simdlen(1) /* { dg-error "too many 'simdlen' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp simd simdlen(1) simdlen(2) /* { dg-error "too many 'simdlen' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp simd safelen(1) safelen(1) /* { dg-error "too many 'safelen' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp simd safelen(1) safelen(2) /* { dg-error "too many 'safelen' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp teams
+ {
+ #pragma omp distribute collapse(1) collapse(1) /* { dg-error "too many 'collapse' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp distribute collapse(1) collapse(2) /* { dg-error "too many 'collapse' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ }
+ #pragma omp teams thread_limit (3) thread_limit (3) /* { dg-error "too many 'thread_limit' clauses" } */
+ f0 ();
+ #pragma omp teams thread_limit (3) thread_limit (5) /* { dg-error "too many 'thread_limit' clauses" } */
+ f0 ();
+ #pragma omp teams num_teams (3) num_teams (3) /* { dg-error "too many 'num_teams' clauses" } */
+ f0 ();
+ #pragma omp teams num_teams (3) num_teams (5) /* { dg-error "too many 'num_teams' clauses" } */
+ f0 ();
+ #pragma omp single nowait nowait /* { dg-error "too many 'nowait' clauses" } */
+ f0 ();
+ #pragma omp loop bind (thread) collapse(1) collapse(3) /* { dg-error "too many 'collapse' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp task final (0) final (0) /* { dg-error "too many 'final' clauses" } */
+ f0 ();
+ #pragma omp task final (0) final (1) /* { dg-error "too many 'final' clauses" } */
+ f0 ();
+ #pragma omp task priority (1) priority (1) /* { dg-error "too many 'priority' clauses" } */
+ f0 ();
+ #pragma omp task priority (0) priority (1) /* { dg-error "too many 'priority' clauses" } */
+ f0 ();
+ #pragma omp taskloop final (0) final (0) /* { dg-error "too many 'final' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp taskloop final (0) final (1) /* { dg-error "too many 'final' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp taskloop priority (1) priority (1) /* { dg-error "too many 'priority' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp taskloop priority (0) priority (1) /* { dg-error "too many 'priority' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp taskloop grainsize (1) grainsize (2) /* { dg-error "too many 'grainsize' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp taskloop grainsize (2) grainsize (2) /* { dg-error "too many 'grainsize' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp taskloop num_tasks (1) num_tasks (2) /* { dg-error "too many 'num_tasks' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp taskloop num_tasks (2) num_tasks (2) /* { dg-error "too many 'num_tasks' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp taskloop num_tasks (1) grainsize (2)
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp taskloop grainsize (2) num_tasks (2)
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp taskloop collapse (1) collapse (1) /* { dg-error "too many 'collapse' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp taskloop collapse (1) collapse (2) /* { dg-error "too many 'collapse' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp target data device (1) device (1) map (alloc: i) /* { dg-error "too many 'device' clauses" } */
+ f0 ();
+ #pragma omp target enter data device (1) device (1) map (to: i) /* { dg-error "too many 'device' clauses" } */
+ #pragma omp target enter data nowait nowait map (to: i) /* { dg-error "too many 'nowait' clauses" } */
+ #pragma omp target exit data device (1) device (1) map (from: i) /* { dg-error "too many 'device' clauses" } */
+ #pragma omp target exit data nowait nowait map (from: i) /* { dg-error "too many 'nowait' clauses" } */
+ #pragma omp target device (1) device (1) /* { dg-error "too many 'device' clauses" } */
+ f0 ();
+ #pragma omp target nowait nowait /* { dg-error "too many 'nowait' clauses" } */
+ f0 ();
+ #pragma omp target update device (1) device (1) to (i) /* { dg-error "too many 'device' clauses" } */
+ #pragma omp target update nowait nowait to (i) /* { dg-error "too many 'nowait' clauses" } */
+ #pragma omp atomic seq_cst seq_cst /* { dg-error "too many memory order clauses" } */
+ p[0]++;
+ #pragma omp atomic release release /* { dg-error "too many memory order clauses" } */
+ p[0]++;
+ #pragma omp atomic relaxed relaxed /* { dg-error "too many memory order clauses" } */
+ p[0]++;
+ #pragma omp atomic seq_cst release /* { dg-error "too many memory order clauses" } */
+ p[0]++;
+ #pragma omp atomic release relaxed /* { dg-error "too many memory order clauses" } */
+ p[0]++;
+ #pragma omp atomic relaxed seq_cst /* { dg-error "too many memory order clauses" } */
+ p[0]++;
+ #pragma omp atomic hint(0) hint(0) /* { dg-error "too many 'hint' clauses" } */
+ p[0]++;
+ #pragma omp atomic update seq_cst seq_cst /* { dg-error "too many memory order clauses" } */
+ p[0]++;
+ #pragma omp atomic update release release /* { dg-error "too many memory order clauses" } */
+ p[0]++;
+ #pragma omp atomic update relaxed relaxed /* { dg-error "too many memory order clauses" } */
+ p[0]++;
+ #pragma omp atomic update seq_cst release /* { dg-error "too many memory order clauses" } */
+ p[0]++;
+ #pragma omp atomic update release relaxed /* { dg-error "too many memory order clauses" } */
+ p[0]++;
+ #pragma omp atomic update relaxed seq_cst /* { dg-error "too many memory order clauses" } */
+ p[0]++;
+ #pragma omp atomic update hint (0) hint(0) /* { dg-error "too many 'hint' clauses" } */
+ p[0]++;
+ #pragma omp atomic write seq_cst seq_cst /* { dg-error "too many memory order clauses" } */
+ p[0] = 0;
+ #pragma omp atomic write release release /* { dg-error "too many memory order clauses" } */
+ p[0] = 0;
+ #pragma omp atomic write relaxed relaxed /* { dg-error "too many memory order clauses" } */
+ p[0] = 0;
+ #pragma omp atomic write seq_cst release /* { dg-error "too many memory order clauses" } */
+ p[0] = 0;
+ #pragma omp atomic write release relaxed /* { dg-error "too many memory order clauses" } */
+ p[0] = 0;
+ #pragma omp atomic write relaxed seq_cst /* { dg-error "too many memory order clauses" } */
+ p[0] = 0;
+ #pragma omp atomic write hint(0)hint(0) /* { dg-error "too many 'hint' clauses" } */
+ p[0] = 0;
+ #pragma omp atomic read seq_cst seq_cst /* { dg-error "too many memory order clauses" } */
+ i = p[0];
+ #pragma omp atomic read acquire acquire /* { dg-error "too many memory order clauses" } */
+ i = p[0];
+ #pragma omp atomic read relaxed relaxed /* { dg-error "too many memory order clauses" } */
+ i = p[0];
+ #pragma omp atomic read seq_cst acquire /* { dg-error "too many memory order clauses" } */
+ i = p[0];
+ #pragma omp atomic read acquire relaxed /* { dg-error "too many memory order clauses" } */
+ i = p[0];
+ #pragma omp atomic read relaxed seq_cst /* { dg-error "too many memory order clauses" } */
+ i = p[0];
+ #pragma omp atomic read hint (0) hint(0) /* { dg-error "too many 'hint' clauses" } */
+ i = p[0];
+ #pragma omp atomic capture seq_cst seq_cst /* { dg-error "too many memory order clauses" } */
+ i = p[0]++;
+ #pragma omp atomic capture acq_rel acq_rel /* { dg-error "too many memory order clauses" } */
+ i = p[0]++;
+ #pragma omp atomic capture acquire acquire /* { dg-error "too many memory order clauses" } */
+ i = p[0]++;
+ #pragma omp atomic capture release release /* { dg-error "too many memory order clauses" } */
+ i = p[0]++;
+ #pragma omp atomic capture relaxed relaxed /* { dg-error "too many memory order clauses" } */
+ i = p[0]++;
+ #pragma omp atomic capture seq_cst acq_rel /* { dg-error "too many memory order clauses" } */
+ i = p[0]++;
+ #pragma omp atomic capture acq_rel acquire /* { dg-error "too many memory order clauses" } */
+ i = p[0]++;
+ #pragma omp atomic capture acquire release /* { dg-error "too many memory order clauses" } */
+ i = p[0]++;
+ #pragma omp atomic capture release relaxed /* { dg-error "too many memory order clauses" } */
+ i = p[0]++;
+ #pragma omp atomic capture relaxed seq_cst /* { dg-error "too many memory order clauses" } */
+ i = p[0]++;
+ #pragma omp atomic capture hint(0) hint (0) /* { dg-error "too many 'hint' clauses" } */
+ i = p[0]++;
+
+}
+
+#pragma omp declare simd simdlen (4) simdlen (4) /* { dg-error "too many 'simdlen' clauses" } */
+void f2 (int a, int b);
+#pragma omp declare simd simdlen (4) simdlen (8) /* { dg-error "too many 'simdlen' clauses" } */
+void f3 (int a, int b);
+#pragma omp declare simd uniform (a) uniform (a) /* { dg-error "'a' appears more than once in data clauses" } */
+void f4 (int a, int b);
+#pragma omp declare simd linear (a) linear (a) /* { dg-error "'a' appears more than once in data clauses" } */
+void f5 (int a, int b);
+#pragma omp declare simd linear (a) linear (a:3) /* { dg-error "'a' appears more than once in data clauses" } */
+void f6 (int a, int b);
+#pragma omp declare simd uniform (a) linear (a) /* { dg-error "'a' appears more than once in data clauses" } */
+void f7 (int a, int b);
+#pragma omp declare simd linear (a) uniform (a) /* { dg-error "'a' appears more than once in data clauses" } */
+void f8 (int a, int b);
diff --git a/gcc/testsuite/c-c++-common/gomp/declare-target-2.c b/gcc/testsuite/c-c++-common/gomp/declare-target-2.c
index 1135a1d..c7a325c 100644
--- a/gcc/testsuite/c-c++-common/gomp/declare-target-2.c
+++ b/gcc/testsuite/c-c++-common/gomp/declare-target-2.c
@@ -3,7 +3,7 @@
extern int a;
#pragma omp declare target
-#pragma omp declare target to (a) /* { dg-error "with clauses in between" } */
+#pragma omp declare target to (a)
#pragma omp end declare target
int b;
#pragma omp declare target to (b) link (b) /* { dg-error "appears more than once on the same .declare target. directive" } */
diff --git a/gcc/testsuite/c-c++-common/gomp/declare-target-4.c b/gcc/testsuite/c-c++-common/gomp/declare-target-4.c
new file mode 100644
index 0000000..887a815
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/declare-target-4.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp" } */
+
+#pragma omp declare target device_type (any) /* { dg-warning "directive with only 'device_type' clauses ignored" } */
+
+void f1 (void) {}
+void f2 (void);
+#pragma omp declare target to (f1) device_type (any) to (f2)
+
+void f3 (void) {}
+void f4 (void) {}
+#pragma omp declare target device_type (host) to (f3)
+#pragma omp declare target to (f4) device_type (nohost)
+
+#pragma omp declare target
+void f5 (void);
+void f6 (void) {}
+void f7 (void) {}
+#pragma omp declare target to (f7)
+void f8 (void) {}
+#pragma omp declare target to (f8, f5)
+#pragma omp declare target to (f5) to(f8)
+#pragma omp declare target to (f8) device_type (host)
+void f9 (void) {}
+#pragma omp declare target to (f9) device_type (nohost)
+#pragma omp declare target to (f9)
+void f10 (void) {}
+#pragma omp declare target device_type (any) to (f10)
+void f11 (void) {}
+#pragma omp end declare target
+
+void f12 (void) {}
+#pragma omp declare target device_type (any) to (f12)
+#pragma omp declare target to (f12) device_type (host)
+void f13 (void) {}
+#pragma omp declare target device_type (host) to (f13)
+#pragma omp declare target to (f13) device_type (nohost)
+void f14 (void) {}
+#pragma omp declare target device_type (nohost) to (f14)
+#pragma omp declare target device_type (any) to (f14)
+void f15 (void) {}
+#pragma omp declare target device_type (host) to (f15) device_type (nohost)
+void f16 (void) {}
+#pragma omp declare target device_type (any) to (f15) device_type (any)
diff --git a/gcc/testsuite/c-c++-common/gomp/if-4.c b/gcc/testsuite/c-c++-common/gomp/if-4.c
new file mode 100644
index 0000000..f374ce0
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/if-4.c
@@ -0,0 +1,60 @@
+void f0 (void);
+
+void
+f1 (int *p)
+{
+ int i;
+ #pragma omp task if (0) if (0) /* { dg-error "too many 'if' clauses without modifier" } */
+ f0 ();
+ #pragma omp task if (0) if (1) /* { dg-error "too many 'if' clauses without modifier" } */
+ f0 ();
+ #pragma omp task if (task:0) if (task:0) /* { dg-error "too many 'if' clauses with 'task' modifier" } */
+ f0 ();
+ #pragma omp task if (task:0) if (1) /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+ f0 ();
+ #pragma omp task if (0) if (task:1) /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+ f0 ();
+ #pragma omp taskloop if (0) if (0) /* { dg-error "too many 'if' clauses without modifier" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp taskloop if (0) if (1) /* { dg-error "too many 'if' clauses without modifier" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp taskloop if (taskloop:0) if (taskloop:0) /* { dg-error "too many 'if' clauses with 'taskloop' modifier" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp taskloop if (taskloop:0) if (1) /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp taskloop if (0) if (taskloop:0) /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp target data if (1) if (1) map (alloc: i) /* { dg-error "too many 'if' clauses without modifier" } */
+ f0 ();
+ #pragma omp target data if (target data: 1) if (target data:0) map (alloc: i) /* { dg-error "too many 'if' clauses with 'target data' modifier" } */
+ f0 ();
+ #pragma omp target data if (1) if (target data:0) map (alloc: i) /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+ f0 ();
+ #pragma omp target data if (target data: 1) if (0) map (alloc: i) /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+ f0 ();
+ #pragma omp target enter data if (1) if (1) map (to: i) /* { dg-error "too many 'if' clauses without modifier" } */
+ #pragma omp target enter data if (target enter data: 1) if (target enter data:0) map (to: i) /* { dg-error "too many 'if' clauses with 'target enter data' modifier" } */
+ #pragma omp target enter data if (1) if (target enter data:0) map (to: i) /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+ #pragma omp target enter data if (target enter data: 1) if (0) map (to: i) /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+ #pragma omp target exit data if (1) if (1) map (from: i) /* { dg-error "too many 'if' clauses without modifier" } */
+ #pragma omp target exit data if (target exit data: 1) if (target exit data:0) map (from: i) /* { dg-error "too many 'if' clauses with 'target exit data' modifier" } */
+ #pragma omp target exit data if (1) if (target exit data:0) map (from: i) /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+ #pragma omp target exit data if (target exit data: 1) if (0) map (from: i) /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+ #pragma omp target if (1) if (1) /* { dg-error "too many 'if' clauses without modifier" } */
+ f0 ();
+ #pragma omp target if (target: 1) if (target:0) /* { dg-error "too many 'if' clauses with 'target' modifier" } */
+ f0 ();
+ #pragma omp target if (1) if (target:0) /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+ f0 ();
+ #pragma omp target if (target: 1) if (0) /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+ f0 ();
+ #pragma omp target update if (1) if (1) to (i) /* { dg-error "too many 'if' clauses without modifier" } */
+ #pragma omp target update if (target update: 1) if (target update:0) to (i) /* { dg-error "too many 'if' clauses with 'target update' modifier" } */
+ #pragma omp target update if (1) if (target update:0) to (i) /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+ #pragma omp target update if (target update: 1) if (0) to (i) /* { dg-error "if any 'if' clause has modifier, then all 'if' clauses have to use modifier" } */
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/pr91401-1.c b/gcc/testsuite/c-c++-common/gomp/pr91401-1.c
new file mode 100644
index 0000000..f588bf6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pr91401-1.c
@@ -0,0 +1,10 @@
+/* PR c/91401 */
+
+void
+foo (void)
+{
+ int i;
+ #pragma omp distribute parallel for schedule (static) dist_schedule (static)
+ for (i = 0; i < 64; i++)
+ ;
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/pr91401-2.c b/gcc/testsuite/c-c++-common/gomp/pr91401-2.c
new file mode 100644
index 0000000..f537e66
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pr91401-2.c
@@ -0,0 +1,15 @@
+#pragma omp declare target
+void f0 (void);
+
+void
+f1 (void)
+{
+ int i;
+ #pragma omp distribute dist_schedule(static) dist_schedule(static) /* { dg-warning "too many 'dist_schedule' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+ #pragma omp distribute dist_schedule(static,2) dist_schedule(static,4) /* { dg-warning "too many 'dist_schedule' clauses" } */
+ for (i = 0; i < 8; ++i)
+ f0 ();
+}
+#pragma omp end declare target
diff --git a/gcc/testsuite/c-c++-common/gomp/target-data-1.c b/gcc/testsuite/c-c++-common/gomp/target-data-1.c
index 0d4975b..7aa111a 100644
--- a/gcc/testsuite/c-c++-common/gomp/target-data-1.c
+++ b/gcc/testsuite/c-c++-common/gomp/target-data-1.c
@@ -4,15 +4,39 @@ void
foo (void)
{
int a[4] = { 1, 2, 3, 4 };
+ int *p = &a[0];
+ int x = 5;
+ #pragma omp target data map(to:p[:4])
+ #pragma omp target data use_device_ptr(p)
+ #pragma omp target is_device_ptr(p)
+ {
+ p[0]++;
+ }
#pragma omp target data map(to:a)
- #pragma omp target data use_device_ptr(a)
+ #pragma omp target data use_device_addr(a)
#pragma omp target is_device_ptr(a)
{
- a[0]++;
+ p[0]++;
+ }
+ #pragma omp target data map(to:x)
+ #pragma omp target data use_device_addr(x)
+ {
+ int *q = &x;
+ #pragma omp target is_device_ptr(q)
+ {
+ q[0]++;
+ }
}
#pragma omp target data /* { dg-error "must contain at least one" } */
a[0]++;
+ #pragma omp target data map(to:p)
+ #pragma omp target data use_device_ptr(p) use_device_ptr(p) /* { dg-error "appears more than once in data clauses" } */
+ a[0]++;
#pragma omp target data map(to:a)
- #pragma omp target data use_device_ptr(a) use_device_ptr(a) /* { dg-error "appears more than once in data clauses" } */
+ #pragma omp target data use_device_addr(a) use_device_addr(a) /* { dg-error "appears more than once in data clauses" } */
a[0]++;
+ #pragma omp target data map(to:a)
+ #pragma omp target data use_device_ptr(a) /* { dg-error "'use_device_ptr' variable is not a pointer" "" { target c } } */
+ /* { dg-error "'use_device_ptr' variable is neither a pointer nor reference to pointer" "" { target c++ } .-1 } */
+ a[0]++; /* { dg-error "must contain at least one" "" { target *-*-* } .-2 } */
}
diff --git a/gcc/testsuite/c-c++-common/guality/Og-dce-1.c b/gcc/testsuite/c-c++-common/guality/Og-dce-1.c
new file mode 100644
index 0000000..a859e32
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/guality/Og-dce-1.c
@@ -0,0 +1,14 @@
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+int *__attribute__((noipa)) consume (int *ptr) { return ptr; }
+
+int
+main (void)
+{
+ int x;
+ int *volatile ptr = consume (&x);
+ x = 0;
+ x = 1; /* { dg-final { gdb-test . "*ptr" "0" } } */
+ return 0; /* { dg-final { gdb-test . "*ptr" "1" } } */
+}
diff --git a/gcc/testsuite/c-c++-common/guality/Og-dce-2.c b/gcc/testsuite/c-c++-common/guality/Og-dce-2.c
new file mode 100644
index 0000000..3df2c79
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/guality/Og-dce-2.c
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+struct s { int a, b, c, d; };
+
+struct s gs1 = { 1, 2, 3, 4 };
+struct s gs2 = { 5, 6, 7, 8 };
+
+struct s *__attribute__((noipa)) consume (struct s *ptr) { return ptr; }
+
+int
+main (void)
+{
+ struct s x;
+ struct s *volatile ptr = consume (&x);
+ x = gs1;
+ x = gs2; /* { dg-final { gdb-test . "ptr->a" "1" } } */
+ return 0; /* { dg-final { gdb-test . "ptr->a" "5" } } */
+}
diff --git a/gcc/testsuite/c-c++-common/guality/Og-dce-3.c b/gcc/testsuite/c-c++-common/guality/Og-dce-3.c
new file mode 100644
index 0000000..fa6186a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/guality/Og-dce-3.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+volatile int amount = 10;
+
+void __attribute__((noipa))
+do_something (int *ptr)
+{
+ *ptr += 10;
+}
+
+int __attribute__((noipa))
+foo (int count)
+{
+ int x = 1;
+ for (int i = 0; i < count; ++i)
+ do_something (&x); /* { dg-final { gdb-test . "x" "1" } } */
+ int res = x; /* { dg-final { gdb-test . "x" "101" } } */
+ x = res + 1;
+ return res; /* { dg-final { gdb-test . "x" "102" } } */
+
+}
+
+int
+main (void)
+{
+ foo (10);
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/guality/Og-global-dse-1.c b/gcc/testsuite/c-c++-common/guality/Og-global-dse-1.c
new file mode 100644
index 0000000..3d4b4e6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/guality/Og-global-dse-1.c
@@ -0,0 +1,17 @@
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+struct s { int i, j; };
+struct s gs1, gs2 = { 3, 4 };
+
+void __attribute__((noipa)) consume (void) {};
+
+int
+main (void)
+{
+ gs1.i = 1;
+ gs1.j = 2; /* { dg-final { gdb-test . "gs1.i" "1" } } */
+ gs1 = gs2; /* { dg-final { gdb-test . "gs1.j" "2" } } */
+ consume (); /* { dg-final { gdb-test . "gs1.i" "3" } } */
+ return 0; /* { dg-final { gdb-test . "gs1.j" "4" } } */
+}
diff --git a/gcc/testsuite/c-c++-common/guality/Og-static-wo-1.c b/gcc/testsuite/c-c++-common/guality/Og-static-wo-1.c
new file mode 100644
index 0000000..a4c7f30
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/guality/Og-static-wo-1.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+#include "../../gcc.dg/nop.h"
+
+static int x = 0;
+
+int
+main (void)
+{
+ asm volatile (NOP); /* { dg-final { gdb-test . "x" "0" } } */
+ x = 1;
+ asm volatile (NOP); /* { dg-final { gdb-test . "x" "1" } } */
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/pr89888.c b/gcc/testsuite/c-c++-common/pr89888.c
index d9e11d6..f14881c 100644
--- a/gcc/testsuite/c-c++-common/pr89888.c
+++ b/gcc/testsuite/c-c++-common/pr89888.c
@@ -11,8 +11,8 @@ foo (unsigned char x)
{
case -1: y = -1; break; /* { dg-message "previously used here" } */
/* { dg-warning "case label value is less than minimum value for type" "" { target *-*-* } .-1 } */
- case 0xffffffff: y = 0xffffffff; break; /* { dg-error "duplicate case value" } */
- case ~0U: y = ~0U; break; /* { dg-error "duplicate case value" } */
+ case 0xffffffff: y = 0xffffffff; break; /* { dg-error "duplicate case value|narrowing" } */
+ case ~0U: y = ~0U; break; /* { dg-error "duplicate case value|narrowing" } */
}
}
diff --git a/gcc/testsuite/c-c++-common/pr90590-1.c b/gcc/testsuite/c-c++-common/pr90590-1.c
new file mode 100644
index 0000000..4e11deb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr90590-1.c
@@ -0,0 +1,15 @@
+// PR c++/90590
+// { dg-options -Wswitch }
+#include "pr90590-1.h"
+
+void
+g ()
+{
+ enum E e = _A;
+ switch (e) // { dg-bogus "enumeration value '_C' not handled in switch" }
+ {
+ case _A:
+ case _B:
+ break;
+ }
+}
diff --git a/gcc/testsuite/c-c++-common/pr90590-1.h b/gcc/testsuite/c-c++-common/pr90590-1.h
new file mode 100644
index 0000000..22f1a7d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr90590-1.h
@@ -0,0 +1,2 @@
+#pragma GCC system_header
+enum E { _A, _B, _C };
diff --git a/gcc/testsuite/c-c++-common/pr90590-2.c b/gcc/testsuite/c-c++-common/pr90590-2.c
new file mode 100644
index 0000000..23da97f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr90590-2.c
@@ -0,0 +1,11 @@
+// PR c++/90590
+// { dg-options -Wswitch }
+
+#include "pr90590-2.h"
+
+void
+fn ()
+{
+ switch (c.b) // { dg-bogus "enumeration value" }
+ ;
+}
diff --git a/gcc/testsuite/c-c++-common/pr90590-2.h b/gcc/testsuite/c-c++-common/pr90590-2.h
new file mode 100644
index 0000000..e4f8635
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr90590-2.h
@@ -0,0 +1,4 @@
+#pragma GCC system_header
+struct {
+ enum { _A } b;
+} c;
diff --git a/gcc/testsuite/c-c++-common/ubsan/object-size-9.c b/gcc/testsuite/c-c++-common/ubsan/object-size-9.c
index 3684bbe..bd2a53e 100644
--- a/gcc/testsuite/c-c++-common/ubsan/object-size-9.c
+++ b/gcc/testsuite/c-c++-common/ubsan/object-size-9.c
@@ -1,6 +1,6 @@
/* { dg-do run } */
/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */
-/* { dg-options "-fsanitize=undefined" } */
+/* { dg-options "-Wno-stringop-overflow -fsanitize=undefined" } */
/* Test PARM_DECLs and RESULT_DECLs. */
diff --git a/gcc/testsuite/g++.dg/abi/mangle53.C b/gcc/testsuite/g++.dg/abi/mangle53.C
index 13f9e71..727fd75 100644
--- a/gcc/testsuite/g++.dg/abi/mangle53.C
+++ b/gcc/testsuite/g++.dg/abi/mangle53.C
@@ -1,10 +1,11 @@
// { dg-do compile { target c++11 } }
bool b;
+int i;
// { dg-final { scan-assembler "_Z1fIiEDTquL_Z1bEfp_twLi42EET_" } }
-template <class T> auto f (T t) -> decltype(b?t:throw 42) { return 0; }
+template <class T> auto f (T t) -> decltype(b?t:throw 42) { return i; }
// { dg-final { scan-assembler "_Z2f2IiEDTquL_Z1bEfp_trET_" } }
-template <class T> auto f2 (T t) -> decltype(b?t:throw) { return 0; }
+template <class T> auto f2 (T t) -> decltype(b?t:throw) { return i; }
int main()
{
diff --git a/gcc/testsuite/g++.dg/abi/mangle73.C b/gcc/testsuite/g++.dg/abi/mangle73.C
new file mode 100644
index 0000000..2a5322a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/abi/mangle73.C
@@ -0,0 +1,96 @@
+// { dg-do compile { target c++2a } }
+
+struct A
+{
+ char a[2][2];
+};
+
+template <A> struct B { };
+
+typedef B<A{ { { 0, 0 }, { 0, 0 } } }> AZZZZ;
+typedef B<A{ { { 0, 0 }, { 0 } } }> AZZZ_;
+typedef B<A{ { { 0, 0 } } }> AZZ__;
+typedef B<A{ { { 0 } } }> AZ___;
+typedef B<A{ { { } } }> A____;
+
+typedef B<A{ { { "" }, { "" } } }> AS_S_;
+typedef B<A{ { { "" }, { 0, 0 } } }> AS_ZZ;
+typedef B<A{ { { "" }, { 0 } } }> AS_Z_;
+typedef B<A{ { { "" } } }> AS___;
+
+
+// Verify that the types mangle the same.
+void a_zzzz (AZZZZ) { }
+// { dg-final { scan-assembler "_Z6a_zzzz1BIXtl1AEEE" } }
+
+void a_zzz_ (AZZZ_) { }
+// { dg-final { scan-assembler "_Z6a_zzz_1BIXtl1AEEE" } }
+
+void a_zz__ (AZZ__) { }
+// { dg-final { scan-assembler "_Z6a_zz__1BIXtl1AEEE" } }
+
+void a_z___ (AZ___) { }
+// { dg-final { scan-assembler "_Z6a_z___1BIXtl1AEEE" } }
+
+void a_____ (A____) { }
+// { dg-final { scan-assembler "_Z6a_____1BIXtl1AEEE" } }
+
+void a_s_s_ (AS_S_) { }
+// { dg-final { scan-assembler "_Z6a_s_s_1BIXtl1AEEE" } }
+
+void a_s_zz (AS_ZZ) { }
+// { dg-final { scan-assembler "_Z6a_s_zz1BIXtl1AEEE" } }
+
+void a_s_z_ (AS_Z_) { }
+// { dg-final { scan-assembler "_Z6a_s_z_1BIXtl1AEEE" } }
+
+void a_s___ (AS___) { }
+// { dg-final { scan-assembler "_Z6a_s___1BIXtl1AEEE" } }
+
+
+struct C
+{
+ struct { const char a[2][2], *p; } a[2];
+};
+
+template <C> struct D { };
+
+typedef D<C{{{{{ 0, 0 }, { 0, 0 }}, 0 }, {{{ 0, 0 }, { 0, 0 }}, 0 }}}> DZZZZZZZZZZ;
+typedef D<C{{{{{ 0, 0 }, { 0, 0 }}, 0 }, {{{ 0, 0 }, { 0, 0 }}}}}> DZZZZZZZZZ_;
+typedef D<C{{{{{ 0, 0 }, { 0, 0 }}, 0 }, {{{ 0, 0 }, { 0 }}}}}> DZZZZZZZZ__;
+typedef D<C{{{{{ 0, 0 }, { 0, 0 }}, 0 }, {{{ 0, 0 } }}}}> DZZZZZZZ___;
+typedef D<C{{{{{ 0, 0 }, { 0, 0 }}, 0 }, {{{ 0 } }}}}> DZZZZZZ____;
+typedef D<C{{{{{ 0, 0 }, { 0, 0 }}, 0 }}}> DZZZZZ_____;
+typedef D<C{{{{{ 0, 0 }, { 0, 0 }}}}}> DZZZZ______;
+typedef D<C{{{{{ 0, 0 }, { 0 }}}}}> DZZZ_______;
+typedef D<C{{{{{ 0, 0 }}}}}> DZZ________;
+typedef D<C{{{{{ 0 }}}}}> DZ_________;
+typedef D<C{ }> D__________;
+
+typedef D<C{{{{{ "" }, { "" }}, 0 }, {{{ "" }, { "" }}, 0 }}}> DS_S_ZS_S_Z;
+
+void d_zzzzzzzzzz (DZZZZZZZZZZ) { }
+// { dg-final { scan-assembler "_Z12d_zzzzzzzzzz1DIXtl1CEEE" } }
+void d_zzzzzzzzz_ (DZZZZZZZZZ_) { }
+// { dg-final { scan-assembler "_Z12d_zzzzzzzzz_1DIXtl1CEEE" } }
+void d_zzzzzzzz__ (DZZZZZZZZ__) { }
+// { dg-final { scan-assembler "_Z12d_zzzzzzzz__1DIXtl1CEEE" } }
+void d_zzzzzzz___ (DZZZZZZZ___) { }
+// { dg-final { scan-assembler "_Z12d_zzzzzzz___1DIXtl1CEEE" } }
+void d_zzzzzz____ (DZZZZZZ____) { }
+// { dg-final { scan-assembler "_Z12d_zzzzzz____1DIXtl1CEEE" } }
+void d_zzzzz_____ (DZZZZZ_____) { }
+// { dg-final { scan-assembler "_Z12d_zzzzz_____1DIXtl1CEEE" } }
+void d_zzzz______ (DZZZZ______) { }
+// { dg-final { scan-assembler "_Z12d_zzzz______1DIXtl1CEEE" } }
+void d_zzz_______ (DZZZ_______) { }
+// { dg-final { scan-assembler "_Z12d_zzz_______1DIXtl1CEEE" } }
+void d_zz________ (DZZ________) { }
+// { dg-final { scan-assembler "_Z12d_zz________1DIXtl1CEEE" } }
+void d_z_________ (DZ_________) { }
+// { dg-final { scan-assembler "_Z12d_z_________1DIXtl1CEEE" } }
+void d___________ (D__________) { }
+// { dg-final { scan-assembler "_Z12d___________1DIXtl1CEEE" } }
+
+void d_s_s_zs_s_z (DS_S_ZS_S_Z) { }
+// { dg-final { scan-assembler "_Z12d_s_s_zs_s_z1DIXtl1CEEE" } }
diff --git a/gcc/testsuite/g++.dg/concepts/pr89036.C b/gcc/testsuite/g++.dg/concepts/pr89036.C
index f83ef8b..5dcd649 100644
--- a/gcc/testsuite/g++.dg/concepts/pr89036.C
+++ b/gcc/testsuite/g++.dg/concepts/pr89036.C
@@ -6,3 +6,13 @@ struct Y {
~Y() requires(true) = default;
~Y() requires(false) {}
};
+
+Y<int> y;
+
+template<typename T>
+struct X {
+ ~X() requires(sizeof(T) == 8) = default;
+ ~X() requires(sizeof(T) != 8) {}
+};
+
+X<int> x;
diff --git a/gcc/testsuite/g++.dg/conversion/simd4.C b/gcc/testsuite/g++.dg/conversion/simd4.C
index f8f7f2e..22274a1 100644
--- a/gcc/testsuite/g++.dg/conversion/simd4.C
+++ b/gcc/testsuite/g++.dg/conversion/simd4.C
@@ -12,13 +12,13 @@ void
foo ()
{
b[t];
- b[u]; // { dg-error "invalid types" }
- b[v]; // { dg-error "invalid types" }
- b[w]; // { dg-error "invalid types" }
+ b[u]; // { dg-error "4:invalid types" }
+ b[v]; // { dg-error "4:invalid types" }
+ b[w]; // { dg-error "4:invalid types" }
t[b];
- u[b]; // { dg-error "invalid types" }
- v[b]; // { dg-error "invalid types" }
- w[b]; // { dg-error "invalid types" }
+ u[b]; // { dg-error "4:invalid types" }
+ v[b]; // { dg-error "4:invalid types" }
+ w[b]; // { dg-error "4:invalid types" }
new int[t];
new int[u]; // { dg-error "new-declarator must have integral" }
new int[v]; // { dg-error "new-declarator must have integral" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/Wnarrowing17.C b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing17.C
new file mode 100644
index 0000000..064de53
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/Wnarrowing17.C
@@ -0,0 +1,19 @@
+// PR c++/90805 - detect narrowing in case values.
+// { dg-do compile { target c++11 } }
+
+void f(int i, char c, unsigned u)
+{
+ switch (i)
+ {
+ case 2149056512u:; // { dg-error "narrowing conversion of .2149056512. from .unsigned int. to .int." }
+ case (long long int) 1e10:; // { dg-error "narrowing conversion of .10000000000. from .long long int. to .int." }
+ // { dg-warning "overflow in conversion" "overflow" { target *-*-* } .-1 }
+ }
+
+ switch (c)
+ // No narrowing, the adjusted type is int.
+ case 300:; // { dg-warning "exceeds maximum value for type" }
+
+ switch (u)
+ case -42:; // { dg-error "narrowing conversion of .-42. from .int. to .unsigned int." }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/desig1.C b/gcc/testsuite/g++.dg/cpp0x/desig1.C
index 393f530..dd9ad5d 100644
--- a/gcc/testsuite/g++.dg/cpp0x/desig1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/desig1.C
@@ -25,5 +25,5 @@ struct C
constexpr operator SE() const { return SE::se0; }
};
-int c[] = { [C()] = 0 }; // { dg-error "integral constant-expression" }
+int c[] = { [C()] = 0 }; // { dg-error "14:C99 designator .C\\\(\\\). is not an integral constant-expression" }
// { dg-warning "does not allow C99 designated initializers" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum20.C b/gcc/testsuite/g++.dg/cpp0x/enum20.C
index 8937cc7..f39933a 100644
--- a/gcc/testsuite/g++.dg/cpp0x/enum20.C
+++ b/gcc/testsuite/g++.dg/cpp0x/enum20.C
@@ -2,4 +2,4 @@
// { dg-do compile { target c++11 } }
enum A { };
-void A::f() { } // { dg-error "not a class" }
+void A::f() { } // { dg-error "6:.enum A. is not a class" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum28.C b/gcc/testsuite/g++.dg/cpp0x/enum28.C
index 3967699..bfebde5 100644
--- a/gcc/testsuite/g++.dg/cpp0x/enum28.C
+++ b/gcc/testsuite/g++.dg/cpp0x/enum28.C
@@ -7,11 +7,11 @@ void f(int i)
{
switch (i)
{
- case 1.0:; // { dg-error "could not convert" }
+ case 1.0:; // { dg-error "could not convert|conversion from" }
}
switch (i)
{
- case g():; // { dg-error "could not convert" }
+ case g():; // { dg-error "could not convert|conversion from" }
}
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-68.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-68.C
new file mode 100644
index 0000000..6bede06
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-68.C
@@ -0,0 +1,40 @@
+// PR c++/81429 - wrong parsing of constructor with C++11 attribute.
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wunused-parameter -Wno-pedantic" }
+
+void fn1([[maybe_unused]] int a) { }
+void fn2(int a [[maybe_unused]]) { }
+void fn3(__attribute__((unused)) int a) { }
+void fn4(int a __attribute__((unused))) { }
+
+struct S1 {
+ S1([[maybe_unused]] int a) { }
+};
+
+struct S2 {
+ S2([[maybe_unused]] int f, [[maybe_unused]] int a) { }
+};
+
+struct S3 {
+ S3(int a [[maybe_unused]]) { }
+};
+
+struct S4 {
+ S4(int f [[maybe_unused]], int a [[maybe_unused]]) { }
+};
+
+struct S5 {
+ S5(__attribute__((unused)) int a) { }
+};
+
+struct S6 {
+ S6(__attribute__((unused)) int f, __attribute__((unused)) int a) { }
+};
+
+struct S7 {
+ S7(int a __attribute__((unused))) { }
+};
+
+struct S8 {
+ S8(int f __attribute__((unused)), int a __attribute__((unused))) { }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-69.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-69.C
new file mode 100644
index 0000000..43173db
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-69.C
@@ -0,0 +1,40 @@
+// PR c++/81429 - wrong parsing of constructor with C++11 attribute.
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wno-pedantic" }
+
+void fn1([[maybe_unused]] int);
+void fn2(int a [[maybe_unused]]);
+void fn3(__attribute__((unused)) int);
+void fn4(int __attribute__((unused)));
+
+struct S1 {
+ S1([[maybe_unused]] int);
+};
+
+struct S2 {
+ S2([[maybe_unused]] int, [[maybe_unused]] int);
+};
+
+struct S3 {
+ S3(int a [[maybe_unused]]);
+};
+
+struct S4 {
+ S4(int a [[maybe_unused]], int b [[maybe_unused]]);
+};
+
+struct S5 {
+ S5(__attribute__((unused)) int);
+};
+
+struct S6 {
+ S6(__attribute__((unused)) int, __attribute__((unused)) int);
+};
+
+struct S7 {
+ S7(int __attribute__((unused)));
+};
+
+struct S8 {
+ S8(int __attribute__((unused)), int __attribute__((unused)));
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic9.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic9.C
new file mode 100644
index 0000000..8c5085c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic9.C
@@ -0,0 +1,16 @@
+// PR c++/90538
+// { dg-do compile { target c++11 } }
+
+template <class... Ts>
+void f(Ts... ts)
+{
+ [=]{
+ f(ts...);
+ f(ts...);
+ }();
+}
+
+void g()
+{
+ f(1);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/nontype2.C b/gcc/testsuite/g++.dg/cpp0x/nontype2.C
new file mode 100644
index 0000000..aad2ed5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nontype2.C
@@ -0,0 +1,7 @@
+// PR c++/77575
+// { dg-do compile { target c++11 } }
+
+template<template <class> class> struct meow {};
+template<class T> using kitty = T&;
+
+meow<kitty> u;
diff --git a/gcc/testsuite/g++.dg/cpp0x/nontype3.C b/gcc/testsuite/g++.dg/cpp0x/nontype3.C
new file mode 100644
index 0000000..02b5f60
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nontype3.C
@@ -0,0 +1,32 @@
+// PR c++/53009
+// { dg-do compile { target c++11 } }
+
+template<typename T, T> class function_proxy;
+
+template<typename Return, typename Obj, Return(*func)(Obj)>
+struct function_proxy<Return(*)(Obj), func>
+{
+ static void wrapper(){ }
+};
+
+template<typename CT, CT> class member_helper;
+
+template<typename Class, void(Class::*fun)()>
+struct member_helper<void(Class::*)(), fun>
+{
+ static void as_free(Class& obj){ }
+
+ static void worker(){
+ (void) function_proxy<decltype(&as_free), &as_free>::wrapper;
+ }
+};
+
+struct Test
+{
+ void test(){ }
+};
+
+int main()
+{
+ member_helper<decltype(&Test::test), &Test::test>::worker();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/nontype4.C b/gcc/testsuite/g++.dg/cpp0x/nontype4.C
new file mode 100644
index 0000000..2c552d0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nontype4.C
@@ -0,0 +1,25 @@
+// PR c++/56428
+// { dg-do compile { target c++11 } }
+
+struct A { };
+
+template<bool B>
+ struct Builder
+ {
+ static A build() { return A(); }
+ };
+
+template<A (*F)()>
+ A f()
+ {
+ return Builder<F != nullptr>::build();
+ }
+
+A g();
+
+int main()
+{
+ f< &g >();
+ f< nullptr >();
+ f< &f<nullptr> >();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/nullptr42.C b/gcc/testsuite/g++.dg/cpp0x/nullptr42.C
new file mode 100644
index 0000000..2fb628d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nullptr42.C
@@ -0,0 +1,18 @@
+// PR c++/90473 - wrong code with nullptr in default argument.
+// { dg-do run { target c++11 } }
+
+int g;
+void f() { g++; }
+
+void fn1 (void* p = (f(), nullptr)) { }
+void fn2 (int p = (f(), 0)) { }
+
+int main()
+{
+ fn1 ();
+ if (g != 1)
+ __builtin_abort ();
+ fn2 ();
+ if (g != 2)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/range-for19.C b/gcc/testsuite/g++.dg/cpp0x/range-for19.C
index e3f446f..6afaee5 100644
--- a/gcc/testsuite/g++.dg/cpp0x/range-for19.C
+++ b/gcc/testsuite/g++.dg/cpp0x/range-for19.C
@@ -5,6 +5,6 @@
int main()
{
auto a; // { dg-error "no initializer" }
- for(auto i: a) // { dg-error "deduce" }
+ for(auto i: a)
;
}
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn56.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn56.C
new file mode 100644
index 0000000..69bdd95
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn56.C
@@ -0,0 +1,19 @@
+// PR c++/91378
+// { dg-do compile { target c++14 } }
+
+struct B
+{
+ int i;
+};
+
+struct C
+{
+ template <class T> static auto
+ g(B b) noexcept(noexcept(b.i)) { }
+};
+
+template <class T>
+void h(T t)
+{
+ C::g<int>({});
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-79520.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-79520.C
new file mode 100644
index 0000000..a53bb3e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-79520.C
@@ -0,0 +1,11 @@
+// PR c++/79520
+// { dg-do compile { target c++14 } }
+
+constexpr int f(int const& x) { return x; }
+
+constexpr struct S {
+ int x = 0;
+ constexpr S() {(void)f(x); x = 1;}
+} s;
+
+static_assert(f(s.x) == 1, "");
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-neg1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-neg1.C
index ae3dcc6..d82dbad 100644
--- a/gcc/testsuite/g++.dg/cpp1y/constexpr-neg1.C
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-neg1.C
@@ -7,7 +7,7 @@ constexpr int f(int i) {
thread_local int l = i; // { dg-error "thread_local" }
goto foo; // { dg-error "goto" }
foo:
- asm("foo"); // { dg-error "asm" }
+ asm("foo"); // { dg-error "asm" "" { target c++17_down } }
int k; // { dg-error "uninitialized" }
A a; // { dg-error "non-literal" }
return i;
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const1.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const1.C
new file mode 100644
index 0000000..e081a53
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const1.C
@@ -0,0 +1,72 @@
+// PR c++/91264
+// { dg-do compile { target c++14 } }
+
+constexpr void
+mod (int &r)
+{
+ r = 99; // { dg-error "modifying a const object" }
+}
+
+constexpr int
+fn1 ()
+{
+ const int i = 0; // { dg-message "originally declared" }
+ mod (const_cast<int &>(i)); // { dg-message "in .constexpr. expansion of " }
+ return i;
+}
+
+constexpr int i1 = fn1 (); // { dg-message "in .constexpr. expansion of " }
+
+constexpr int
+fn2 ()
+{
+ const int i = 5; // { dg-message "originally declared" }
+ const_cast<int &>(i) = 10; // { dg-error "modifying a const object" }
+ return i;
+}
+
+constexpr int i2 = fn2 (); // { dg-message "in .constexpr. expansion of " }
+
+constexpr int
+fn3 ()
+{
+ const int i = 5; // { dg-message "originally declared" }
+ ++const_cast<int &>(i); // { dg-error "modifying a const object" }
+ return i;
+}
+
+constexpr int i3 = fn3 (); // { dg-message "in .constexpr. expansion of " }
+
+constexpr int
+fn4 ()
+{
+ const int i = 5; // { dg-message "originally declared" }
+ const_cast<int &>(i)--; // { dg-error "modifying a const object" }
+ return i;
+}
+
+constexpr int i4 = fn4 (); // { dg-message "in .constexpr. expansion of " }
+
+constexpr int
+fn5 ()
+{
+ const int i = 5; // { dg-message "originally declared" }
+ const_cast<int &>(i) += 2; // { dg-error "modifying a const object" }
+ return i;
+}
+
+constexpr int i5 = fn5 (); // { dg-message "in .constexpr. expansion of " }
+
+constexpr int
+fn6 ()
+{
+ // This is OK.
+ int i = 3;
+ const int *cip = &i;
+ int *ip = const_cast<int *>(cip);
+ *ip = 4;
+ return i;
+}
+
+constexpr int i6 = fn6 ();
+static_assert(i6 == 4, "");
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const10.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const10.C
new file mode 100644
index 0000000..53acb37
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const10.C
@@ -0,0 +1,22 @@
+// PR c++/91264
+// { dg-do compile { target c++14 } }
+
+struct B {
+ B() = default;
+ int i;
+};
+
+constexpr B bar()
+{
+ constexpr B b = B(); // { dg-message "originally declared" }
+ B *p = const_cast<B*>(&b);
+
+ p->i = 11; // { dg-error "modifying a const object" }
+
+ return *p;
+}
+
+void foo()
+{
+ constexpr B y = bar(); // { dg-message "in .constexpr. expansion of" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const11.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const11.C
new file mode 100644
index 0000000..2b351cd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const11.C
@@ -0,0 +1,16 @@
+// PR c++/91264
+// { dg-do compile { target c++14 } }
+
+struct S {
+ int a = 1;
+ int * ptr = &a;
+};
+
+constexpr bool f() {
+ auto const s = S{}; // { dg-message "originally declared" }
+ *s.ptr = 2; // { dg-error "modifying a const object" }
+ return s.a == 2;
+}
+
+static_assert(f(), ""); // { dg-error "non-constant condition" }
+// { dg-message "in 'constexpr' expansion of" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const12.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const12.C
new file mode 100644
index 0000000..d83e279
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const12.C
@@ -0,0 +1,17 @@
+// PR c++/91264
+// { dg-do compile { target c++14 } }
+
+struct A {
+ const int n;
+ int m;
+ constexpr A() : n(1), m(2) { }
+};
+struct B {
+ A a;
+ constexpr B() {
+ int *p = &a.m;
+ *p = 3;
+ }
+};
+constexpr B b;
+static_assert(b.a.m == 3, "");
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const13.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const13.C
new file mode 100644
index 0000000..bc7faa3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const13.C
@@ -0,0 +1,20 @@
+// PR c++/91264
+// { dg-do compile { target c++14 } }
+
+struct A {
+ mutable int i;
+ constexpr A() : i(0) { }
+};
+struct B {
+ A a;
+ constexpr B() : a{} { }
+};
+
+constexpr void
+g ()
+{
+ const B b;
+ b.a.i = 42;
+}
+
+static_assert((g(), 1), "");
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const14.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const14.C
new file mode 100644
index 0000000..45c4fcf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const14.C
@@ -0,0 +1,38 @@
+// PR c++/91264
+// { dg-do compile { target c++14 } }
+
+struct F {
+ const int f;
+ constexpr F() : f(9) { }
+};
+
+struct C {
+ int n;
+ const F f;
+ constexpr C() : n(1) { n = 66; }
+};
+
+struct A {
+ int r;
+ const C c;
+ constexpr A() : r(11) { r = 14; const_cast<C &>(c).n = 42; } // { dg-error "modifying a const object" }
+};
+
+struct D {
+ const A a;
+ constexpr D() { } // { dg-message "in .constexpr. expansion of" }
+};
+
+struct E {
+ const D d;
+ constexpr E() { } // { dg-message "in .constexpr. expansion of" }
+};
+
+struct B {
+ const E e;
+ constexpr B(bool) { } // { dg-message "in .constexpr. expansion of" }
+};
+
+constexpr B b(false); // { dg-message "in .constexpr. expansion of" }
+// { dg-message "originally declared" "" { target *-*-* } .-1 }
+static_assert(b.e.d.a.c.n == 2, ""); // { dg-error "non-constant condition" }
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const2.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const2.C
new file mode 100644
index 0000000..9803309
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const2.C
@@ -0,0 +1,23 @@
+// PR c++/91264
+// { dg-do compile { target c++14 } }
+
+struct X {
+ int j;
+ constexpr X() : j(0) { }
+};
+
+struct Y {
+ X x;
+ constexpr Y() : x{} { }
+};
+
+constexpr void
+g ()
+{
+ const Y y; // { dg-message "originally declared" }
+ Y *p = const_cast<Y *>(&y);
+ p->x.j = 99; // { dg-error "modifying a const object" }
+}
+
+static_assert((g() , 1), ""); // { dg-error "non-constant condition" }
+// { dg-message "in 'constexpr' expansion of" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const3.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const3.C
new file mode 100644
index 0000000..6853775
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const3.C
@@ -0,0 +1,22 @@
+// PR c++/91264
+// { dg-do compile { target c++14 } }
+
+struct A {
+ int n;
+ constexpr A() : n(1) { n = 2; }
+};
+
+struct B {
+ const A a;
+ constexpr B(bool b) {
+ if (b)
+ const_cast<A &>(a).n = 3; // { dg-error "modifying a const object" }
+ }
+};
+
+constexpr B b(false);
+static_assert(b.a.n == 2, "");
+
+constexpr B b2(true); // { dg-message "in .constexpr. expansion of " }
+// { dg-message "originally declared" "" { target *-*-* } .-1 }
+static_assert((b2.a.n, 1), "");
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const4.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const4.C
new file mode 100644
index 0000000..8263a7c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const4.C
@@ -0,0 +1,17 @@
+// PR c++/91264
+// { dg-do compile { target c++14 } }
+
+struct A {
+ const int n;
+ constexpr A() : n(1) { }
+};
+struct B {
+ A a;
+ constexpr B() {
+ int *p = const_cast<int *>(&a.n);
+ *p = 3; // { dg-error "modifying a const object" }
+ }
+};
+constexpr B b; // { dg-message "in .constexpr. expansion of " }
+// { dg-message "originally declared" "" { target *-*-* } .-1 }
+static_assert((b.a.n, 1), "");
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const5.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const5.C
new file mode 100644
index 0000000..bea54fb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const5.C
@@ -0,0 +1,17 @@
+// PR c++/91264
+// { dg-do compile { target c++14 } }
+
+struct A {
+ mutable int n;
+ constexpr A() : n(1) { n = 2; }
+};
+
+struct B {
+ const A a;
+ constexpr B() {
+ const_cast<A &>(a).n = 3;
+ }
+};
+
+constexpr B b{};
+static_assert((b.a.n, 1), "");
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const6.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const6.C
new file mode 100644
index 0000000..54d83b1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const6.C
@@ -0,0 +1,22 @@
+// PR c++/91264
+// { dg-do compile { target c++14 } }
+
+struct X {
+ mutable int j;
+ constexpr X() : j(0) { }
+};
+
+struct Y {
+ X x;
+ constexpr Y() : x{} { }
+};
+
+constexpr void
+g ()
+{
+ const Y y;
+ Y *p = const_cast<Y *>(&y);
+ p->x.j = 99;
+}
+
+static_assert((g(), 1), "");
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const7.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const7.C
new file mode 100644
index 0000000..922e8ff
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const7.C
@@ -0,0 +1,23 @@
+// PR c++/91264
+// { dg-do compile { target c++14 } }
+
+struct D { int n; };
+
+struct C { const D d; };
+
+struct A {
+ C c;
+ constexpr A() : c{} { }
+};
+
+struct B {
+ A a;
+ constexpr B() {
+ int &r = const_cast<int &>(a.c.d.n);
+ r = 3; // { dg-error "modifying a const object" }
+ }
+};
+
+constexpr B b{}; // { dg-message "in .constexpr. expansion of " }
+// { dg-message "originally declared" "" { target *-*-* } .-1 }
+static_assert((b.a.c.d.n, 1), "");
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const8.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const8.C
new file mode 100644
index 0000000..2b3fe79
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const8.C
@@ -0,0 +1,23 @@
+// PR c++/91264
+// { dg-do compile { target c++14 } }
+
+struct B {
+ int i;
+ double d;
+};
+
+constexpr B bar()
+{
+ constexpr B b = {10,10.10}; // { dg-message "originally declared" }
+ B *p = const_cast<B*>(&b);
+
+ p->i = 11; // { dg-error "modifying a const object" }
+ p->d = 11.11;
+
+ return *p;
+}
+
+void foo()
+{
+ constexpr B y = bar(); // { dg-message "in .constexpr. expansion of" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const9.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const9.C
new file mode 100644
index 0000000..0edec4d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-tracking-const9.C
@@ -0,0 +1,23 @@
+// PR c++/91264
+// { dg-do compile { target c++14 } }
+
+struct B {
+ int i;
+ double d;
+};
+
+constexpr B bar()
+{
+ constexpr B b{}; // { dg-message "originally declared" }
+ B *p = const_cast<B*>(&b);
+
+ p->i = 11; // { dg-error "modifying a const object" }
+ p->d = 11.11;
+
+ return *p;
+}
+
+void foo()
+{
+ constexpr B y = bar(); // { dg-message "in .constexpr. expansion of" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-pretty1.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-pretty1.C
new file mode 100644
index 0000000..4d3246b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-pretty1.C
@@ -0,0 +1,17 @@
+// PR c++/91230
+// { dg-do compile { target c++14 } }
+
+struct StringWrapper {
+ const char* Value;
+};
+
+template <typename T>
+void f() {
+ [](auto) {
+ StringWrapper{__PRETTY_FUNCTION__};
+ };
+}
+
+int main() {
+ f<int>();
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init16.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init16.C
index 0a40ebb..6b4ed34 100644
--- a/gcc/testsuite/g++.dg/cpp1y/lambda-init16.C
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init16.C
@@ -3,7 +3,7 @@
template < class T = int > void f (T)
{
- auto g = [&a = f] () {}; // { dg-error "invalid initialization" }
+ auto g = [&a = f] () {}; // { dg-error "auto" }
}
int main ()
diff --git a/gcc/testsuite/g++.dg/cpp1y/new1.C b/gcc/testsuite/g++.dg/cpp1y/new1.C
new file mode 100644
index 0000000..5e4f1bf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/new1.C
@@ -0,0 +1,73 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cddce-details" } */
+
+#include <stdlib.h>
+
+void
+new_without_use() {
+ int *x = new int;
+}
+
+void
+new_array_without_use() {
+ int *x = new int[5];
+}
+
+void
+new_primitive() {
+ int *x = new int;
+ delete x;
+}
+
+void
+new_array() {
+ int *x = new int[10];
+ delete [] x;
+}
+
+void
+new_primitive_store() {
+ int *x = new int;
+ *x = 10;
+ delete x;
+}
+
+void
+new_primitive_load() {
+ int *x = new int;
+ int tmp = *x;
+ delete x;
+}
+
+int
+new_primitive_load_with_use() {
+ int *x = new int;
+ int tmp = *x;
+ delete x;
+ return tmp;
+}
+
+void
+new_array_store() {
+ int *x = new int[10];
+ x[4] = 10;
+ delete [] x;
+}
+
+void
+new_array_load() {
+ int *x = new int[10];
+ int tmp = x[4];
+ delete [] x;
+}
+
+void
+test_unused() {
+ volatile double d = 0.0;
+ double *p = new double ();
+ d += 1.0;
+ delete p;
+}
+
+/* { dg-final { scan-tree-dump-times "Deleting : operator delete" 5 "cddce1"} } */
+/* { dg-final { scan-tree-dump-times "Deleting : _\\d+ = operator new" 7 "cddce1"} } */
diff --git a/gcc/testsuite/g++.dg/cpp1y/new2.C b/gcc/testsuite/g++.dg/cpp1y/new2.C
new file mode 100644
index 0000000..926e796
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/new2.C
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -std=c++17 -fdump-tree-cddce-details" } */
+
+#include <cstdio>
+#include <cstdlib>
+#include <new>
+
+void* operator new(std::size_t sz)
+{
+ std::printf("global op new called, size = %zu\n", sz);
+ void *ptr = std::malloc(sz);
+ if (ptr)
+ return ptr;
+ else
+ throw std::bad_alloc{};
+}
+
+void operator delete(void* ptr) noexcept
+{
+ std::puts("global op delete called");
+ std::free(ptr);
+}
+
+void
+new_primitive_load() {
+ int *x = new int;
+ int tmp = *x;
+ delete x;
+}
+
+void
+new_array_load() {
+ int *x = new int[10];
+ int tmp = x[4];
+ delete [] x;
+}
+
+/* { dg-final { scan-tree-dump-times "Deleting : _\\d+ = operator new" 2 "cddce1"} } */
+/* { dg-final { scan-tree-dump-times "Deleting : operator delete" 2 "cddce1"} } */
diff --git a/gcc/testsuite/g++.dg/cpp1z/constexpr-if29.C b/gcc/testsuite/g++.dg/cpp1z/constexpr-if29.C
new file mode 100644
index 0000000..a40912a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/constexpr-if29.C
@@ -0,0 +1,28 @@
+// PR c++/85827
+// { dg-do compile { target c++17 } }
+// { dg-options "-Wunused-variable -Wunused-parameter" }
+
+template <int N> int f()
+{
+ constexpr bool _1 = N == 1;
+ constexpr bool _2 = N == 2;
+ constexpr bool _3 = N == 3;
+
+ if constexpr (_1) {
+ return 5;
+ } else if constexpr (_2) {
+ return 1;
+ } else if constexpr (_3) {
+ return 7;
+ }
+}
+
+int a() {
+ return f<1>();
+}
+int b() {
+ return f<2>();
+}
+int c() {
+ return f<3>();
+}
diff --git a/gcc/testsuite/g++.dg/cpp1z/nodiscard6.C b/gcc/testsuite/g++.dg/cpp1z/nodiscard6.C
new file mode 100644
index 0000000..d9813fc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/nodiscard6.C
@@ -0,0 +1,11 @@
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+ [[nodiscard]] A();
+};
+
+void foo()
+{
+ A(); // { dg-warning "ignoring return value" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/comma1.C b/gcc/testsuite/g++.dg/cpp2a/comma1.C
new file mode 100644
index 0000000..8ffe5d7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/comma1.C
@@ -0,0 +1,26 @@
+// PR c++/91338 - P1161R3: Deprecate a[b,c].
+// { dg-do compile { target c++11 } }
+
+struct S {
+ int operator,(int) { return 42; }
+};
+
+void
+fn (int *a, int b, int c)
+{
+ a[b,c]; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++2a } }
+ a[(b,c)];
+
+ a[(void) b, c]; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++2a } }
+ a[((void) b, c)];
+
+ a[(void) b, (void) c, (void) b, b]; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++2a } }
+ a[((void) b, (void) c, (void) b, b)];
+
+ a[S(), 10]; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++2a } }
+ a[(S(), 10)];
+
+ a[int{(1,2)}];
+ a[int{(1,2)}, int{}]; // { dg-warning "top-level comma expression in array subscript is deprecated" "" { target c++2a } }
+ a[(int{(1,2)}, int{})];
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/comma2.C b/gcc/testsuite/g++.dg/cpp2a/comma2.C
new file mode 100644
index 0000000..15fd26a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/comma2.C
@@ -0,0 +1,27 @@
+// PR c++/91338 - P1161R3: Deprecate a[b,c].
+// { dg-do compile { target c++2a } }
+// { dg-options "-Wno-comma-subscript" }
+
+struct S {
+ int operator,(int) { return 42; }
+};
+
+void
+fn (int *a, int b, int c)
+{
+ a[b,c]; // { dg-bogus "top-level comma expression in array subscript is deprecated" }
+ a[(b,c)];
+
+ a[(void) b, c]; // { dg-bogus "top-level comma expression in array subscript is deprecated" }
+ a[((void) b, c)];
+
+ a[(void) b, (void) c, (void) b, b]; // { dg-bogus "top-level comma expression in array subscript is deprecated" }
+ a[((void) b, (void) c, (void) b, b)];
+
+ a[S(), 10]; // { dg-bogus "top-level comma expression in array subscript is deprecated" }
+ a[(S(), 10)];
+
+ a[int{(1,2)}];
+ a[int{(1,2)}, int{}]; // { dg-bogus "top-level comma expression in array subscript is deprecated" }
+ a[(int{(1,2)}, int{})];
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/comma3.C b/gcc/testsuite/g++.dg/cpp2a/comma3.C
new file mode 100644
index 0000000..c39dd4b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/comma3.C
@@ -0,0 +1,27 @@
+// PR c++/91338 - P1161R3: Deprecate a[b,c].
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wcomma-subscript" }
+
+struct S {
+ int operator,(int) { return 42; }
+};
+
+void
+fn (int *a, int b, int c)
+{
+ a[b,c]; // { dg-warning "top-level comma expression in array subscript is deprecated" }
+ a[(b,c)];
+
+ a[(void) b, c]; // { dg-warning "top-level comma expression in array subscript is deprecated" }
+ a[((void) b, c)];
+
+ a[(void) b, (void) c, (void) b, b]; // { dg-warning "top-level comma expression in array subscript is deprecated" }
+ a[((void) b, (void) c, (void) b, b)];
+
+ a[S(), 10]; // { dg-warning "top-level comma expression in array subscript is deprecated" }
+ a[(S(), 10)];
+
+ a[int{(1,2)}];
+ a[int{(1,2)}, int{}]; // { dg-warning "top-level comma expression in array subscript is deprecated" }
+ a[(int{(1,2)}, int{})];
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/comma4.C b/gcc/testsuite/g++.dg/cpp2a/comma4.C
new file mode 100644
index 0000000..23183ad
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/comma4.C
@@ -0,0 +1,27 @@
+// PR c++/91338 - P1161R3: Deprecate a[b,c].
+// { dg-do compile { target c++2a } }
+// { dg-options "-Wno-deprecated" }
+
+struct S {
+ int operator,(int) { return 42; }
+};
+
+void
+fn (int *a, int b, int c)
+{
+ a[b,c]; // { dg-bogus "top-level comma expression in array subscript is deprecated" }
+ a[(b,c)];
+
+ a[(void) b, c]; // { dg-bogus "top-level comma expression in array subscript is deprecated" }
+ a[((void) b, c)];
+
+ a[(void) b, (void) c, (void) b, b]; // { dg-bogus "top-level comma expression in array subscript is deprecated" }
+ a[((void) b, (void) c, (void) b, b)];
+
+ a[S(), 10]; // { dg-bogus "top-level comma expression in array subscript is deprecated" }
+ a[(S(), 10)];
+
+ a[int{(1,2)}];
+ a[int{(1,2)}, int{}]; // { dg-bogus "top-level comma expression in array subscript is deprecated" }
+ a[(int{(1,2)}, int{})];
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/comma5.C b/gcc/testsuite/g++.dg/cpp2a/comma5.C
new file mode 100644
index 0000000..68d19c0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/comma5.C
@@ -0,0 +1,21 @@
+// PR c++/91391 - bogus -Wcomma-subscript warning.
+// { dg-do compile { target c++2a } }
+
+template<typename T, typename U>
+int foo(T t, U u) { return t + u; }
+
+void
+fn (int *a, int b, int c)
+{
+ a[foo<int, int>(1, 2)];
+ a[foo<int, int>(1, 2), foo<int, int>(3, 4)]; // { dg-warning "24:top-level comma expression in array subscript is deprecated" }
+
+ a[b < c, b < c]; // { dg-warning "top-level comma expression in array subscript is deprecated" }
+ a[b < c, b > c]; // { dg-warning "top-level comma expression in array subscript is deprecated" }
+ a[b > c, b > c]; // { dg-warning "top-level comma expression in array subscript is deprecated" }
+ a[b > c, b < c]; // { dg-warning "top-level comma expression in array subscript is deprecated" }
+ a[(b < c, b < c)];
+ a[(b < c, b > c)];
+ a[b << c, b << c]; // { dg-warning "top-level comma expression in array subscript is deprecated" }
+ a[(b << c, b << c)];
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/cond-triv1.C b/gcc/testsuite/g++.dg/cpp2a/cond-triv1.C
new file mode 100644
index 0000000..8f5806e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/cond-triv1.C
@@ -0,0 +1,46 @@
+// Testcase from P0848R0
+// { dg-do compile { target concepts } }
+
+#include <type_traits>
+
+template <typename T>
+class optional
+{
+ struct empty {};
+ union {
+ empty _ = { };
+ T value;
+ };
+ bool engaged = false;
+
+public:
+ constexpr optional() = default;
+
+ constexpr optional(optional const&)
+ requires std::is_trivially_copy_constructible_v<T>
+ = default;
+ constexpr optional(optional const& o)
+ : engaged (o.engaged)
+ {
+ if (engaged)
+ new (&value) T (o.value);
+ }
+
+ ~optional()
+ requires std::is_trivially_destructible_v<T>
+ = default;
+ ~optional()
+ {
+ if (engaged)
+ value.~T();
+ }
+
+ // ...
+};
+
+struct A { A(); A(const A&); ~A(); };
+
+static_assert(std::is_trivially_copy_constructible_v<optional<int>>);
+static_assert(!std::is_trivially_copy_constructible_v<optional<A>>);
+static_assert(std::is_trivially_destructible_v<optional<int>>);
+static_assert(!std::is_trivially_destructible_v<optional<A>>);
diff --git a/gcc/testsuite/g++.dg/cpp2a/cond-triv1a.C b/gcc/testsuite/g++.dg/cpp2a/cond-triv1a.C
new file mode 100644
index 0000000..febd109
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/cond-triv1a.C
@@ -0,0 +1,46 @@
+// Like cond-triv1.C, but with the declaration order swapped.
+// { dg-do compile { target concepts } }
+
+#include <type_traits>
+
+template <typename T>
+class optional
+{
+ struct empty {};
+ union {
+ empty _ = { };
+ T value;
+ };
+ bool engaged = false;
+
+public:
+ constexpr optional() = default;
+
+ constexpr optional(optional const& o)
+ : engaged (o.engaged)
+ {
+ if (engaged)
+ new (&value) T (o.value);
+ }
+ constexpr optional(optional const&)
+ requires std::is_trivially_copy_constructible_v<T>
+ = default;
+
+ ~optional()
+ {
+ if (engaged)
+ value.~T();
+ }
+ ~optional()
+ requires std::is_trivially_destructible_v<T>
+ = default;
+
+ // ...
+};
+
+struct A { A(); A(const A&); ~A(); };
+
+static_assert(std::is_trivially_copy_constructible_v<optional<int>>);
+static_assert(!std::is_trivially_copy_constructible_v<optional<A>>);
+static_assert(std::is_trivially_destructible_v<optional<int>>);
+static_assert(!std::is_trivially_destructible_v<optional<A>>);
diff --git a/gcc/testsuite/g++.dg/cpp2a/inline-asm1.C b/gcc/testsuite/g++.dg/cpp2a/inline-asm1.C
new file mode 100644
index 0000000..a7835c7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/inline-asm1.C
@@ -0,0 +1,13 @@
+// P1668R1: Permit unevaluated inline asm in constexpr functions
+// PR c++/91346
+// { dg-do compile { target c++14 } }
+// { dg-options "" }
+
+constexpr int
+foo (int a, int b)
+{
+ if (__builtin_is_constant_evaluated ())
+ return a + b;
+ asm (""); // { dg-warning ".asm. in .constexpr. function only available with" "" { target c++17_down } }
+ return a;
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/inline-asm2.C b/gcc/testsuite/g++.dg/cpp2a/inline-asm2.C
new file mode 100644
index 0000000..6038c11
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/inline-asm2.C
@@ -0,0 +1,17 @@
+// P1668R1: Permit unevaluated inline asm in constexpr functions
+// PR c++/91346
+// { dg-do compile { target c++2a } }
+
+constexpr int
+foo (bool b)
+{
+ if (b)
+ return 42;
+ asm (""); // { dg-error "inline assembly is not a constant expression" }
+// { dg-message "only unevaluated inline assembly" "" { target *-*-* } .-1 }
+ return -1;
+}
+
+constexpr int i = foo (true);
+static_assert(i == 42, "");
+constexpr int j = foo (false); // { dg-message "in .constexpr. expansion of" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/inline-asm3.C b/gcc/testsuite/g++.dg/cpp2a/inline-asm3.C
new file mode 100644
index 0000000..b636e3b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/inline-asm3.C
@@ -0,0 +1,12 @@
+// P1668R1: Permit unevaluated inline asm in constexpr functions
+// { dg-do compile { target c++2a } }
+// { dg-additional-options "-Wno-pedantic" }
+
+constexpr int
+foo ()
+{
+ constexpr int i = ({ asm(""); 42; }); // { dg-error "inline assembly is not a constant expression" }
+ return i;
+}
+
+constexpr int i = foo ();
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class23.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class23.C
new file mode 100644
index 0000000..ab9e80f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class23.C
@@ -0,0 +1,102 @@
+// PR c++/90947 - Simple lookup table of array of strings is miscompiled
+// Test to verify that the same specializations on non-type template
+// parameters of class types are in fact treated as the same. Unlike
+// nontype-class15.C which involves only one-dimensional arrays this
+// test involves arrays of arrays and arrays of structs.
+// { dg-do compile { target c++2a } }
+
+struct AA3
+{
+ const char a[2][2][2];
+};
+
+template <AA3> struct BAA3 { };
+
+// Redeclare the same variable using different initialization forms
+// of the same constant to verify that they are in fact all recognized
+// as the same.
+extern BAA3<AA3{{{ "", "" }, { "", "" }}}> baa3;
+extern BAA3<AA3{{{ "", "" }, { "", { 0, 0 } }}}> baa3;
+extern BAA3<AA3{{{ "", "" }, { "", { 0 } }}}> baa3;
+extern BAA3<AA3{{{ "", "" }, { "", {} }}}> baa3;
+extern BAA3<AA3{{{ "", "" }, { "" }}}> baa3;
+extern BAA3<AA3{{{ "", "" }, { { 0, 0 } }}}> baa3;
+extern BAA3<AA3{{{ "", "" }, { { 0 } }}}> baa3;
+extern BAA3<AA3{{{ "", "" }, { {} }}}> baa3;
+extern BAA3<AA3{{{ "", "" }, { }}}> baa3;
+extern BAA3<AA3{{{ "", "" }}}> baa3;
+extern BAA3<AA3{{{ "", { 0, 0 } }}}> baa3;
+extern BAA3<AA3{{{ "", { 0 } }}}> baa3;
+extern BAA3<AA3{{{ "", {} }}}> baa3;
+extern BAA3<AA3{{{ "" }}}> baa3;
+extern BAA3<AA3{{{ { 0, 0 } }}}> baa3;
+extern BAA3<AA3{{{ { 0 } }}}> baa3;
+extern BAA3<AA3{{{ {} }}}> baa3;
+extern BAA3<AA3{{{ }}}> baa3;
+extern BAA3<AA3{{ }}> baa3;
+extern BAA3<AA3{ }> baa3;
+
+extern BAA3<AA3{{{ "", "" }, { "", "1" }}}> baa3_1;
+extern BAA3<AA3{{{ "", "" }, { "", { '1', 0 } }}}> baa3_1;
+extern BAA3<AA3{{{ "", "" }, { "", { '1' } }}}> baa3_1;
+
+extern BAA3<AA3{{{ "", "" }, { "1", {} }}}> baa3_2;
+extern BAA3<AA3{{{ "", "" }, { "1" }}}> baa3_2;
+extern BAA3<AA3{{{ "", "" }, { { '1', 0 } }}}> baa3_2;
+extern BAA3<AA3{{{ "", "" }, { { '1' } }}}> baa3_2;
+
+extern BAA3<AA3{{{ "", "1" }}}> baa3_3;
+extern BAA3<AA3{{{ "", { '1', 0 } }}}> baa3_3;
+extern BAA3<AA3{{{ "", { '1' } }}}> baa3_3;
+
+extern BAA3<AA3{{{ "1" }}}> baa3_4;
+extern BAA3<AA3{{{ { '1', 0 } }}}> baa3_4;
+extern BAA3<AA3{{{ { '1' } }}}> baa3_4;
+
+struct AS2
+{
+ struct S { const char a[2], *p; } a[2];
+};
+
+template <AS2> struct BAS2 { };
+
+extern BAS2<AS2{{{ "", 0 }, { "", 0 }}}> bas2;
+extern BAS2<AS2{{{ "", 0 }, { {}, 0 }}}> bas2;
+extern BAS2<AS2{{{ "", 0 }, { "" }}}> bas2;
+extern BAS2<AS2{{{ "", 0 }, { {} }}}> bas2;
+extern BAS2<AS2{{{ "", 0 }, { }}}> bas2;
+extern BAS2<AS2{{{ "", 0 }}}> bas2;
+extern BAS2<AS2{{{ {}, 0 }}}> bas2;
+extern BAS2<AS2{{{ "" }}}> bas2;
+extern BAS2<AS2{{{ {} }}}> bas2;
+extern BAS2<AS2{{{ }}}> bas2;
+extern BAS2<AS2{{ }}> bas2;
+extern BAS2<AS2{ }> bas2;
+
+struct AS2_2
+{
+ struct S { const char a[2], *p; } a[2][2];
+};
+
+template <AS2_2> struct BAS2_2 { };
+
+extern BAS2_2<AS2_2{{{{ "", 0 }, { "", 0 } }, { { "", 0 }, { "", 0 }}}}> b2_2;
+extern BAS2_2<AS2_2{{{{ "", 0 }, { "", 0 } }, { { "", 0 }, { "" }}}}> b2_2;
+extern BAS2_2<AS2_2{{{{ "", 0 }, { "", 0 } }, { { "", 0 }, { {} }}}}> b2_2;
+extern BAS2_2<AS2_2{{{{ "", 0 }, { "", 0 } }, { { "", 0 }, { }}}}> b2_2;
+extern BAS2_2<AS2_2{{{{ "", 0 }, { "", 0 } }, { { "", 0 } }}}> b2_2;
+extern BAS2_2<AS2_2{{{{ "", 0 }, { "", 0 } }, { { "" } }}}> b2_2;
+extern BAS2_2<AS2_2{{{{ "", 0 }, { "", 0 } }, { { {} } }}}> b2_2;
+extern BAS2_2<AS2_2{{{{ "", 0 }, { "", 0 } }, { { }}}}> b2_2;
+extern BAS2_2<AS2_2{{{{ "", 0 }, { "", 0 } }, { }}}> b2_2;
+extern BAS2_2<AS2_2{{{{ "", 0 }, { "", 0 }}}}> b2_2;
+extern BAS2_2<AS2_2{{{{ "", 0 }, { "" }}}}> b2_2;
+extern BAS2_2<AS2_2{{{{ "", 0 }, { {} }}}}> b2_2;
+extern BAS2_2<AS2_2{{{{ "", 0 }, { }}}}> b2_2;
+extern BAS2_2<AS2_2{{{{ "", 0 }}}}> b2_2;
+extern BAS2_2<AS2_2{{{{ "" }}}}> b2_2;
+extern BAS2_2<AS2_2{{{{ {} }}}}> b2_2;
+extern BAS2_2<AS2_2{{{{ }}}}> b2_2;
+extern BAS2_2<AS2_2{{{ }}}> b2_2;
+extern BAS2_2<AS2_2{{ }}> b2_2;
+extern BAS2_2<AS2_2{ }> b2_2;
diff --git a/gcc/testsuite/g++.dg/cpp2a/typename17.C b/gcc/testsuite/g++.dg/cpp2a/typename17.C
new file mode 100644
index 0000000..bf534f1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/typename17.C
@@ -0,0 +1,6 @@
+// DR 2413 - typename in conversion-function-ids.
+// { dg-do compile { target c++2a } }
+
+template<class T> struct S {
+ operator T::X();
+};
diff --git a/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-ctad-neg.C b/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-ctad-neg.C
new file mode 100644
index 0000000..437fa9b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-ctad-neg.C
@@ -0,0 +1,24 @@
+// PR c++/88095
+// Test class non-type template parameters for literal operator templates.
+// Validate handling of failed class template argument deduction.
+// { dg-do compile { target c++2a } }
+
+namespace std {
+using size_t = decltype(sizeof(int));
+}
+
+template <typename CharT, std::size_t N>
+struct fixed_string {
+ constexpr static std::size_t length = N;
+ constexpr fixed_string(...) { }
+ // auto operator<=> (const fixed_string&) = default;
+};
+// Missing deduction guide.
+
+template <fixed_string fs>
+constexpr std::size_t operator"" _udl() {
+ return decltype(fs)::length;
+}
+
+static_assert("test"_udl == 5); // { dg-error "15:no matching function for call to" }
+ // { dg-error "15:class template argument deduction failed" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-ctad-neg2.C b/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-ctad-neg2.C
new file mode 100644
index 0000000..89bb5d3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-ctad-neg2.C
@@ -0,0 +1,20 @@
+// PR c++/88095
+// Test class non-type template parameters for literal operator templates.
+// Validate rejection of class template parameter packs.
+// { dg-do compile { target c++2a } }
+
+namespace std {
+using size_t = decltype(sizeof(int));
+}
+
+template <typename CharT, std::size_t N>
+struct fixed_string {
+ constexpr static std::size_t length = N;
+ constexpr fixed_string(...) { }
+ // auto operator<=> (const fixed_string&) = default;
+};
+template <typename CharT, std::size_t N>
+fixed_string(const CharT (&str)[N]) -> fixed_string<CharT, N>;
+
+template <fixed_string...>
+int operator"" _udl(); // { dg-error "5:literal operator template .int operator\"\"_udl\\(\\). has invalid parameter list" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-ctad.C b/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-ctad.C
new file mode 100644
index 0000000..f6877a9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-ctad.C
@@ -0,0 +1,24 @@
+// PR c++/88095
+// Test class non-type template parameters for literal operator templates.
+// Validate support for class template argument deduction.
+// { dg-do compile { target c++2a } }
+
+namespace std {
+using size_t = decltype(sizeof(int));
+}
+
+template <typename CharT, std::size_t N>
+struct fixed_string {
+ constexpr static std::size_t length = N;
+ constexpr fixed_string(...) { }
+ // auto operator<=> (const fixed_string&) = default;
+};
+template <typename CharT, std::size_t N>
+fixed_string(const CharT (&str)[N]) -> fixed_string<CharT, N>;
+
+template <fixed_string fs>
+constexpr std::size_t operator"" _udl() {
+ return decltype(fs)::length;
+}
+
+static_assert("test"_udl == 5);
diff --git a/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-neg.C b/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-neg.C
new file mode 100644
index 0000000..8f7e3f2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-neg.C
@@ -0,0 +1,12 @@
+// PR c++/88095
+// Test class non-type template parameters for literal operator templates.
+// Validate that parameter packs are rejected.
+// { dg-do compile { target c++2a } }
+
+struct literal_class {
+ constexpr literal_class(...) { }
+ // auto operator<=> (const fixed_string&) = default;
+};
+
+template <literal_class...>
+int operator"" _udl(); // { dg-error "5:literal operator template .int operator\"\"_udl\\(\\). has invalid parameter list" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-neg2.C b/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-neg2.C
new file mode 100644
index 0000000..2c00c5c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp-neg2.C
@@ -0,0 +1,13 @@
+// PR c++/88095
+// Test class non-type template parameters for literal operator templates.
+// Validate that non-literal class types are rejected.
+// { dg-do compile { target c++2a } }
+
+struct non_literal_class {
+ constexpr non_literal_class(...) { }
+ ~non_literal_class() {}
+ // auto operator<=> (const non_literal_fixed_string&) = default;
+};
+
+template <non_literal_class> // { dg-error "11:is not a valid type for a template non-type parameter because it is not literal" }
+int operator"" _udl(); // { dg-error "5:literal operator template .int operator\"\"_udl\\(\\). has invalid parameter list" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp.C b/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp.C
new file mode 100644
index 0000000..dcaca3e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/udlit-class-nttp.C
@@ -0,0 +1,16 @@
+// PR c++/88095
+// Test class non-type template parameters for literal operator templates.
+// Validate basic support.
+// { dg-do compile { target c++2a } }
+
+struct literal_class {
+ constexpr literal_class(...) { }
+ // auto operator<=> (const fixed_string&) = default;
+};
+
+template <literal_class>
+constexpr int operator"" _udl() {
+ return 1;
+}
+
+static_assert("test"_udl == 1);
diff --git a/gcc/testsuite/g++.dg/diagnostic/delete1.C b/gcc/testsuite/g++.dg/diagnostic/delete1.C
new file mode 100644
index 0000000..d31458c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/delete1.C
@@ -0,0 +1,14 @@
+void f ()
+{
+ int a[1];
+ delete (a); // { dg-warning "11:deleting array" }
+
+ bool b;
+ delete (b); // { dg-error "11:type .bool. argument" }
+
+ void g ();
+ delete (g); // { dg-error "11:cannot delete a function" }
+
+ void* p;
+ delete (p); // { dg-warning "11:deleting .void*." }
+}
diff --git a/gcc/testsuite/g++.dg/expr/cond15.C b/gcc/testsuite/g++.dg/expr/cond15.C
new file mode 100644
index 0000000..4a9d057
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/cond15.C
@@ -0,0 +1,13 @@
+// PR c++/90393
+
+struct S {
+ S();
+ S(const S&) {}
+};
+
+S f() {
+ const S m;
+ return true ? m : throw 0;
+}
+
+int main() {}
diff --git a/gcc/testsuite/g++.dg/expr/cond16.C b/gcc/testsuite/g++.dg/expr/cond16.C
new file mode 100644
index 0000000..796828b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/expr/cond16.C
@@ -0,0 +1,25 @@
+// PR c++/90393
+// { dg-do run }
+
+int c, d;
+
+struct string {
+ string(const char *p): s(p) { ++c; }
+ ~string() { ++d; }
+ string(const string& str): s(str.s) { ++c; }
+ const char* s;
+ bool empty() const { return !s; }
+};
+
+string foo()
+{
+ string s("foo");
+ return s.empty() ? throw "empty" : s;
+}
+
+int main()
+{
+ foo();
+ if (c != d)
+ __builtin_abort();
+}
diff --git a/gcc/testsuite/g++.dg/gcov/pr16855.C b/gcc/testsuite/g++.dg/gcov/pr16855.C
index d7aa8a4..a68b05c 100644
--- a/gcc/testsuite/g++.dg/gcov/pr16855.C
+++ b/gcc/testsuite/g++.dg/gcov/pr16855.C
@@ -1,6 +1,8 @@
/* { dg-options "-fprofile-arcs -ftest-coverage" } */
/* { dg-do run { target native } } */
+/* See PR91087 for information on Darwin xfails. */
+
#include <stdlib.h>
#include <stdio.h>
@@ -18,7 +20,9 @@ class Test
{
public:
Test (void) { fprintf (stderr, "In Test::Test\n"); /* count(1) */ }
- ~Test (void) { fprintf (stderr, "In Test::~Test\n"); /* count(1) */ }
+ ~Test (void) {
+ fprintf (stderr, "In Test::~Test\n"); /* count(1) { xfail *-*-darwin* } */
+ }
} T1;
void
@@ -42,7 +46,7 @@ static void __attribute__ ((constructor)) ctor_default ()
static void __attribute__ ((destructor)) dtor_default ()
{
- fprintf (stderr, "in destructor(())\n"); /* count(1) */
+ fprintf (stderr, "in destructor(())\n"); /* count(1) { xfail *-*-darwin* } */
}
-/* { dg-final { run-gcov branches { -b pr16855.C } } } */
+/* { dg-final { run-gcov branches { -b pr16855.C } { xfail *-*-darwin* } } } */
diff --git a/gcc/testsuite/g++.dg/guality/guality.exp b/gcc/testsuite/g++.dg/guality/guality.exp
index 757b20b..33571f1 100644
--- a/gcc/testsuite/g++.dg/guality/guality.exp
+++ b/gcc/testsuite/g++.dg/guality/guality.exp
@@ -65,8 +65,22 @@ if {[check_guality "
return 0;
}
"]} {
- gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.C]] "" ""
- gcc-dg-runtest [lsort [glob $srcdir/c-c++-common/guality/*.c]] "" ""
+ set general [list]
+ set Og [list]
+ foreach file [lsort [glob $srcdir/c-c++-common/guality/*.c]] {
+ switch -glob -- [file tail $file] {
+ Og-* { lappend Og $file }
+ * { lappend general $file }
+ }
+ }
+
+ gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.C]] "" ""
+ gcc-dg-runtest $general "" ""
+ set-torture-options \
+ [list "-O0" "-Og"] \
+ [list {}] \
+ [list "-Og -flto"]
+ gcc-dg-runtest $Og "" ""
}
if [info exists guality_gdb_name] {
diff --git a/gcc/testsuite/g++.dg/init/array53.C b/gcc/testsuite/g++.dg/init/array53.C
new file mode 100644
index 0000000..2bf4805
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/array53.C
@@ -0,0 +1,33 @@
+// PR c++/90947 - Simple lookup table of array of strings is miscompiled
+// Verify that initializers for arrays of elements of a class type with
+// "unusual" data members are correctly recognized as non-zero.
+// { dg-do compile }
+// { dg-options "-O1 -fdump-tree-optimized" }
+
+struct S
+{
+ const char *p;
+ static int i;
+ enum { e };
+ typedef int X;
+ int: 1, b:1;
+ union {
+ int c;
+ };
+ const char *q;
+};
+
+void f (void)
+{
+ const struct S a[2] =
+ {
+ { /* .p = */ "", /* .b = */ 0, /* .c = */ 0, /* .q = */ "" },
+ { /* .p = */ "", /* .b = */ 0, /* .c = */ 0, /* .q = */ "" }
+ };
+
+ if (!a[0].p || *a[0].p || !a[0].q || *a[0].q
+ || !a[1].p || *a[1].p || !a[1].q || *a[1].q)
+ __builtin_abort ();
+}
+
+// { dg-final { scan-tree-dump-not "abort" "optimized" } }
diff --git a/gcc/testsuite/g++.dg/ipa/ipa-icf-2.C b/gcc/testsuite/g++.dg/ipa/ipa-icf-2.C
index 9e78006..7f56189 100644
--- a/gcc/testsuite/g++.dg/ipa/ipa-icf-2.C
+++ b/gcc/testsuite/g++.dg/ipa/ipa-icf-2.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
class A
{
diff --git a/gcc/testsuite/g++.dg/ipa/ipa-icf-3.C b/gcc/testsuite/g++.dg/ipa/ipa-icf-3.C
index 4747b30..5a3cca2 100644
--- a/gcc/testsuite/g++.dg/ipa/ipa-icf-3.C
+++ b/gcc/testsuite/g++.dg/ipa/ipa-icf-3.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
__attribute__ ((noinline))
int zero()
diff --git a/gcc/testsuite/g++.dg/ipa/ipa-icf-4.C b/gcc/testsuite/g++.dg/ipa/ipa-icf-4.C
index b552ef4..0b49c6f 100644
--- a/gcc/testsuite/g++.dg/ipa/ipa-icf-4.C
+++ b/gcc/testsuite/g++.dg/ipa/ipa-icf-4.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf -fno-inline" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized-missed -fno-inline" } */
namespace {
struct A
diff --git a/gcc/testsuite/g++.dg/ipa/ipa-icf-6.C b/gcc/testsuite/g++.dg/ipa/ipa-icf-6.C
index d7650e4..7bcb9dc 100644
--- a/gcc/testsuite/g++.dg/ipa/ipa-icf-6.C
+++ b/gcc/testsuite/g++.dg/ipa/ipa-icf-6.C
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-O3 -fdump-ipa-icf" } */
+/* { dg-options "-O3 -fdump-ipa-icf-optimized" } */
struct A {
A() {ptr=&b;}
diff --git a/gcc/testsuite/g++.dg/lookup/missing-std-include-5.C b/gcc/testsuite/g++.dg/lookup/missing-std-include-5.C
index fe880a6..3ec9abd 100644
--- a/gcc/testsuite/g++.dg/lookup/missing-std-include-5.C
+++ b/gcc/testsuite/g++.dg/lookup/missing-std-include-5.C
@@ -1,2 +1,3 @@
+// { dg-do compile { target c++14 } }
using namespace std::complex_literals; // { dg-error "" }
// { dg-message "#include <complex>" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/g++.dg/lookup/missing-std-include-6.C b/gcc/testsuite/g++.dg/lookup/missing-std-include-6.C
index d9eeb42..a8f2747 100644
--- a/gcc/testsuite/g++.dg/lookup/missing-std-include-6.C
+++ b/gcc/testsuite/g++.dg/lookup/missing-std-include-6.C
@@ -11,15 +11,6 @@ void test_make_shared ()
// { dg-error "expected primary-expression before '\\)' token" "" { target *-*-* } .-3 }
}
-template<class T>
-void test_make_unique ()
-{
- auto p = std::make_unique<T>(); // { dg-error "'make_unique' is not a member of 'std'" }
- // { dg-message "'#include <memory>'" "" { target *-*-* } .-1 }
- // { dg-error "expected primary-expression before '>' token" "" { target *-*-* } .-2 }
- // { dg-error "expected primary-expression before '\\)' token" "" { target *-*-* } .-3 }
-}
-
std::shared_ptr<int> test_shared_ptr; // { dg-error "'shared_ptr' in namespace 'std' does not name a template type" }
// { dg-message "'#include <memory>'" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/g++.dg/lookup/missing-std-include-8.C b/gcc/testsuite/g++.dg/lookup/missing-std-include-8.C
index 68b2082..73532c8 100644
--- a/gcc/testsuite/g++.dg/lookup/missing-std-include-8.C
+++ b/gcc/testsuite/g++.dg/lookup/missing-std-include-8.C
@@ -13,6 +13,15 @@ void test_make_shared ()
// { dg-error "expected primary-expression before '\\)' token" "" { target *-*-* } .-3 }
}
+template<class T>
+void test_make_unique ()
+{
+ std::make_unique<T>(); // { dg-error "'make_unique' is not a member of 'std'" }
+ // { dg-message "'std::make_unique' is only available from C\\+\\+14 onwards" "" { target *-*-* } .-1 }
+ // { dg-error "expected primary-expression before '>' token" "" { target *-*-* } .-2 }
+ // { dg-error "expected primary-expression before '\\)' token" "" { target *-*-* } .-3 }
+}
+
void test_array ()
{
std::array a; // { dg-error "'array' is not a member of 'std'" }
diff --git a/gcc/testsuite/g++.dg/lto/devirt-19_0.C b/gcc/testsuite/g++.dg/lto/devirt-19_0.C
index 696d8c0..b43527e 100644
--- a/gcc/testsuite/g++.dg/lto/devirt-19_0.C
+++ b/gcc/testsuite/g++.dg/lto/devirt-19_0.C
@@ -1,5 +1,5 @@
/* { dg-lto-do link } */
/* { dg-lto-options { "-O2 -fdump-ipa-cp -Wno-return-type -flto -r -nostdlib" } } */
-/* { dg-extra-ld-options "-flinker-output=nolto-rel" } */
+/* { dg-extra-ld-options "-flinker-output=nolto-rel -flto=auto" } */
#include "../ipa/devirt-19.C"
/* { dg-final { scan-wpa-ipa-dump-times "Discovered a virtual call to a known target" 1 "cp" } } */
diff --git a/gcc/testsuite/g++.dg/lto/pr87906_0.C b/gcc/testsuite/g++.dg/lto/pr87906_0.C
index 434d9fb..6a04cd5 100644
--- a/gcc/testsuite/g++.dg/lto/pr87906_0.C
+++ b/gcc/testsuite/g++.dg/lto/pr87906_0.C
@@ -1,5 +1,6 @@
// { dg-lto-do link }
// { dg-require-effective-target fpic }
+// { dg-require-effective-target shared }
// { dg-lto-options { { -O -fPIC -flto } } }
// { dg-extra-ld-options "-shared -nostdlib" }
diff --git a/gcc/testsuite/g++.dg/lto/pr89330_0.C b/gcc/testsuite/g++.dg/lto/pr89330_0.C
new file mode 100644
index 0000000..9f06556
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/pr89330_0.C
@@ -0,0 +1,52 @@
+// { dg-lto-do link }
+// { dg-lto-options { { -O3 -g -flto -shared -fPIC -Wno-odr } } }
+// { dg-require-effective-target fpic }
+// { dg-require-effective-target shared }
+
+namespace Inkscape {
+class Anchored {};
+namespace XML {
+enum NodeType {};
+class Node :Anchored {
+public:
+ virtual NodeType type() ;
+ virtual char name() ;
+ virtual int code() ;
+ virtual unsigned position() ;
+ virtual unsigned childCount() ;
+ virtual char content() ;
+ virtual char *attribute() const ;
+ virtual int attributeList() ;
+ virtual bool matchAttributeName() ;
+ virtual void setPosition() ;
+ virtual void setContent() ;
+ virtual void setAttribute() ;
+ virtual int document() ;
+ virtual int document() const ;
+ virtual Node *root() ;
+ virtual Node *root() const ;
+ virtual Node *parent() ;
+ virtual Node *next() const ;
+ virtual Node *firstChild() const ;
+
+};
+} } struct rdf_license_t {
+ };
+;
+class RDFImpl {
+;
+ rdf_license_t *getLicense();
+};
+static bool rdf_match_license(Inkscape::XML::Node const *repr) {
+ for (Inkscape::XML::Node *current = repr->firstChild(); current;
+ current->next()->attribute());
+ return 0;
+}
+rdf_license_t *RDFImpl::getLicense() {
+ Inkscape::XML::Node *repr ;
+ for (rdf_license_t *license ; license;
+ license) {
+ rdf_match_license(repr);
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/lto/pr89330_1.C b/gcc/testsuite/g++.dg/lto/pr89330_1.C
new file mode 100644
index 0000000..5b999ee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/pr89330_1.C
@@ -0,0 +1,36 @@
+typedef char gchar;
+namespace Inkscape {
+class Anchored {
+int _anchor;
+};
+namespace XML {
+enum NodeType {};
+class Node :Anchored {
+virtual NodeType type() ;
+ virtual char const *name() const ;
+ virtual int code() ;
+ virtual unsigned position() ;
+ virtual unsigned childCount() ;
+ virtual char content() ;
+ virtual char attribute() ;
+ virtual int attributeList() ;
+ virtual bool matchAttributeName() ;
+ virtual void setPosition() ;
+ virtual void setContent() ;
+ virtual int document() ;
+ virtual int document() const ;
+ virtual Node *root() ;
+ virtual Node *root() const ;
+ virtual Node *parent() ;
+ virtual Node *parent() const ;
+ virtual Node *next() ;
+ virtual Node const *next() const ;
+
+};
+class SimpleNode : virtual Node {
+char const *name() const;
+ Node *next() const { return _next; }
+ SimpleNode *_next;
+};
+gchar const *SimpleNode::name() const { return 0; }
+} }
diff --git a/gcc/testsuite/g++.dg/other/friend3.C b/gcc/testsuite/g++.dg/other/friend3.C
index ce872e5..cf74606 100644
--- a/gcc/testsuite/g++.dg/other/friend3.C
+++ b/gcc/testsuite/g++.dg/other/friend3.C
@@ -4,10 +4,10 @@
struct A
{
- friend ~A(); // { dg-error "qualified name" }
+ friend ~A(); // { dg-error "10:expected qualified name" }
};
struct B
{
- friend ~A(); // { dg-error "qualified name" }
+ friend ~A(); // { dg-error "10:expected qualified name" }
};
diff --git a/gcc/testsuite/g++.dg/parse/dtor5.C b/gcc/testsuite/g++.dg/parse/dtor5.C
index 297a0e7..3cb569a 100644
--- a/gcc/testsuite/g++.dg/parse/dtor5.C
+++ b/gcc/testsuite/g++.dg/parse/dtor5.C
@@ -1,12 +1,12 @@
// PR c++/19732
struct A;
-typedef int ~A; // { dg-error "non-function" }
+typedef int ~A; // { dg-error "13:declaration of .~ A. as non-function" }
struct B {
- ~A(); // { dg-error "" }
- typedef int ~A; // { dg-error "non-function" }
+ ~A(); // { dg-error "3:declaration of .~A. as member of .B." }
+ typedef int ~A; // { dg-error "15:declaration of .~ A. as non-function" }
void f() {
- extern ~B(); // { dg-error "non-member" }
+ extern ~B(); // { dg-error "12:declaration of .~ B. as non-member" }
}
};
-void ~A(); // { dg-error "non-member" }
+void ~A(); // { dg-error "6:declaration of .~ A. as non-member" }
diff --git a/gcc/testsuite/g++.dg/parse/friend7.C b/gcc/testsuite/g++.dg/parse/friend7.C
index 7fc480f..19e3179 100644
--- a/gcc/testsuite/g++.dg/parse/friend7.C
+++ b/gcc/testsuite/g++.dg/parse/friend7.C
@@ -19,14 +19,16 @@ struct B
struct C
{
friend int C ();
- friend int ~C (); // { dg-error "return type|in friend decl" }
+ friend int ~C (); // { dg-error "10:return type" }
+ // { dg-error "14:expected qualified name in friend decl" "" { target *-*-* } .-1 }
friend int C (const C &);
};
struct D
{
friend int D () {}
- friend int ~D () {} // { dg-error "return type|in friend decl" }
+ friend int ~D () {} // { dg-error "10:return type" }
+ // { dg-error "14:expected qualified name in friend decl" "" { target *-*-* } .-1 }
friend int D (const D &) {}
};
diff --git a/gcc/testsuite/g++.dg/parse/typedef9.C b/gcc/testsuite/g++.dg/parse/typedef9.C
index 7788f78..2e7d672 100644
--- a/gcc/testsuite/g++.dg/parse/typedef9.C
+++ b/gcc/testsuite/g++.dg/parse/typedef9.C
@@ -1,8 +1,8 @@
// PR c++/38794
// { dg-do compile }
-typedef void foo () {} // { dg-error "invalid function declaration" }
+typedef void foo () {} // { dg-error "14:typedef may not be a function definition" }
struct S
{
- typedef int bar (void) { return 0; } // { dg-error "invalid member function declaration" }
+ typedef int bar (void) { return 0; } // { dg-error "15:typedef may not be a member function definition" }
};
diff --git a/gcc/testsuite/g++.dg/pr60517.C b/gcc/testsuite/g++.dg/pr60517.C
new file mode 100644
index 0000000..2997fa1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr60517.C
@@ -0,0 +1,22 @@
+// PR c++/60517 - warning/error for taking address of member of a temporary
+// object
+// { dg-do compile }
+
+class B
+{
+public:
+ double x[2];
+};
+
+class A
+{
+ B b;
+public:
+ B getB () { return b; }
+};
+
+double foo (A a)
+{
+ double * x = &(a.getB().x[0]); // { dg-error "taking address of rvalue" }
+ return x[0];
+}
diff --git a/gcc/testsuite/g++.dg/template/error22.C b/gcc/testsuite/g++.dg/template/error22.C
index d793fe4..a7e6172 100644
--- a/gcc/testsuite/g++.dg/template/error22.C
+++ b/gcc/testsuite/g++.dg/template/error22.C
@@ -3,7 +3,7 @@
struct A
{
template<void (A::*)()> struct B {};
- void ::foo(); // { dg-error "invalid use" }
+ void ::foo(); // { dg-error "10:invalid use" }
B<&A::foo> b; // { dg-error "incomplete type|template argument" }
};
diff --git a/gcc/testsuite/g++.dg/tls/thread_local-ice5.C b/gcc/testsuite/g++.dg/tls/thread_local-ice5.C
new file mode 100644
index 0000000..4147c32
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tls/thread_local-ice5.C
@@ -0,0 +1,7 @@
+// PR c++/67533
+// { dg-do compile { target c++11 } }
+// { dg-require-effective-target tls }
+
+struct Tls {};
+void _ZTW5mytls();
+thread_local Tls mytls = mytls; // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/torture/pr90313.cc b/gcc/testsuite/g++.dg/torture/pr90313.cc
new file mode 100644
index 0000000..d9f183a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr90313.cc
@@ -0,0 +1,33 @@
+// { dg-do run }
+
+#include <stddef.h>
+
+namespace std {
+ template<typename T, size_t N> struct array {
+ T elems[N];
+ const T &operator[](size_t i) const { return elems[i]; }
+ };
+}
+
+using Coordinates = std::array<double, 3>;
+
+Coordinates map(const Coordinates &c, size_t level)
+{
+ Coordinates result{ c[1], c[2], c[0] };
+
+ if (level != 0)
+ result = map (result, level - 1);
+
+ return result;
+}
+
+int main()
+{
+ Coordinates vecOfCoordinates = { 1.0, 2.0, 3.0 };
+
+ auto result = map(vecOfCoordinates, 1);
+ if (result[0] != 3 || result[1] != 1 || result[2] != 2)
+ __builtin_abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr91270.C b/gcc/testsuite/g++.dg/torture/pr91270.C
new file mode 100644
index 0000000..60d766e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr91270.C
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+struct S {
+ ~S();
+};
+int a = 123;
+void fn1() {
+ S *s = new S[a];
+ delete[] s;
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr91280.C b/gcc/testsuite/g++.dg/torture/pr91280.C
new file mode 100644
index 0000000..063bef8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr91280.C
@@ -0,0 +1,223 @@
+// { dg-do compile }
+
+enum { Aligned, RowMajor };
+enum { ReadOnlyAccessors };
+template <typename> struct K {
+ enum { value };
+};
+template <typename> struct traits;
+template <typename T> struct traits<const T> : traits<T> {};
+struct A {
+ enum { has_write_access, value };
+};
+template <typename, int n> class array {
+public:
+ int operator[](unsigned long p1) { return values[p1]; }
+ int values[n];
+};
+template <typename> struct I;
+template <typename, int, template <class> class = I> class M;
+template <typename, int, int, typename> class J;
+template <typename, int> class N;
+template <typename, typename> class D;
+template <typename, typename, typename, typename> class TensorContractionOp;
+template <long, typename> class TensorChippingOp;
+class C;
+template <typename DenseIndex, int NumDims>
+struct K<array<DenseIndex, NumDims>> {
+ static const long value = NumDims;
+};
+template <typename Scalar_, int NumIndices_, int Options_, typename IndexType_>
+struct traits<J<Scalar_, NumIndices_, Options_, IndexType_>> {
+ typedef IndexType_ Index;
+};
+template <typename PlainObjectType, int Options_,
+ template <class> class MakePointer_>
+struct traits<M<PlainObjectType, Options_, MakePointer_>>
+ : traits<PlainObjectType> {};
+template <typename T> struct B { typedef T type; };
+template <typename Derived> class N<Derived, ReadOnlyAccessors> {
+public:
+ typedef typename traits<Derived>::Index Index;
+ D<int, Derived> m_fn1();
+ template <typename OtherDerived, typename Dimensions>
+ TensorContractionOp<Dimensions, Derived, const OtherDerived, int>
+ m_fn2(OtherDerived, Dimensions);
+ template <Index> TensorChippingOp<1, Derived> m_fn3(Index);
+};
+template <typename Derived, int = A::value>
+class N : public N<Derived, ReadOnlyAccessors> {
+public:
+ template <typename DeviceType> C m_fn4(DeviceType);
+};
+template <typename, typename> struct TensorEvaluator;
+template <typename UnaryOp, typename ArgType, typename Device>
+struct TensorEvaluator<const D<UnaryOp, ArgType>, Device> {
+ TensorEvaluator(D<UnaryOp, ArgType>, Device);
+};
+template <typename, typename> class D {
+public:
+ typedef typename B<D>::type Nested;
+};
+template <typename Indices_, typename LeftArgType_, typename RightArgType_,
+ typename OutputKernelType_, typename Device_>
+struct traits<
+ TensorEvaluator<const TensorContractionOp<Indices_, LeftArgType_,
+ RightArgType_, OutputKernelType_>,
+ Device_>> {
+ typedef Indices_ Indices;
+ typedef LeftArgType_ LeftArgType;
+ typedef RightArgType_ RightArgType;
+ typedef OutputKernelType_ OutputKernelType;
+ typedef Device_ Device;
+};
+template <typename, typename LhsXprType, typename RhsXprType, typename>
+class TensorContractionOp {
+public:
+ typedef typename B<TensorContractionOp>::type Nested;
+ typename LhsXprType::Nested m_fn5();
+ typename RhsXprType::Nested m_fn6();
+};
+template <typename Derived> struct TensorContractionEvaluatorBase {
+ typedef typename traits<Derived>::LeftArgType LeftArgType;
+ typedef typename traits<Derived>::RightArgType RightArgType;
+ typedef typename traits<Derived>::Device Device;
+ TensorContractionEvaluatorBase(
+ TensorContractionOp<typename traits<Derived>::Indices, LeftArgType,
+ RightArgType,
+ typename traits<Derived>::OutputKernelType>
+ p1,
+ Device p2)
+ : m_leftImpl(p1.m_fn6(), p2), m_rightImpl(p1.m_fn5(), p2) {
+ long nocontract_idx;
+ for (int i;; i++) {
+ bool contracting;
+ if (contracting) {
+ if (nocontract_idx < K<int>::value)
+ m_j_size = m_j_strides[nocontract_idx];
+ nocontract_idx++;
+ }
+ }
+ }
+ array<long, 1> m_j_strides;
+ long m_j_size;
+ TensorEvaluator<RightArgType, Device> m_leftImpl;
+ TensorEvaluator<LeftArgType, Device> m_rightImpl;
+};
+template <typename Indices, typename LeftArgType, typename RightArgType,
+ typename OutputKernelType, typename Device>
+struct TensorEvaluator<
+ const TensorContractionOp<Indices, LeftArgType, RightArgType,
+ OutputKernelType>,
+ Device>
+ : TensorContractionEvaluatorBase<TensorEvaluator<
+ const TensorContractionOp<Indices, LeftArgType, RightArgType,
+ OutputKernelType>,
+ Device>> {
+ typedef TensorEvaluator Self;
+ typedef TensorContractionEvaluatorBase<Self> Base;
+ TensorEvaluator(
+ TensorContractionOp<Indices, LeftArgType, RightArgType, OutputKernelType>
+ p1,
+ Device p2)
+ : Base(p1, p2) {}
+};
+template <long DimId, typename XprType>
+struct traits<TensorChippingOp<DimId, XprType>> : traits<XprType> {};
+template <long, typename XprType>
+class TensorChippingOp : public N<TensorChippingOp<1, XprType>> {
+public:
+ typedef typename B<TensorChippingOp>::type Nested;
+};
+template <long DimId, typename ArgType, typename Device>
+struct TensorEvaluator<const TensorChippingOp<DimId, ArgType>, Device> {
+ static const int NumInputDims = K<typename ArgType::Dimensions>::value;
+ array<long, NumInputDims> m_dimensions;
+};
+template <long DimId, typename ArgType, typename Device>
+struct TensorEvaluator<TensorChippingOp<DimId, ArgType>, Device>
+ : TensorEvaluator<const TensorChippingOp<1, ArgType>, Device> {
+ TensorEvaluator(TensorChippingOp<DimId, ArgType>, Device);
+};
+template <typename, typename RhsXprType> class TensorAssignOp {
+public:
+ TensorAssignOp(TensorChippingOp<0, const M<J<int, 3, 1, int>, 1>>,
+ RhsXprType);
+ TensorChippingOp<0, const M<J<int, 3, 1, int>, 1>> m_fn7();
+ typename RhsXprType::Nested m_fn8();
+};
+template <typename LeftArgType, typename RightArgType, typename Device>
+struct TensorEvaluator<const TensorAssignOp<LeftArgType, RightArgType>,
+ Device> {
+ TensorEvaluator(TensorAssignOp<LeftArgType, RightArgType> p1, Device p2)
+ : m_leftImpl(p1.m_fn7(), p2), m_rightImpl(p1.m_fn8(), p2) {}
+ TensorEvaluator<LeftArgType, Device> m_leftImpl;
+ TensorEvaluator<RightArgType, Device> m_rightImpl;
+};
+template <typename Expression> class F {
+public:
+ static void m_fn9(Expression p1) {
+ int device;
+ TensorEvaluator<Expression, int>(p1, device);
+ }
+};
+class C {
+public:
+ void
+ operator=(TensorContractionOp<array<int, 1>,
+ TensorChippingOp<1, M<J<float, 3, 1, int>, 0>>,
+ const D<int, M<J<float, 3, 1, int>, 0>>, int>
+ p1) {
+ TensorAssignOp<
+ TensorChippingOp<0, const M<J<int, 3, 1, int>, 1>>,
+ const TensorContractionOp<
+ array<int, 1>, TensorChippingOp<1, M<J<float, 3, 1, int>, 0>>,
+ const D<int, M<J<float, 3, 1, int>, 0>>, int>>
+ assign(m_expression, p1);
+ F<const TensorAssignOp<
+ TensorChippingOp<0, const M<J<int, 3, 1, int>, 1>>,
+ const TensorContractionOp<
+ array<int, 1>, TensorChippingOp<1, M<J<float, 3, 1, int>, 0>>,
+ const D<int, M<J<float, 3, 1, int>, 0>>, int>>>::m_fn9(assign);
+ }
+ TensorChippingOp<0, const M<J<int, 3, 1, int>, 1>> m_expression;
+};
+template <typename, int NumIndices_, int, typename> class J {
+public:
+ typedef array<long, NumIndices_> Dimensions;
+};
+template <typename PlainObjectType, int Options_, template <class> class>
+class M : public N<M<PlainObjectType, Options_>> {
+public:
+ typedef typename PlainObjectType::Dimensions Dimensions;
+};
+template <int NDIMS> struct TTypes {
+ typedef M<J<float, NDIMS, RowMajor, int>, Aligned> ConstTensor;
+};
+class L {
+public:
+ template <typename, long NDIMS> typename TTypes<NDIMS>::ConstTensor m_fn10();
+};
+class H {
+public:
+ H(int *);
+};
+class G {
+public:
+ G(H *(int *));
+};
+int Run_d;
+class O : H {
+public:
+ int BatchMatMul_context;
+ O() : H(&BatchMatMul_context) {
+ L out, in_y, in_x;
+ auto Tx = in_x.m_fn10<float, 3>(), Ty = in_y.m_fn10<float, 3>(),
+ Tz = out.m_fn10<float, 3>(), z = Tz;
+ array<int, 1> contract_pairs;
+ auto x = Tx.m_fn3<0>(0);
+ auto y = Ty.m_fn1();
+ z.m_fn4(Run_d) = x.m_fn2(y, contract_pairs);
+ }
+};
+G registrar__body__0__object([](int *) -> H * { O(); return 0; });
diff --git a/gcc/testsuite/g++.dg/torture/pr91334.C b/gcc/testsuite/g++.dg/torture/pr91334.C
new file mode 100644
index 0000000..ba79d71
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr91334.C
@@ -0,0 +1,14 @@
+/* PR c++/91334. */
+/* { dg-do compile } */
+
+#include <new>
+#include <stdlib.h>
+
+struct A {
+ A() { throw 0; }
+ void* operator new(size_t size, double = 0.0) { return ::operator new(size);}
+ void operator delete(void* p, double) { exit(0); }
+ void operator delete(void* p) { abort(); }
+};
+
+int main() { try { new A; } catch(...) {} }
diff --git a/gcc/testsuite/g++.dg/tree-prof/devirt.C b/gcc/testsuite/g++.dg/tree-prof/devirt.C
index d8fb2d9..1121f48 100644
--- a/gcc/testsuite/g++.dg/tree-prof/devirt.C
+++ b/gcc/testsuite/g++.dg/tree-prof/devirt.C
@@ -1,5 +1,5 @@
/* PR ipa/88561 */
-/* { dg-options "-O3 -fdump-tree-tracer-details -fdump-tree-dom3-details" } */
+/* { dg-options "-O3 -fdump-tree-tracer-details -fdump-tree-dom3-details -fno-profile-values" } */
struct nsISupports
{
diff --git a/gcc/testsuite/g++.dg/tree-prof/indir-call-prof.C b/gcc/testsuite/g++.dg/tree-prof/indir-call-prof.C
index 3134c3c..be896c0 100644
--- a/gcc/testsuite/g++.dg/tree-prof/indir-call-prof.C
+++ b/gcc/testsuite/g++.dg/tree-prof/indir-call-prof.C
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile -fdump-ipa-afdo" } */
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized -fdump-ipa-afdo" } */
struct A {
A () {}
diff --git a/gcc/testsuite/g++.dg/tree-prof/morefunc.C b/gcc/testsuite/g++.dg/tree-prof/morefunc.C
index a9bdc16..621d09a 100644
--- a/gcc/testsuite/g++.dg/tree-prof/morefunc.C
+++ b/gcc/testsuite/g++.dg/tree-prof/morefunc.C
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -fno-devirtualize --param=profile-func-internal-id=0 -fdump-ipa-profile -fdump-ipa-afdo -Wno-attributes -Wno-coverage-mismatch -Wno-missing-profile" } */
+/* { dg-options "-O2 -fno-devirtualize --param=profile-func-internal-id=0 -fdump-ipa-profile-optimized -fdump-ipa-afdo -Wno-attributes -Wno-coverage-mismatch -Wno-missing-profile" } */
#include "reorder_class1.h"
#include "reorder_class2.h"
diff --git a/gcc/testsuite/g++.dg/tree-prof/reorder.C b/gcc/testsuite/g++.dg/tree-prof/reorder.C
index 6b3bad1..000fb65 100644
--- a/gcc/testsuite/g++.dg/tree-prof/reorder.C
+++ b/gcc/testsuite/g++.dg/tree-prof/reorder.C
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -fno-devirtualize --param=profile-func-internal-id=0 -fdump-ipa-profile -fdump-ipa-afdo -Wno-coverage-mismatch -Wno-attributes" } */
+/* { dg-options "-O2 -fno-devirtualize --param=profile-func-internal-id=0 -fdump-ipa-profile-optimized -fdump-ipa-afdo -Wno-coverage-mismatch -Wno-attributes" } */
#ifdef _PROFILE_USE
#include "reorder_class1.h"
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr19807.C b/gcc/testsuite/g++.dg/tree-ssa/pr19807.C
index 10de295..6a3fff0 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr19807.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr19807.C
@@ -11,8 +11,7 @@ void foo(void)
z = 1 + &a[1];
}
-/* { dg-final { scan-tree-dump-times "&MEM\\\[\\\(void .\\\)&a \\\+ 8B\\\]" 3 "optimized" { target { ! store_merge } } } }
- { dg-final { scan-tree-dump-times "&MEM <int> \\\[\\\(void .\\\)&a \\\+ 8B\\\]" 3 "optimized" { target { store_merge } } } } */
+/* { dg-final { scan-tree-dump-times "&MEM <int> \\\[\\\(void .\\\)&a \\\+ 8B\\\]" 3 "optimized" } } */
void bar(int i)
diff --git a/gcc/testsuite/g++.dg/ubsan/vla-1.C b/gcc/testsuite/g++.dg/ubsan/vla-1.C
index 311cdb1..81e93e3 100644
--- a/gcc/testsuite/g++.dg/ubsan/vla-1.C
+++ b/gcc/testsuite/g++.dg/ubsan/vla-1.C
@@ -1,8 +1,14 @@
// { dg-do run }
-// { dg-options "-Wno-vla -fsanitize=undefined" }
+// { dg-options "-Wno-vla -Wno-stringop-overflow -fsanitize=undefined" }
// { dg-output "index 1 out of bounds" }
-void f(int i) {
+void f(int i)
+{
+ /* The following creates an array of char[4] on the stack and
+ the initialization triggers a -Wstringop-overflow with LTO
+ (or when the function is inlined into the called, such as
+ with -fwhole-program). See PR91258. The warning is
+ suppressed above. */
int ar[i] = { 42, 24 };
}
diff --git a/gcc/testsuite/g++.dg/warn/Wsign-conversion-5.C b/gcc/testsuite/g++.dg/warn/Wsign-conversion-5.C
new file mode 100644
index 0000000..ff38416
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wsign-conversion-5.C
@@ -0,0 +1,18 @@
+// PR c++/87519 - bogus warning with -Wsign-conversion.
+// { dg-options "-Wsign-conversion" }
+
+typedef unsigned long int uint64_t;
+
+void f(unsigned long int a, int q)
+{
+ a += a + q; // { dg-warning "may change the sign" }
+
+ // Explicit cast should disable the warning.
+ a = a + static_cast<uint64_t>(q);
+ a = a + (uint64_t) q;
+ a = a + uint64_t(q);
+ a = a + static_cast<const uint64_t>(q);
+ a = a + (const uint64_t) q;
+ a = a + static_cast<unsigned long int>(q);
+ a = a + static_cast<const unsigned long int>(q);
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/err-msg5.C b/gcc/testsuite/g++.old-deja/g++.brendan/err-msg5.C
index 1837e2f..460d65c 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/err-msg5.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/err-msg5.C
@@ -1,4 +1,4 @@
// { dg-do assemble }
// GROUPS passed error-messages
class foo {};
-~foo () {}// { dg-error "" } destructors must be member functions.*
+~foo () {}// { dg-error "1:declaration of .~ foo. as non-member" } destructors must be member functions.*
diff --git a/gcc/testsuite/g++.old-deja/g++.eh/cond1.C b/gcc/testsuite/g++.old-deja/g++.eh/cond1.C
index 1b2de1d..fe6d429 100644
--- a/gcc/testsuite/g++.old-deja/g++.eh/cond1.C
+++ b/gcc/testsuite/g++.old-deja/g++.eh/cond1.C
@@ -22,8 +22,8 @@ void fn(int i)
(i ? throw X() : throw X()); // ok, void
(i ? i : j) = 1; // ok, int &
- (i ? throw X() : j) = 1; // { dg-error "" } non-lvalue
- (i ? j : throw X()) = 1; // { dg-error "" } non-lvalue
+ (i ? throw X() : j) = 1; // ok, int &
+ (i ? j : throw X()) = 1; // ok, int &
(i ? throw X() : throw X()) = 1; // { dg-error "" } void
(i ? (void)1 : i++); // { dg-error "" } ANSI forbids
diff --git a/gcc/testsuite/g++.old-deja/g++.other/cond5.C b/gcc/testsuite/g++.old-deja/g++.other/cond5.C
index f4d16e9..0d2baf9 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/cond5.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/cond5.C
@@ -35,8 +35,8 @@ void fn(int i)
(i ? throw X() : throw X()); // ok, void
(i ? i : j) = 1; // ok, int &
- (i ? throw X() : j) = 1; // { dg-error "lvalue" }
- (i ? j : throw X()) = 1; // { dg-error "lvalue" }
+ (i ? throw X() : j) = 1; // ok, int &
+ (i ? j : throw X()) = 1; // ok, int &
(i ? throw X() : throw X()) = 1; // { dg-error "lvalue" }
(i ? (void)1 : i++); // { dg-error "throw-expression" }
diff --git a/gcc/testsuite/g++.target/aarch64/return_address_sign_ab_exception.C b/gcc/testsuite/g++.target/aarch64/return_address_sign_ab_exception.C
index 520cd18..ead11de 100644
--- a/gcc/testsuite/g++.target/aarch64/return_address_sign_ab_exception.C
+++ b/gcc/testsuite/g++.target/aarch64/return_address_sign_ab_exception.C
@@ -1,5 +1,6 @@
/* { dg-do run } */
/* { dg-options "--save-temps" } */
+/* { dg-require-effective-target arm_v8_3a_bkey_directive } */
__attribute__((target("branch-protection=pac-ret+leaf")))
int foo_a () {
diff --git a/gcc/testsuite/g++.target/aarch64/return_address_sign_b_exception.C b/gcc/testsuite/g++.target/aarch64/return_address_sign_b_exception.C
index eab2869..2f82731 100644
--- a/gcc/testsuite/g++.target/aarch64/return_address_sign_b_exception.C
+++ b/gcc/testsuite/g++.target/aarch64/return_address_sign_b_exception.C
@@ -1,5 +1,6 @@
/* { dg-do run } */
/* { dg-options "-mbranch-protection=pac-ret+leaf+b-key --save-temps" } */
+/* { dg-require-effective-target arm_v8_3a_bkey_directive } */
int foo () {
throw 22;
diff --git a/gcc/testsuite/g++.target/aarch64/sve/dup_sel_1.C b/gcc/testsuite/g++.target/aarch64/sve/dup_sel_1.C
new file mode 100644
index 0000000..a59862c
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/sve/dup_sel_1.C
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msve-vector-bits=256" } */
+
+#include <stdint.h>
+
+typedef int32_t vnx4si __attribute__((vector_size(32)));
+
+void
+foo (int32_t val)
+{
+ register vnx4si x asm ("z0");
+ register vnx4si y asm ("z0");
+ asm volatile ("" : "=w" (y));
+ val += 1;
+ vnx4si z = { val, val, val, val, val, val, val, val };
+ x = (vnx4si) { -1, 0, 0, -1, 0, -1, 0, -1 } ? z : y;
+ asm volatile ("" :: "w" (x));
+}
+
+/* { dg-final { scan-assembler {\tmov\tz0\.s, p[0-7]/m, w[0-9]+\n} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
diff --git a/gcc/testsuite/g++.target/aarch64/sve/dup_sel_2.C b/gcc/testsuite/g++.target/aarch64/sve/dup_sel_2.C
new file mode 100644
index 0000000..47aad2d
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/sve/dup_sel_2.C
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msve-vector-bits=256" } */
+
+#include <stdint.h>
+
+typedef int32_t vnx4si __attribute__((vector_size(32)));
+
+void
+foo (int32_t val)
+{
+ register vnx4si x asm ("z0");
+ register vnx4si y asm ("z1");
+ asm volatile ("" : "=w" (y));
+ val += 1;
+ vnx4si z = { val, val, val, val, val, val, val, val };
+ x = (vnx4si) { -1, 0, 0, -1, 0, -1, 0, -1 } ? z : y;
+ asm volatile ("" :: "w" (x));
+}
+
+/* { dg-final { scan-assembler {\tmovprfx\tz0, z1\n\tmov\tz0\.s, p[0-7]/m, w[0-9]+\n} } } */
diff --git a/gcc/testsuite/g++.target/aarch64/sve/dup_sel_3.C b/gcc/testsuite/g++.target/aarch64/sve/dup_sel_3.C
new file mode 100644
index 0000000..e8ec6f8
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/sve/dup_sel_3.C
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msve-vector-bits=256" } */
+
+#include <stdint.h>
+
+typedef int32_t vnx4si __attribute__((vector_size(32)));
+typedef float vnx4sf __attribute__((vector_size(32)));
+
+void
+foo (float val)
+{
+ register vnx4sf x asm ("z0");
+ register vnx4sf y asm ("z0");
+ asm volatile ("" : "=w" (y));
+ vnx4sf z = { val, val, val, val, val, val, val, val };
+ x = (vnx4si) { -1, 0, 0, -1, 0, -1, 0, -1 } ? z : y;
+ asm volatile ("" :: "w" (x));
+}
+
+/* { dg-final { scan-assembler {\tmov\tz0\.s, p[0-7]/m, s[0-9]+\n} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
diff --git a/gcc/testsuite/g++.target/aarch64/sve/dup_sel_4.C b/gcc/testsuite/g++.target/aarch64/sve/dup_sel_4.C
new file mode 100644
index 0000000..32ca594
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/sve/dup_sel_4.C
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msve-vector-bits=256" } */
+
+#include <stdint.h>
+
+typedef int32_t vnx4si __attribute__((vector_size(32)));
+typedef float vnx4sf __attribute__((vector_size(32)));
+
+void
+foo (float val)
+{
+ register vnx4sf x asm ("z0");
+ register vnx4sf y asm ("z1");
+ asm volatile ("" : "=w" (y));
+ vnx4sf z = { val, val, val, val, val, val, val, val };
+ x = (vnx4si) { -1, 0, 0, -1, 0, -1, 0, -1 } ? z : y;
+ asm volatile ("" :: "w" (x));
+}
+
+/* { dg-final { scan-assembler {\tmovprfx\tz0, z1\n\tmov\tz0\.s, p[0-7]/m, s[0-9]+\n} } } */
diff --git a/gcc/testsuite/g++.target/aarch64/sve/dup_sel_5.C b/gcc/testsuite/g++.target/aarch64/sve/dup_sel_5.C
new file mode 100644
index 0000000..2fb903a
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/sve/dup_sel_5.C
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msve-vector-bits=256" } */
+
+#include <stdint.h>
+
+typedef int32_t vnx4si __attribute__((vector_size(32)));
+
+void
+foo (int32_t val)
+{
+ register vnx4si x asm ("z0");
+ val += 1;
+ vnx4si y = { val, val, val, val, val, val, val, val };
+ x = (vnx4si) { -1, 0, 0, -1, 0, -1, 0, -1 } ? y : (vnx4si) { 0 };
+ asm volatile ("" :: "w" (x));
+}
+
+/* { dg-final { scan-assembler {\tmovprfx\tz0\.s, p[0-7]/z, z0\.s\n\tmov\tz0\.s, p[0-7]/m, w[0-9]+\n} } } */
diff --git a/gcc/testsuite/g++.target/aarch64/sve/dup_sel_6.C b/gcc/testsuite/g++.target/aarch64/sve/dup_sel_6.C
new file mode 100644
index 0000000..f2b0181
--- /dev/null
+++ b/gcc/testsuite/g++.target/aarch64/sve/dup_sel_6.C
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msve-vector-bits=256" } */
+
+#include <stdint.h>
+
+typedef int32_t vnx4si __attribute__((vector_size(32)));
+typedef float vnx4sf __attribute__((vector_size(32)));
+
+void
+foo (float val)
+{
+ register vnx4sf x asm ("z0");
+ vnx4sf y = { val, val, val, val, val, val, val, val };
+ x = (vnx4si) { -1, 0, 0, -1, 0, -1, 0, -1 } ? y : (vnx4sf) { 0 };
+ asm volatile ("" :: "w" (x));
+}
+
+/* { dg-final { scan-assembler {\tmovprfx\tz0\.s, p[0-7]/z, z0\.s\n\tmov\tz0\.s, p[0-7]/m, s[0-9]+\n} } } */
diff --git a/gcc/testsuite/gcc.c-torture/pr88140.c b/gcc/testsuite/gcc.c-torture/compile/pr88140.c
index 1a2bd32..1a2bd32 100644
--- a/gcc/testsuite/gcc.c-torture/pr88140.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr88140.c
diff --git a/gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c b/gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c
new file mode 100644
index 0000000..b99417c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/noinit-attribute.c
@@ -0,0 +1,59 @@
+/* { dg-do run } */
+/* { dg-require-effective-target noinit } */
+/* { dg-options "-O2" } */
+
+/* This test checks that noinit data is handled correctly. */
+
+extern void _start (void) __attribute__ ((noreturn));
+extern void abort (void) __attribute__ ((noreturn));
+extern void exit (int) __attribute__ ((noreturn));
+
+int var_common;
+int var_zero = 0;
+int var_one = 1;
+int __attribute__((noinit)) var_noinit;
+int var_init = 2;
+
+int __attribute__((noinit)) func(); /* { dg-warning "attribute only applies to variables" } */
+int __attribute__((section ("mysection"), noinit)) var_section1; /* { dg-warning "because it conflicts with attribute" } */
+int __attribute__((noinit, section ("mysection"))) var_section2; /* { dg-warning "because it conflicts with attribute" } */
+
+
+int
+main (void)
+{
+ /* Make sure that the C startup code has correctly initialized the ordinary variables. */
+ if (var_common != 0)
+ abort ();
+
+ /* Initialized variables are not re-initialized during startup, so
+ check their original values only during the first run of this
+ test. */
+ if (var_init == 2)
+ if (var_zero != 0 || var_one != 1)
+ abort ();
+
+ switch (var_init)
+ {
+ case 2:
+ /* First time through - change all the values. */
+ var_common = var_zero = var_one = var_noinit = var_init = 3;
+ break;
+
+ case 3:
+ /* Second time through - make sure that d has not been reset. */
+ if (var_noinit != 3)
+ abort ();
+ exit (0);
+
+ default:
+ /* Any other value for var_init is an error. */
+ abort ();
+ }
+
+ /* Simulate a processor reset by calling the C startup code. */
+ _start ();
+
+ /* Should never reach here. */
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
new file mode 100644
index 0000000..d6201b0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-14.c
@@ -0,0 +1,56 @@
+/* Test to verify that past-the-end multibyte writes via lvalues of wider
+ types than char are diagnosed.
+ { dg-do compile }
+ { dg-require-effective-target int32plus }
+ { dg-options "-O2 -Wall -Wno-array-bounds" } */
+
+typedef __INT16_TYPE__ int16_t;
+typedef __INT32_TYPE__ int32_t;
+typedef __INT64_TYPE__ int64_t;
+typedef __SIZE_TYPE__ size_t;
+
+void* memcpy (void*, const void*, size_t);
+char* strcpy (char*, const char*);
+
+char a4[4], a8[8], a16[16];
+
+const char s4[] = "1234";
+const char t4[] = "4321";
+
+void test_memcpy_cond (int i)
+{
+ char *p = a4 + 1;
+ const char *q = i ? s4 : t4;
+ // On strictly aligned target the call below is left unchanged and
+ // triggers (inaccurately) a -Warray-bounds. The test suppresses
+ // the warning above, which then lets -Wstringop-overrflow detect
+ // the overflow just before expansion.
+ // On other targets it's transformed into a store of a 4-byte integer
+ // which is detected by -Wstringop-overrflow in the strlen pass (i.e.,
+ // before it gets to expansion).
+ memcpy (p, q, 4); // { dg-warning "writing 4 bytes into a region of size 3" }
+}
+
+
+void test_int16 (void)
+{
+ char *p = a4 + 1;
+ *(int16_t*)p = 0;
+ *(int16_t*)(p + 2) = 0; // { dg-warning "writing 2 bytes into a region of size 1" }
+}
+
+
+void test_int32 (void)
+{
+ char *p = a8 + 3;
+ *(int32_t*)p = 0;
+ *(int32_t*)(p + 2) = 0; // { dg-warning "writing 4 bytes into a region of size 3" }
+}
+
+
+void test_int64 (void)
+{
+ char *p = a16 + 5;
+ *(int64_t*)p = 0;
+ *(int64_t*)(p + 5) = 0; // { dg-warning "writing 8 bytes into a region of size 6" }
+}
diff --git a/gcc/testsuite/gcc.dg/attr-nonstring-2.c b/gcc/testsuite/gcc.dg/attr-nonstring-2.c
index 246a372..ef2144d 100644
--- a/gcc/testsuite/gcc.dg/attr-nonstring-2.c
+++ b/gcc/testsuite/gcc.dg/attr-nonstring-2.c
@@ -73,8 +73,8 @@ void test_strnlen_string_cst (void)
T (3, "12", 3, 1);
T (3, "12", 3, 9);
T (3, "123", 3, 1);
- T (3, "123", 3, 4); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound 4" "bug 86688" { xfail *-*-* } } */
- T (3, "123", 3, 9); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound 9" "bug 86688" { xfail *-*-* } } */
+ T (3, "123", 3, 4); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound 4" } */
+ T (3, "123", 3, 9); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound 9" } */
T (5, "1", 2, 1);
T (5, "1", 2, 2);
@@ -110,6 +110,6 @@ void test_strnlen_string_range (void)
{
T (3, "1", 2, UR (0, 1));
T (3, "1", 2, UR (3, 9));
- T (3, "123", 3, UR (4, 5)); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound \\\[4, 5]" "bug 86688" { xfail *-*-* } } */
- T (3, "123", 3, UR (5, 9)); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound \\\[5, 9]" "bug 86688" { xfail *-*-* } } */
+ T (3, "123", 3, UR (4, 5)); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound \\\[4, 5]" } */
+ T (3, "123", 3, UR (5, 9)); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound \\\[5, 9]" } */
}
diff --git a/gcc/testsuite/gcc.dg/enum-redef-1.c b/gcc/testsuite/gcc.dg/enum-redef-1.c
new file mode 100644
index 0000000..b3fa6cb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/enum-redef-1.c
@@ -0,0 +1,29 @@
+enum a { A };
+enum a { B }; /* { dg-bogus "nested redefinition" } */
+/* { dg-error "redeclaration of 'enum a'" "" { target *-*-* } .-1 } */
+
+enum empty {}; /* { dg-error "empty enum is invalid" } */
+enum empty {}; /* { dg-bogus "nested redefinition" } */
+/* { dg-error "empty enum is invalid" "" { target *-*-* } .-1 } */
+
+enum nested_first {
+ C1 = sizeof(enum nested_first { C1a }), /* { dg-error "nested redefinition of 'enum nested_first" } */
+ C2 = sizeof(enum nested_first { C2a }) /* { dg-error "redeclaration of 'enum nested_first'" "" } */
+};
+
+enum nested_second {
+ D1,
+ D2 = sizeof(enum nested_second { D2a }), /* { dg-error "nested redefinition of 'enum nested_second" } */
+ D3 = sizeof(enum nested_second { D3a }) /* { dg-error "redeclaration of 'enum nested_second'" "" } */
+};
+
+enum nested_repeat { E };
+enum nested_repeat { /* { dg-error "redeclaration of 'enum nested_repeat'" "" } */
+ F = sizeof(enum nested_repeat { Fa }) /* { dg-error "nested redefinition of 'enum nested_repeat" } */
+};
+
+enum nested_empty {
+ G1 = sizeof(enum nested_empty {}), /* { dg-error "nested redefinition of 'enum nested_empty" } */
+ /* { dg-error "empty enum is invalid" "" { target *-*-* } .-1 } */
+ G2 = sizeof(enum nested_empty { G2a })
+};
diff --git a/gcc/testsuite/gcc.dg/format/pr80619.c b/gcc/testsuite/gcc.dg/format/pr80619.c
new file mode 100644
index 0000000..c9f0496
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/format/pr80619.c
@@ -0,0 +1,89 @@
+/* PR c/80619 - bad fix-it hint for GCC %lu directive with int argument: %wu
+ { dg-do compile }
+ { dg-options "-Wall -fdiagnostics-show-caret" } */
+
+void T (const char*, ...) __attribute__ ((format (__gcc_diag__, 1, 2)));
+
+void test_suggested_modifier (void)
+{
+ T ("%ld", 0); // { dg-warning "format '%ld' expects argument of type 'long int', but argument 2 has type 'int'" }
+ /* { dg-begin-multiline-output "" }
+ T ("%ld", 0);
+ ~~^ ~
+ | |
+ | int
+ long int
+ %d
+ { dg-end-multiline-output "" } */
+
+ T ("%li", 0); // { dg-warning "format '%li' expects argument of type 'long int', but argument 2 has type 'int'" }
+ /* { dg-begin-multiline-output "" }
+ T ("%li", 0);
+ ~~^ ~
+ | |
+ | int
+ long int
+ %i
+ { dg-end-multiline-output "" } */
+
+ T ("%lu", 0); // { dg-warning "format '%lu' expects argument of type 'long unsigned int', but argument 2 has type 'int'" }
+ /* { dg-begin-multiline-output "" }
+ T ("%lu", 0);
+ ~~^ ~
+ | |
+ | int
+ long unsigned int
+ %u
+ { dg-end-multiline-output "" } */
+
+ T ("%lx", 0); // { dg-warning "format '%lx' expects argument of type 'long unsigned int', but argument 2 has type 'int'" }
+ /* { dg-begin-multiline-output "" }
+ T ("%lx", 0);
+ ~~^ ~
+ | |
+ | int
+ long unsigned int
+ %x
+ { dg-end-multiline-output "" } */
+
+ T ("%lli", 0); // { dg-warning "format '%lli' expects argument of type 'long long int', but argument 2 has type 'int'" }
+ /* { dg-begin-multiline-output "" }
+ T ("%lli", 0);
+ ~~~^ ~
+ | |
+ | int
+ long long int
+ %i
+ { dg-end-multiline-output "" } */
+
+ T ("%llo", 0); // { dg-warning "format '%llo' expects argument of type 'long long unsigned int', but argument 2 has type 'int'" }
+ /* { dg-begin-multiline-output "" }
+ T ("%llo", 0);
+ ~~~^ ~
+ | |
+ | int
+ long long unsigned int
+ %o
+ { dg-end-multiline-output "" } */
+
+ T ("%llu", 0); // { dg-warning "format '%llu' expects argument of type 'long long unsigned int', but argument 2 has type 'int'" }
+ /* { dg-begin-multiline-output "" }
+ T ("%llu", 0);
+ ~~~^ ~
+ | |
+ | int
+ long long unsigned int
+ %u
+ { dg-end-multiline-output "" } */
+
+ T ("%llx", 0); // { dg-warning "format '%llx' expects argument of type 'long long unsigned int', but argument 2 has type 'int'" }
+ /* { dg-begin-multiline-output "" }
+ T ("%llx", 0);
+ ~~~^ ~
+ | |
+ | int
+ long long unsigned int
+ %x
+ { dg-end-multiline-output "" } */
+}
+
diff --git a/gcc/testsuite/gcc.dg/gomp/pr91216.c b/gcc/testsuite/gcc.dg/gomp/pr91216.c
new file mode 100644
index 0000000..3fcc135
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/pr91216.c
@@ -0,0 +1,20 @@
+/* PR middle-end/91216 */
+
+int r;
+
+void
+foo (int *a)
+{
+ int i;
+ #pragma omp for reduction(+:r)
+ for (i = 0; i < 64; i++)
+ a[i] = i;
+ #pragma omp for private (r)
+ for (i = 0; i < 64; i++)
+ {
+ r = 0;
+ #pragma omp parallel shared(r)
+ #pragma omp master
+ r = r + 1;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/guality/guality.exp b/gcc/testsuite/gcc.dg/guality/guality.exp
index ca77a44..89cd896 100644
--- a/gcc/testsuite/gcc.dg/guality/guality.exp
+++ b/gcc/testsuite/gcc.dg/guality/guality.exp
@@ -80,8 +80,22 @@ if {[check_guality "
return 0;
}
"]} {
- gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] "" ""
- gcc-dg-runtest [lsort [glob $srcdir/c-c++-common/guality/*.c]] "" "-Wc++-compat"
+ set general [list]
+ set Og [list]
+ foreach file [lsort [glob $srcdir/c-c++-common/guality/*.c]] {
+ switch -glob -- [file tail $file] {
+ Og-* { lappend Og $file }
+ * { lappend general $file }
+ }
+ }
+
+ gcc-dg-runtest [lsort [glob $srcdir/$subdir/*.c]] "" ""
+ gcc-dg-runtest $general "" "-Wc++-compat"
+ set-torture-options \
+ [list "-O0" "-Og"] \
+ [list {}] \
+ [list "-Og -flto"]
+ gcc-dg-runtest $Og "" "-Wc++-compat"
}
if [info exists guality_gdb_name] {
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-1.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-1.c
index a3d8858..8cb9186 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-1.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
#include <stdio.h>
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-10.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-10.c
index 5f76c1d..8fdac38 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-10.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-10.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
int ferda(int x, int y) __attribute__ ((pure));
int funkce(int a, int b) __attribute__ ((pure));
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-11.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-11.c
index 2610af9..dbc0cbe 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-11.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-11.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
__attribute__ ((noinline))
int fce(int a, int b)
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-12.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-12.c
index 8e4aa56..7ed75f8 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-12.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-12.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
#include <stdlib.h>
#include <stdio.h>
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-13.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-13.c
index 09d817c..d58f182 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-13.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-13.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized-all-all" } */
#include <stdlib.h>
#include <stdio.h>
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-16.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-16.c
index a2613af..b11cae0 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-16.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-16.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
#include <stdio.h>
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-18.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-18.c
index e246c2b..7753e1e 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-18.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-18.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
__attribute__ ((noinline))
int foo(int x)
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-2.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-2.c
index 983e3d8..e6e165a 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-2.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
#include <stdio.h>
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-20.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-20.c
index 46dc704..42e9ce9 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-20.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-20.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
#include <math.h>
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-21.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-21.c
index a20b4a4..ea7164c 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-21.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-21.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
-/* { dg-options "-O2 -msse2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -msse2 -fdump-ipa-icf-optimized" } */
#include <xmmintrin.h>
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-23.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-23.c
index 02bb138..805a406 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-23.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-23.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
struct A
{
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-25.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-25.c
index 4b364eb..5b963a8 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-25.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-25.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized-all" } */
static int zip();
static int zap();
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-26.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-26.c
index 325ece1..42c5386 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-26.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-26.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
void destroy (void)
{
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-27.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-27.c
index bc49e58..a2ce86a 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-27.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-27.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf -fno-inline" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized -fno-inline" } */
void destroy (void)
{
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-3.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-3.c
index 2ecab23..8d83a28 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-3.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
typedef int v4si __attribute__ ((vector_size (16)));
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-35.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-35.c
index d194f91..03bac84 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-35.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-35.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized-all-all" } */
void f1()
{
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-36.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-36.c
index 5d125d0..e630b6d 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-36.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-36.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf -fmerge-all-constants" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized-all-all-all-all -fmerge-all-constants" } */
static int a;
static int b;
static const int c = 2;
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-37.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-37.c
index 5c02e8e..e482bd2 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-37.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-37.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized-all-all-all-all" } */
static int a;
static int b;
static const int c = 2;
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c
index 788038a..b9aea90 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c
@@ -1,5 +1,5 @@
/* { dg-do link } */
-/* { dg-options "-O2 -fdump-ipa-icf -flto -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized -flto -fdump-tree-optimized" } */
/* { dg-require-effective-target lto } */
/* { dg-additional-sources "ipa-icf-38a.c" }*/
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-39.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-39.c
index a60721f..83ccd20 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-39.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-39.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* { dg-require-alias "" } */
-/* { dg-options "-O2 -fdump-ipa-icf -fmerge-all-constants -fdbg-cnt=merged_ipa_icf:1:3" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized -fmerge-all-constants -fdbg-cnt=merged_ipa_icf:1:3" } */
/* { dg-prune-output "dbg_cnt 'merged_ipa_icf' set to 1-3" } */
/* { dg-prune-output "\\*\\*\\*dbgcnt:.*limit.*reached" } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-5.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-5.c
index b2d48f9..40d7174 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-5.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-5.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target c99_runtime } } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
/* { dg-add-options c99_runtime } */
#include <complex.h>
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-7.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-7.c
index 488e133..87a6d26 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-7.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-7.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target c99_runtime } } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
/* { dg-add-options c99_runtime } */
#include <complex.h>
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-8.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-8.c
index 8ee46d0..fe95c2c 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-8.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-8.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-icf" } */
+/* { dg-options "-O2 -fdump-ipa-icf-optimized" } */
#include <stdio.h>
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-merge-1.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-merge-1.c
index 06958a4..f96e8e8 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-icf-merge-1.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-merge-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-O2 -fdump-ipa-icf" } */
+/* { dg-additional-options "-O2 -fdump-ipa-icf-optimized" } */
/* Picking 'main' as a candiate target for equivalent functios is not a
good idea. */
diff --git a/gcc/testsuite/gcc.dg/ipa/pr64307.c b/gcc/testsuite/gcc.dg/ipa/pr64307.c
index 79d93af..e2c9121 100644
--- a/gcc/testsuite/gcc.dg/ipa/pr64307.c
+++ b/gcc/testsuite/gcc.dg/ipa/pr64307.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target c99_runtime } } */
-/* { dg-options "-O0 -fipa-icf -fdump-ipa-icf" } */
+/* { dg-options "-O0 -fipa-icf -fdump-ipa-icf-optimized" } */
#include <complex.h>
diff --git a/gcc/testsuite/gcc.dg/ipa/pr90555.c b/gcc/testsuite/gcc.dg/ipa/pr90555.c
index 327cff9..d357405 100644
--- a/gcc/testsuite/gcc.dg/ipa/pr90555.c
+++ b/gcc/testsuite/gcc.dg/ipa/pr90555.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
-/* { dg-options "-fopenmp-simd -O2 -mavx512f -fdump-ipa-icf" } */
+/* { dg-options "-fopenmp-simd -O2 -mavx512f -fdump-ipa-icf-optimized" } */
#define N 1024
int a[N];
diff --git a/gcc/testsuite/gcc.dg/pr79983.c b/gcc/testsuite/gcc.dg/pr79983.c
index 84aae69..1e292d4 100644
--- a/gcc/testsuite/gcc.dg/pr79983.c
+++ b/gcc/testsuite/gcc.dg/pr79983.c
@@ -8,7 +8,7 @@ struct S { int i, j; }; /* { dg-error "redefinition of 'struct S'" } */
enum E;
enum E { A, B, C }; /* { dg-message "originally defined here" } */
-enum E { D, F }; /* { dg-error "nested redefinition of 'enum E'|redeclaration of 'enum E'" } */
+enum E { D, F }; /* { dg-error "redeclaration of 'enum E'" } */
union U;
union U { int i; }; /* { dg-message "originally defined here" } */
diff --git a/gcc/testsuite/gcc.dg/pr80170.c b/gcc/testsuite/gcc.dg/pr80170.c
index def051a..e400e14 100644
--- a/gcc/testsuite/gcc.dg/pr80170.c
+++ b/gcc/testsuite/gcc.dg/pr80170.c
@@ -24,11 +24,7 @@ NullB (void * misalignedPtr)
struct B * b;
bb_2:
-#if __SIZEOF_LONG__ == 8
- b_2 = misalignedPtr_1(D) + 18446744073709551608ul;
-#else
- b_2 = misalignedPtr_1(D) + 4294967292ul;
-#endif
+ b_2 = misalignedPtr_1(D) + _Literal (__SIZETYPE__) -__SIZEOF_POINTER__;
__MEM <struct B> (b_2).a.a = _Literal (void *) 0;
__MEM <struct B> (b_2).a.b = _Literal (void *) 0;
return;
diff --git a/gcc/testsuite/gcc.dg/spellcheck-options-21.c b/gcc/testsuite/gcc.dg/spellcheck-options-21.c
new file mode 100644
index 0000000..3e0e8a8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/spellcheck-options-21.c
@@ -0,0 +1,3 @@
+/* { dg-do compile } */
+/* { dg-options "-flto=sparta" } */
+/* { dg-error "unrecognized argument to '-flto=' option: 'sparta'" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/strlenopt-44.c b/gcc/testsuite/gcc.dg/strlenopt-44.c
index 0c01088..0af78ac 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-44.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-44.c
@@ -83,7 +83,7 @@ void test_keep (void)
size_t uchar_max = (unsigned char)-1;
KEEP ("1", 0, UR (1, uchar_max + 1), 1);
- KEEP ("1\0\3", 1, UR (1, 2), 1);
+ KEEP ("1\0\3", 1, UR (1, 2), 2);
}
/* { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated_" 0 "optimized" } }
diff --git a/gcc/testsuite/gcc.dg/strlenopt-70.c b/gcc/testsuite/gcc.dg/strlenopt-70.c
new file mode 100644
index 0000000..0853023
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-70.c
@@ -0,0 +1,331 @@
+/* PR tree-optimization/91183 - strlen of a strcpy result with a conditional
+ source not folded
+ Test to verify that strlen can determine string lengths from wider stores
+ than narrow characters. This matters because on targets that can handle
+ unaligned stores and where GCC lowers multi-character stores into smaller
+ numbers of wider stores.
+ { dg-do compile }
+ { dg-options "-O2 -fdump-tree-optimized" } */
+
+#include "strlenopt.h"
+
+#define CHAR_BIT __CHAR_BIT__
+
+typedef __UINT16_TYPE__ uint16_t;
+typedef __UINT32_TYPE__ uint32_t;
+typedef __UINT64_TYPE__ uint64_t;
+typedef __UINT64_TYPE__ uint64_t;
+
+#define CAT(x, y) x ## y
+#define CONCAT(x, y) CAT (x, y)
+#define FAILNAME(name) CONCAT (call_ ## name ##_on_line_, __LINE__)
+
+#define FAIL(name) do { \
+ extern void FAILNAME (name) (void); \
+ FAILNAME (name)(); \
+ } while (0)
+
+/* Macros to emit a call to function named
+ call_failed_to_be_eliminated_on_line_NNN()
+ for each call that's expected to be eliminated. The dg-final
+ scan-tree-dump-time directive at the bottom of the test verifies
+ that no such call appears in output. */
+#define ELIM(expr) \
+ if ((expr)) FAIL (not_eliminated); else (void)0
+
+/* Verify that 'strlen (A) EXPECT' is folded to true. When non-null,
+ the first sizeof (INIT) - 1 bytes of the INIT arrray are stored
+ in A first, followed by *(TYPE*)A = ASSIGN. */
+#define T(init, type, off, assign, expect) do { \
+ char a[32]; \
+ memcpy (a, init ? init : "", init ? sizeof init - 1 : 0); \
+ *(type*)(a + off) = assign; \
+ ELIM (!(strlen (a) expect)); \
+ } while (0)
+
+/* Same as T but works around the optimizer dropping the initializing
+ store before the assignment and defeating the strlen optimization. */
+#define TX(init, type, off, assign, expect) do { \
+ char a[32]; \
+ strcpy (a, init + 2); \
+ strcat (a, init + sizeof (init) - 3); \
+ *(type*)(a + off) = assign; \
+ ELIM (!(strlen (a) expect)); \
+ } while (0)
+
+/* Evaluates to an element at index I of the literal S padded with nuls
+ on the right. */
+#define ELT(s, i) ((s "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")[i])
+
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+/* Form a big-endian 16, 32, 64, and 128-byte integer from a string. */
+# define I16(s) (((uint16_t)ELT (s, 0) << 8) + (uint16_t)ELT (s, 1))
+# define I32(s) \
+ (((uint32_t)ELT (s, 0) << 24) \
+ + ((uint32_t)ELT (s, 1) << 16) \
+ + ((uint32_t)ELT (s, 2) << 8) \
+ + (uint32_t)ELT (s, 3))
+# define I64(s) \
+ (((uint64_t)ELT (s, 0) << 56) \
+ + ((uint64_t)ELT (s, 1) << 48) \
+ + ((uint64_t)ELT (s, 2) << 40) \
+ + ((uint64_t)ELT (s, 3) << 32) \
+ + ((uint64_t)ELT (s, 4) << 24) \
+ + ((uint64_t)ELT (s, 5) << 16) \
+ + ((uint64_t)ELT (s, 6) << 8) \
+ + ELT (s, 7))
+# define I128(s) \
+ (((uint128_t)ELT (s, 0) << (64 + 56)) \
+ + ((uint128_t)ELT (s, 1) << (64 + 48)) \
+ + ((uint128_t)ELT (s, 2) << (64 + 40)) \
+ + ((uint128_t)ELT (s, 3) << (64 + 32)) \
+ + ((uint128_t)ELT (s, 4) << (64 + 24)) \
+ + ((uint128_t)ELT (s, 5) << (64 + 16)) \
+ + ((uint128_t)ELT (s, 6) << (64 + 8)) \
+ + ((uint128_t)ELT (s, 7) << 64) \
+ + ((uint128_t)ELT (s, 8) << 56) \
+ + ((uint128_t)ELT (s, 9) << 48) \
+ + ((uint128_t)ELT (s, 10) << 40) \
+ + ((uint128_t)ELT (s, 11) << 32) \
+ + ((uint128_t)ELT (s, 12) << 24) \
+ + ((uint128_t)ELT (s, 13) << 16) \
+ + ((uint128_t)ELT (s, 14) << 8) \
+ + (uint128_t)ELT (s, 15))
+
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+/* Form a little-endian 16, 32, 64, and 128-byte integer from a string. */
+# define I16(s) (((uint16_t)ELT (s, 1) << 8) + (uint16_t)ELT (s, 0))
+# define I32(s) \
+ (((uint32_t)ELT (s, 3) << 24) \
+ + ((uint32_t)ELT (s, 2) << 16) \
+ + ((uint32_t)ELT (s, 1) << 8) \
+ + (uint32_t)ELT (s, 0))
+# define I64(s) \
+ (((uint64_t)ELT (s, 7) << 56) \
+ + ((uint64_t)ELT (s, 6) << 48) \
+ + ((uint64_t)ELT (s, 5) << 40) \
+ + ((uint64_t)ELT (s, 4) << 32) \
+ + ((uint64_t)ELT (s, 3) << 24) \
+ + ((uint64_t)ELT (s, 2) << 16) \
+ + ((uint64_t)ELT (s, 1) << 8) \
+ + ELT (s, 0))
+# define I128(s) \
+ (((uint128_t)ELT (s, 15) << (64 + 56)) \
+ + ((uint128_t)ELT (s, 14) << (64 + 48)) \
+ + ((uint128_t)ELT (s, 13) << (64 + 40)) \
+ + ((uint128_t)ELT (s, 12) << (64 + 32)) \
+ + ((uint128_t)ELT (s, 11) << (64 + 24)) \
+ + ((uint128_t)ELT (s, 10) << (64 + 16)) \
+ + ((uint128_t)ELT (s, 9) << (64 + 8)) \
+ + ((uint128_t)ELT (s, 8) << 64) \
+ + ((uint128_t)ELT (s, 7) << 56) \
+ + ((uint128_t)ELT (s, 6) << 48) \
+ + ((uint128_t)ELT (s, 5) << 40) \
+ + ((uint128_t)ELT (s, 4) << 32) \
+ + ((uint128_t)ELT (s, 3) << 24) \
+ + ((uint128_t)ELT (s, 2) << 16) \
+ + ((uint128_t)ELT (s, 1) << 8) \
+ + (uint128_t)ELT (s, 0))
+#endif
+
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+
+void store_16bit_be (void)
+{
+ T ("xxx", uint16_t, 0, 0x0001, == 0);
+ T ("xxx", uint16_t, 0, 0x0010, == 0);
+ T ("xxx", uint16_t, 0, 0x0011, == 0);
+ T ("xxx", uint16_t, 0, 0x0100, == 1);
+ T ("xxx", uint16_t, 0, 0x1000, == 1);
+ T ("xxx", uint16_t, 0, 0x1100, == 1);
+}
+
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+
+void store_16bit_le (int i)
+{
+ uint16_t x0000 = I16 ("\0\0");
+ uint16_t x0001 = 0x0001;
+ uint16_t x0010 = 0x0010;
+ uint16_t x0011 = 0x0011;
+ uint16_t x0100 = 0x0100;
+ uint16_t x1000 = 0x1000;
+ uint16_t x1100 = 0x1100;
+
+ T (0, uint16_t, 0, x0000, == 0);
+ T ("x", uint16_t, 0, x0000, == 0);
+ T ("xx", uint16_t, 0, x0000, == 0);
+ T ("xxxx", uint16_t, 0, x0000, == 0);
+ T (0, uint16_t, 0, x0001, == 1);
+ T ("\0\0\0", uint16_t, 0, x0001, == 1);
+ T (0, uint16_t, 0, x0010, == 1);
+ T ("x\0\0", uint16_t, 0, x0010, == 1);
+ T (0, uint16_t, 0, x0011, == 1);
+ T ("xx\0", uint16_t, 0, x0011, == 1);
+ T (0, uint16_t, 0, x0100, == 0);
+ T ("\0\0\0", uint16_t, 0, x0100, == 0);
+ T (0, uint16_t, 0, x1000, == 0);
+ T ("x\0\0", uint16_t, 0, x1000, == 0);
+ T (0, uint16_t, 0, x1100, == 0);
+ T ("xx\0", uint16_t, 0, x1100, == 0);
+
+ // FIXME: This fails because of the next test but succeeds on its own.
+ // T (0, uint16_t, 0, i ? x0001 : x0010, == 1);
+ T ("xxx", uint16_t, 0, i ? x0100 : x1100, == 0);
+}
+
+#endif
+
+void store_32bit (volatile int i)
+{
+ T (0, uint32_t, 0, 0, == 0);
+ T ("x", uint32_t, 0, 0, == 0);
+ T ("xx", uint32_t, 0, 0, == 0);
+ T ("xxx", uint32_t, 0, 0, == 0);
+ T ("xxxx", uint32_t, 0, 0, == 0);
+
+ T ("\0", uint32_t, 1, 0, == 0);
+ T ("x", uint32_t, 1, 0, == 1);
+ T ("xx", uint32_t, 2, 0, == 2);
+ T ("xxx", uint32_t, 3, 0, == 3);
+
+ T ("xxx", uint32_t, 0, I32 ("\1\0\0\0"), == 1);
+ T ("xxx", uint32_t, 0, I32 ("\0\1\0\0"), == 0);
+ T ("xxx", uint32_t, 0, I32 ("\0\0\1\0"), == 0);
+ T ("xxx", uint32_t, 0, I32 ("\0\0\0\1"), == 0);
+
+ T ("xxx", uint32_t, 0, I32 ("\1\2\0\0"), == 2);
+ T ("xxx", uint32_t, 0, I32 ("\0\1\2\0"), == 0);
+ T ("xxx", uint32_t, 0, I32 ("\0\0\1\2"), == 0);
+
+ T ("xxx", uint32_t, 0, I32 ("\1\2\3\0"), == 3);
+ T ("xxx", uint32_t, 0, I32 ("\0\1\2\3"), == 0);
+
+ uint32_t x123_ = I32 ("123\0");
+ uint32_t x12__ = I32 ("12\0\0");
+ uint32_t x1___ = I32 ("1\0\0\0");
+
+ // FIXME: Upper bound not implemented yet.
+ /* T ("xxxx", uint32_t, 0, i ? x123_ : x12__, <= 3); */
+ T ("xxxx", uint32_t, 0, i ? x123_ : x12__, >= 2);
+ T ("xxxx", uint32_t, 0, i ? x12__ : x123_, >= 2);
+ /* T ("xxxx", uint32_t, 0, i ? x123_ : x1___, <= 3); */
+ T ("xxxx", uint32_t, 0, i ? x123_ : x1___, >= 1);
+ T ("xxxx", uint32_t, 0, i ? x1___ : x123_, >= 1);
+
+ TX ("abcde", uint32_t, 0, i ? I32 ("1234") : I32 ("1235"), == 5);
+ TX ("abcde", uint32_t, 1, i ? I32 ("1234") : I32 ("1235"), == 5);
+
+ TX ("abcdef", uint32_t, 0, i ? I32 ("1235") : I32 ("1234"), == 6);
+ TX ("abcdef", uint32_t, 1, i ? I32 ("1235") : I32 ("1234"), == 6);
+ TX ("abcdef", uint32_t, 2, i ? I32 ("1235") : I32 ("1234"), == 6);
+ TX ("abcdef", uint32_t, 3, i ? I32 ("124\0") : I32 ("123\0"), == 6);
+ TX ("abcdef", uint32_t, 3, i ? I32 ("12\0\0") : I32 ("13\0\0"), == 5);
+
+ TX ("abcdef", uint32_t, 3, i ? I32 ("12\0\0") : I32 ("123\0"), >= 5);
+ /* FIXME: Upper bound not implemented yet. */
+ /* TX ("abcdef", uint32_t, 3, i ? I32 ("12\0\0") : I32 ("123\0"), < 7); */
+}
+
+void store_64bit (int i)
+{
+ T ("xxxxxxx", uint64_t, 0, I64 ("\1\0\0\0\0\0\0\0\0"), == 1);
+ T ("xxxxxxx", uint64_t, 0, I64 ("\0\1\0\0\0\0\0\0\0"), == 0);
+ T ("xxxxxxx", uint64_t, 0, I64 ("\0\0\1\0\0\0\0\0\0"), == 0);
+ T ("xxxxxxx", uint64_t, 0, I64 ("\0\0\0\1\0\0\0\0\0"), == 0);
+ T ("xxxxxxx", uint64_t, 0, I64 ("\0\0\0\0\1\0\0\0\0"), == 0);
+ T ("xxxxxxx", uint64_t, 0, I64 ("\0\0\0\0\0\1\0\0\0"), == 0);
+ T ("xxxxxxx", uint64_t, 0, I64 ("\0\0\0\0\0\0\1\0\0"), == 0);
+ T ("xxxxxxx", uint64_t, 0, I64 ("\0\0\0\0\0\0\0\1\0"), == 0);
+
+ T ("xxxxxxx", uint64_t, 0, I64 ("\1\2\0\0\0\0\0\0\0"), == 2);
+ T ("xxxxxxx", uint64_t, 0, I64 ("\0\1\2\0\0\0\0\0\0"), == 0);
+ T ("xxxxxxx", uint64_t, 0, I64 ("\0\0\1\2\0\0\0\0\0"), == 0);
+
+ T ("xxxxxxx", uint64_t, 0, I64 ("\1\2\3\0\0\0\0\0\0"), == 3);
+ T ("xxxxxxx", uint64_t, 0, I64 ("\0\1\2\3\0\0\0\0\0"), == 0);
+
+ T ("xxxxxxx", uint64_t, 0, I64 ("\1\2\3\4\0\0\0\0\0"), == 4);
+ T ("xxxxxxx", uint64_t, 0, I64 ("\1\2\3\4\5\0\0\0\0"), == 5);
+ T ("xxxxxxx", uint64_t, 0, I64 ("\1\2\3\4\5\6\0\0\0"), == 6);
+ T ("xxxxxxx", uint64_t, 0, I64 ("\1\2\3\4\5\6\7\0\0"), == 7);
+
+ uint64_t x7777777_ = I64 ("\7\7\7\7\7\7\7");
+ uint64_t x666666__ = I64 ("\6\6\6\6\6\6\0");
+ uint64_t x4444____ = I64 ("\4\4\4\4\0\0\0");
+ uint64_t x4343____ = I64 ("\4\3\4\3\0\0\0");
+ uint64_t x1_______ = I64 ("\1\0\0\0\0\0\0");
+
+ /* FIXME: Upper bound not implemented yet. */
+ /* T ("x\0xxxxxx", uint64_t, 0, i ? x7777777_ : x666666__, <= 7); */
+ T ("xx\0xxxxx", uint64_t, 0, i ? x7777777_ : x666666__, >= 6);
+ T ("xxx\0xxxx", uint64_t, 1, i ? x7777777_ : x666666__, >= 7);
+ /* T ("xxx\0xxxx", uint64_t, 0, i ? x666666__ : x1, <= 6); */
+ T ("xxxx\0xxx", uint64_t, 0, i ? x666666__ : x1_______, >= 1);
+ T ("xxxxxx\0x", uint64_t, 0, i ? x4444____ : x4343____, == 4);
+}
+
+#if __SIZEOF_INT128__
+
+typedef __uint128_t uint128_t;
+
+void store_128bit (void)
+{
+ uint128_t x1 = I128 ("\1");
+ uint128_t x1z1 = I128 ("\0\1");
+ uint128_t x2z1 = I128 ("\0\0\1");
+ uint128_t x3z1 = I128 ("\0\0\0\1");
+ uint128_t x4z1 = I128 ("\0\0\0\0\1");
+ uint128_t x5z1 = I128 ("\0\0\0\0\0\1");
+ uint128_t x6z1 = I128 ("\0\0\0\0\0\0\1");
+ uint128_t x7z1 = I128 ("\0\0\0\0\0\0\0\1");
+ uint128_t x8z1 = I128 ("\0\0\0\0\0\0\0\0\1");
+ uint128_t x9z1 = I128 ("\0\0\0\0\0\0\0\0\0\1");
+ uint128_t x10z1 = I128 ("\0\0\0\0\0\0\0\0\0\0\1");
+ uint128_t x11z1 = I128 ("\0\0\0\0\0\0\0\0\0\0\0\1");
+ uint128_t x12z1 = I128 ("\0\0\0\0\0\0\0\0\0\0\0\0\1");
+ uint128_t x13z1 = I128 ("\0\0\0\0\0\0\0\0\0\0\0\0\0\1");
+ uint128_t x14z1 = I128 ("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1");
+ uint128_t x15z1 = I128 ("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1");
+
+ T ("xxxxxxx", uint128_t, 0, x1, == 1);
+ T ("xxxxxxx", uint128_t, 0, x1z1, == 0);
+ T ("xxxxxxx", uint128_t, 0, x2z1, == 0);
+ T ("xxxxxxx", uint128_t, 0, x3z1, == 0);
+ T ("xxxxxxx", uint128_t, 0, x4z1, == 0);
+ T ("xxxxxxx", uint128_t, 0, x5z1, == 0);
+ T ("xxxxxxx", uint128_t, 0, x6z1, == 0);
+ T ("xxxxxxx", uint128_t, 0, x7z1, == 0);
+ T ("xxxxxxx", uint128_t, 0, x8z1, == 0);
+ T ("xxxxxxx", uint128_t, 0, x9z1, == 0);
+ T ("xxxxxxx", uint128_t, 0, x10z1, == 0);
+ T ("xxxxxxx", uint128_t, 0, x11z1, == 0);
+ T ("xxxxxxx", uint128_t, 0, x12z1, == 0);
+ T ("xxxxxxx", uint128_t, 0, x13z1, == 0);
+ T ("xxxxxxx", uint128_t, 0, x14z1, == 0);
+ T ("xxxxxxx", uint128_t, 0, x15z1, == 0);
+
+ T ("xxxxxxx", uint128_t, 0, I128 ("\2\1"), == 2);
+ T ("xxxxxxx", uint128_t, 0, I128 ("\0\2\1"), == 0);
+
+ T ("xxxxxxx", uint128_t, 0, I128 ("\3\2\1"), == 3);
+ T ("xxxxxxx", uint128_t, 0, I128 ("\0\3\2\1"), == 0);
+
+ T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4"), == 4);
+ T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5"), == 5);
+ T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6"), == 6);
+ T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7"), == 7);
+ T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10"), == 8);
+ T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10\11"), == 9);
+ T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10\11\12"), == 10);
+ T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10\11\12\13"), == 11);
+ T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10\11\12\13\14"), == 12);
+ T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10\11\12\13\14\15"), == 13);
+ T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10\11\12\13\14\15\16"), == 14);
+ T ("xxxxxxx", uint128_t, 0, I128 ("\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17"), == 15);
+}
+
+#endif // __SIZEOF_INT128__
+
+/* { dg-final { scan-tree-dump-times "strlen" 0 "optimized" } }
+ { dg-final { scan-tree-dump-times "_not_eliminated_" 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/strlenopt-71.c b/gcc/testsuite/gcc.dg/strlenopt-71.c
new file mode 100644
index 0000000..fd4c4a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-71.c
@@ -0,0 +1,223 @@
+/* PR tree-optimization/91183 - strlen of a strcpy result with a conditional
+ source not folded
+ Runtime test to verify that multibyte stores are handled correctly.
+ { dg-do run }
+ { dg-options "-O2 -Wall" } */
+
+#include "strlenopt.h"
+
+#define CHAR_BIT __CHAR_BIT__
+
+typedef __UINT16_TYPE__ uint16_t;
+typedef __UINT32_TYPE__ uint32_t;
+
+#define NOIPA __attribute__ ((noclone, noinline, noipa))
+
+/* Prevent the optimizer from detemining invariants from prior tests. */
+NOIPA void terminate (void)
+{
+ __builtin_abort ();
+}
+
+#define VERIFY(expr, str) \
+ do { \
+ const unsigned expect = strlen (str); \
+ const unsigned len = strlen (expr); \
+ if (len != expect) \
+ { \
+ __builtin_printf ("line %i: strlen(%s) == %u failed: " \
+ "got %u with a = \"%.*s\"\n", \
+ __LINE__, #expr, expect, len, \
+ (int)sizeof a, a); \
+ terminate (); \
+ } \
+ if (memcmp (a, str, expect + 1)) \
+ { \
+ __builtin_printf ("line %i: expected string \"%s\", " \
+ "got a = \"%.*s\"\n", \
+ __LINE__, str, (int)sizeof a, a); \
+ terminate (); \
+ } \
+ } while (0)
+
+
+#define ELT(s, i) ((s "\0\0\0\0")[i])
+
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+# define I16(s) (((uint16_t)ELT (s, 0) << 8) + (uint16_t)ELT (s, 1))
+# define I32(s) \
+ (((uint32_t)ELT (s, 0) << 24) \
+ + ((uint32_t)ELT (s, 1) << 16) \
+ + ((uint32_t)ELT (s, 2) << 8) \
+ + (uint32_t)ELT (s, 3))
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+# define I16(s) (((uint16_t)ELT (s, 1) << 8) + (uint16_t)ELT (s, 0))
+# define I32(s) \
+ (((uint32_t)ELT (s, 3) << 24) \
+ + ((uint32_t)ELT (s, 2) << 16) \
+ + ((uint32_t)ELT (s, 1) << 8) \
+ + (uint32_t)ELT (s, 0))
+#endif
+
+char a[32];
+
+NOIPA void
+i16_1 (void)
+{
+ *(uint16_t*)a = I16 ("12");
+ *(uint16_t*)(a + 2) = I16 ("3");
+ VERIFY (a, "123");
+
+ *(uint16_t*)(a + 1) = I16 ("23");
+ VERIFY (a, "123");
+
+ *(uint16_t*)(a) = I16 ("12");
+ VERIFY (a, "123");
+
+ *(uint16_t*)(a + 1) = I16 ("2");
+ VERIFY (a, "12");
+
+ *(uint16_t*)(a + 3) = I16 ("45");
+ *(uint16_t*)(a + 2) = I16 ("34");
+ VERIFY (a, "12345");
+}
+
+NOIPA void
+i16_2 (void)
+{
+ strcpy (a, "12");
+ strcat (a, "34");
+
+ *(uint16_t*)a = I16 ("12");
+ VERIFY (a, "1234");
+
+ *(uint16_t*)(a + 1) = I16 ("12");
+ VERIFY (a, "1124");
+
+ *(uint16_t*)(a + 2) = I16 ("12");
+ VERIFY (a, "1112");
+
+ *(uint16_t*)(a + 3) = I16 ("12");
+ VERIFY (a, "11112");
+
+ *(uint16_t*)(a + 4) = I16 ("12");
+ VERIFY (a, "111112");
+}
+
+
+NOIPA void
+i32_1 (void)
+{
+ *(uint32_t*)a = I32 ("1234");
+ VERIFY (a, "1234");
+
+ *(uint32_t*)(a + 1) = I32 ("2345");
+ VERIFY (a, "12345");
+}
+
+NOIPA void
+i32_2 (void)
+{
+ strcpy (a, "12");
+ strcat (a, "34");
+
+ *(uint32_t*)a = I32 ("1234");
+ VERIFY (a, "1234");
+
+ *(uint32_t*)(a + 4) = I32 ("567");
+ VERIFY (a, "1234567");
+
+ *(uint32_t*)(a + 7) = I32 ("89\0");
+ VERIFY (a, "123456789");
+
+ *(uint32_t*)(a + 3) = I32 ("4567");
+ VERIFY (a, "123456789");
+
+ *(uint32_t*)(a + 2) = I32 ("3456");
+ VERIFY (a, "123456789");
+
+ *(uint32_t*)(a + 1) = I32 ("2345");
+ VERIFY (a, "123456789");
+}
+
+
+NOIPA void
+i32_3 (void)
+{
+ strcpy (a, "1234");
+ strcat (a, "5678");
+
+ *(uint32_t*)a = I32 ("1234");
+ VERIFY (a, "12345678");
+
+ *(uint32_t*)(a + 1) = I32 ("234");
+ VERIFY (a, "1234");
+
+ *(uint32_t*)(a + 2) = I32 ("3456");
+ VERIFY (a, "12345678");
+
+ *(uint32_t*)(a + 3) = I32 ("4567");
+ VERIFY (a, "12345678");
+
+ *(uint32_t*)(a + 4) = I32 ("5678");
+ VERIFY (a, "12345678");
+
+ *(uint32_t*)(a + 5) = I32 ("6789");
+ VERIFY (a, "123456789");
+
+ *(uint32_t*)(a + 6) = I32 ("789A");
+ VERIFY (a, "123456789A");
+}
+
+volatile int vzero = 0;
+
+NOIPA void
+i32_4 (void)
+{
+ strcpy (a, "1234");
+ strcat (a, "5678");
+
+ *(uint32_t*)a = vzero ? I32 ("1\0\0\0") : I32 ("1234");
+ VERIFY (a, "12345678");
+
+ *(uint32_t*)a = vzero ? I32 ("12\0\0") : I32 ("1234");
+ VERIFY (a, "12345678");
+
+ *(uint32_t*)a = vzero ? I32 ("123\0") : I32 ("1234");
+ VERIFY (a, "12345678");
+
+ *(uint32_t*)a = vzero ? I32 ("1234") : I32 ("1234");
+ VERIFY (a, "12345678");
+
+ *(uint32_t*)a = vzero ? I32 ("1235") : I32 ("1234");
+ VERIFY (a, "12345678");
+
+ *(uint32_t*)a = vzero ? I32 ("1234") : I32 ("123\0");
+ VERIFY (a, "123");
+
+ *(uint32_t*)(a + 3) = vzero ? I32 ("456\0") : I32 ("4567");
+ VERIFY (a, "12345678");
+}
+
+
+int main ()
+{
+ memset (a, 0, sizeof a);
+ i16_1 ();
+
+ memset (a, 0, sizeof a);
+ i16_2 ();
+
+
+ memset (a, 0, sizeof a);
+ i32_1 ();
+
+ memset (a, 0, sizeof a);
+ i32_2 ();
+
+ memset (a, 0, sizeof a);
+ i32_3 ();
+
+ memset (a, 0, sizeof a);
+ i32_4 ();
+}
diff --git a/gcc/testsuite/gcc.dg/strlenopt-72.c b/gcc/testsuite/gcc.dg/strlenopt-72.c
new file mode 100644
index 0000000..9c00a95
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-72.c
@@ -0,0 +1,69 @@
+/* PR tree-optimization/91183 - strlen of a strcpy result with a conditional
+ source not folded
+ Test to verify that strlen can determine string lengths from wider stores
+ than narrow characters. This matters because on targets that can handle
+ unaligned stores and where GCC lowers multi-character stores into smaller
+ numbers of wider stores.
+ { dg-do compile }
+ { dg-options "-O2 -fdump-tree-optimized" }
+ On strictly aligned targets the consecutive char assignments used
+ by the test aren't merged. When they involve multiple trailing nuls
+ these assignments then defeat the strlen optimization as a result of
+ pr83821. When the bug is resolved the directive below can be removed.
+ { dg-require-effective-target non_strict_align } */
+
+#include "strlenopt.h"
+
+#define CAT(x, y) x ## y
+#define CONCAT(x, y) CAT (x, y)
+#define FAILNAME(name) CONCAT (call_ ## name ##_on_line_, __LINE__)
+
+#define FAIL(name) do { \
+ extern void FAILNAME (name) (void); \
+ FAILNAME (name)(); \
+ } while (0)
+
+/* Macros to emit a call to function named
+ call_failed_to_be_eliminated_on_line_NNN()
+ for each call that's expected to be eliminated. The dg-final
+ scan-tree-dump-time directive at the bottom of the test verifies
+ that no such call appears in output. */
+#define ELIM(expr) \
+ if ((expr)) FAIL (not_eliminated); else (void)0
+
+#undef T
+#define T(N, ncpy, expect, assign) do { \
+ char a[N], b[N]; \
+ assign; \
+ memcpy (b, a, ncpy); \
+ ELIM (!(expect == strlen (b))); \
+ } while (0)
+
+void test_copy (void)
+{
+ T (2, 1, 0, (a[0] = 0));
+ T (2, 2, 0, (a[0] = 0, a[1] = 0));
+ T (2, 2, 1, (a[0] = '1', a[1] = 0));
+ T (4, 3, 2, (a[0] = '1', a[1] = '2', a[2] = 0));
+ // Not handled due to pr83821:
+ // T (4, 3, 1, (a[0] = '1', a[1] = 0, a[2] = '2'));
+ T (4, 2, 1, (a[0] = '1', a[1] = 0, a[2] = 0, a[3] = 0));
+ // Not handled due to pr83821:
+ // T (4, 3, 1, (a[0] = '1', a[1] = 0, a[2] = 0, a[3] = 0));
+ T (4, 4, 1, (a[0] = '1', a[1] = 0, a[2] = 0, a[3] = 0));
+ T (4, 3, 2, (a[0] = '1', a[1] = '2', a[2] = 0, a[3] = 0));
+ T (4, 4, 2, (a[0] = '1', a[1] = '2', a[2] = 0, a[3] = 0));
+ T (4, 4, 3, (a[0] = '1', a[1] = '2', a[2] = '3', a[3] = 0));
+ T (5, 4, 1, (a[0] = '1', a[1] = 0, a[2] = 0, a[3] = 0));
+ T (5, 4, 2, (a[0] = '1', a[1] = '2', a[2] = 0, a[3] = 0));
+ T (5, 4, 3, (a[0] = '1', a[1] = '2', a[2] = '3', a[3] = 0));
+ // Not handled:
+ // T (5, 5, 1, (a[0] = '1', a[1] = 0, a[2] = 0, a[3] = 0, a[4] = 0));
+ // T (5, 5, 2, (a[0] = '1', a[1] = '2', a[2] = 0, a[3] = 0, a[4] = 0));
+ // T (5, 5, 3, (a[0] = '1', a[1] = '2', a[2] = '3', a[3] = 0, a[4] = 0));
+ T (5, 5, 4, (a[0] = '1', a[1] = '2', a[2] = '3', a[3] = '4', a[4] = 0));
+}
+
+
+/* { dg-final { scan-tree-dump-times "strlen" 0 "optimized" } }
+ { dg-final { scan-tree-dump-times "_not_eliminated_" 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/strlenopt-73.c b/gcc/testsuite/gcc.dg/strlenopt-73.c
new file mode 100644
index 0000000..d3c3f05
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-73.c
@@ -0,0 +1,135 @@
+/* PR tree-optimization/91183 - strlen of a strcpy result with a conditional
+ source not folded
+ Test to verify that strlen can determine string lengths from stores
+ involving PHI nodes with distinct strings of the same length of at
+ least 16 bytes.
+
+ { dg-do compile }
+ { dg-options "-O2 -fdump-tree-optimized" }
+ On strictly aligned targets the consecutive char assignments used
+ by the test aren't merged. When they involve multiple trailing nuls
+ these assignments then defeat the strlen optimization as a result of
+ pr83821. When the bug is resolved the directive below can be removed.
+ { dg-require-effective-target non_strict_align } */
+
+#include "strlenopt.h"
+
+#define CAT(x, y) x ## y
+#define CONCAT(x, y) CAT (x, y)
+#define FAILNAME(name) CONCAT (call_ ## name ##_on_line_, __LINE__)
+
+#define FAIL(name) do { \
+ extern void FAILNAME (name) (void); \
+ FAILNAME (name)(); \
+ } while (0)
+
+/* Macros to emit a call to function named
+ call_failed_to_be_eliminated_on_line_NNN()
+ for each call that's expected to be eliminated. The dg-final
+ scan-tree-dump-time directive at the bottom of the test verifies
+ that no such call appears in output. */
+#define ELIM(expr) \
+ if ((expr)) FAIL (not_eliminated); else (void)0
+
+#define T(expect, N, ncpy, cond) do { \
+ char CONCAT (arr_, __LINE__)[N]; \
+ char *pa = CONCAT (arr_, __LINE__); \
+ memcpy (pa, cond, ncpy); \
+ ELIM (!(expect strlen (pa))); \
+ sink (pa); \
+ } while (0)
+
+void sink (void*);
+
+const char a32[33] = "0123456789abcdef0123456789abcdef";
+const char b32[33] = "fedcba9876543210fedcba9876543210";
+
+const char a16[33] = "0123456789abcdef";
+const char b16[33] = "fedcba9876543210";
+
+int i0, i1, i2;
+
+void test_copy_cond_equal_length (void)
+{
+ // The test below is represented as this:
+ // # iftmp.0_3 = PHI <&b16(2), &a16(3)>
+ // MEM <unsigned char[17]> [(char * {ref-all})&a]
+ // = MEM <unsigned char[17]> [(char * {ref-all})iftmp.0_3];
+ // _2 = strlen (&a);
+ T (16 ==, 17, 17, i0 ? a16 : b16);
+ T (16 ==, 17, 17, i0 ? a16 : b16);
+ T (15 ==, 17, 16, (i0 ? a16 : b16) + 1);
+ T (14 ==, 17, 15, (i0 ? a16 : b16) + 2);
+ T ( 0 ==, 17, 1, (i0 ? a16 : b16) + 16);
+
+ T (31 ==, 33, 32, (i0 ? a32 : b32) + 1);
+ T (30 ==, 33, 31, (i0 ? a32 : b32) + 2);
+ T (29 ==, 33, 30, (i0 ? a32 : b32) + 3);
+ T ( 1 ==, 33, 2, (i0 ? a32 : b32) + 31);
+ T ( 0 ==, 33, 1, (i0 ? a32 : b32) + 32);
+}
+
+
+const char a4[16] = "0123";
+const char b4[16] = "3210";
+
+void test_copy_cond_unequal_length_i64 (void)
+{
+ T (2 <, 16, 8, i0 ? a4 + 1 : b4 + 0);
+ T (1 <, 16, 8, i0 ? a4 + 1 : b4 + 2);
+ T (0 <, 16, 8, i0 ? a4 + 1 : b4 + 3);
+
+ T (1 <, 16, 8, i0 ? a4 + 2 : b4 + 0);
+ T (1 <, 16, 8, i0 ? a4 + 2 : b4 + 1);
+ T (0 <, 16, 8, i0 ? a4 + 2 : b4 + 3);
+}
+
+
+#if __i386__ && __SIZEOF_INT128__ == 16
+
+/* The following tests assume GCC transforms the memcpy calls into
+ int128_t assignments which it does only on targets that define
+ the MOVE_MAX macro to 16. That's only spu, s390, and i386 with
+ int128_t support. */
+
+const char a8[32] = "01234567";
+const char b8[32] = "76543210";
+
+void test_copy_cond_unequal_length_i128 (void)
+{
+ T (6 <, 32, 16, i0 ? a8 + 1 : b8 + 0);
+ T (5 <, 32, 16, i0 ? a8 + 1 : b8 + 2);
+ T (4 <, 32, 16, i0 ? a8 + 1 : b8 + 3);
+ T (3 <, 32, 16, i0 ? a8 + 1 : b8 + 4);
+ T (2 <, 32, 16, i0 ? a8 + 1 : b8 + 5);
+ T (1 <, 32, 16, i0 ? a8 + 1 : b8 + 6);
+ T (0 <, 32, 16, i0 ? a8 + 1 : b8 + 7);
+
+ T (5 <, 32, 16, i0 ? a8 + 2 : b8 + 0);
+ T (5 <, 32, 16, i0 ? a8 + 2 : b8 + 1);
+ T (3 <, 32, 16, i0 ? a8 + 2 : b8 + 3);
+ T (2 <, 32, 16, i0 ? a8 + 2 : b8 + 4);
+ T (1 <, 32, 16, i0 ? a8 + 2 : b8 + 5);
+ T (0 <, 32, 16, i0 ? a8 + 2 : b8 + 6);
+
+ T (4 <, 32, 16, i0 ? a8 + 3 : b8 + 0);
+ T (4 <, 32, 16, i0 ? a8 + 3 : b8 + 1);
+ T (4 <, 32, 16, i0 ? a8 + 3 : b8 + 2);
+ T (3 <, 32, 16, i0 ? a8 + 3 : b8 + 4);
+ T (2 <, 32, 16, i0 ? a8 + 3 : b8 + 5);
+ T (1 <, 32, 16, i0 ? a8 + 3 : b8 + 6);
+ T (0 <, 32, 16, i0 ? a8 + 3 : b8 + 7);
+
+ T (3 <, 32, 16, i0 ? a8 + 4 : b8 + 0);
+ T (3 <, 32, 16, i0 ? a8 + 4 : b8 + 1);
+ T (3 <, 32, 16, i0 ? a8 + 4 : b8 + 2);
+ T (3 <, 32, 16, i0 ? a8 + 4 : b8 + 3);
+ T (2 <, 32, 16, i0 ? a8 + 4 : b8 + 5);
+ T (1 <, 32, 16, i0 ? a8 + 4 : b8 + 6);
+ T (0 <, 32, 16, i0 ? a8 + 4 : b8 + 7);
+}
+
+#endif /* Support for i128_t stores. */
+
+/* { dg-final { scan-tree-dump-times "strlen" 0 "optimized" } }
+ { dg-final { scan-tree-dump-times "_not_eliminated_" 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/strlenopt-74.c b/gcc/testsuite/gcc.dg/strlenopt-74.c
new file mode 100644
index 0000000..0a9ac6c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-74.c
@@ -0,0 +1,175 @@
+/* PR tree-optimization/91294 - wrong strlen result of a conditional with
+ an offset
+ { dg-do run }
+ { dg-options "-O2 -Wall" } */
+
+#include "strlenopt.h"
+
+#define NOIPA __attribute__ ((noclone, noinline, noipa))
+
+#define CAT(a, b) a ## b
+#define CONCAT(a, b) CAT (a, b)
+#define UNIQ_NAME(name) CONCAT (name, __LINE__)
+
+extern int last_line;
+int nfails;
+
+char buf[32];
+
+#define VERIFY(expr, nbytes, expect) \
+ NOIPA void UNIQ_NAME (test_)(void) \
+ { \
+ memcpy (buf, (expr), (nbytes)); \
+ const size_t len = strlen (buf); \
+ if (len != expect) \
+ { \
+ ++nfails; \
+ __builtin_printf ("line %i: strlen(%s) == %zu failed: " \
+ "got %zu\n", \
+ __LINE__ - 1000 + last_line + 2, \
+ #expr, (size_t)expect, \
+ len); \
+ } \
+ } typedef void DummyType
+
+const char a8[12] = "01234567";
+const char b8[12] = "76543210";
+const char c4[12] = "0123";
+
+int i0, i1 = 1, i2 = 2;
+
+int last_line = __LINE__;
+#line 1000
+VERIFY (i0 ? (a8 + 0) : (b8 + 0), 9, 8);
+VERIFY (i0 ? (a8 + 0) : (b8 + 1), 8, 7);
+VERIFY (i0 ? (a8 + 0) : (b8 + 2), 8, 6);
+VERIFY (i0 ? (a8 + 0) : (b8 + 2), 7, 6);
+VERIFY (i0 ? (a8 + 0) : (b8 + 3), 8, 5);
+VERIFY (i0 ? (a8 + 0) : (b8 + 3), 7, 5);
+VERIFY (i0 ? (a8 + 0) : (b8 + 3), 6, 5);
+VERIFY (i0 ? (a8 + 0) : (b8 + 4), 8, 4);
+VERIFY (i0 ? (a8 + 0) : (b8 + 4), 7, 4);
+VERIFY (i0 ? (a8 + 0) : (b8 + 4), 6, 4);
+VERIFY (i0 ? (a8 + 0) : (b8 + 4), 5, 4);
+VERIFY (i0 ? (a8 + 0) : (b8 + 5), 7, 3);
+VERIFY (i0 ? (a8 + 0) : (b8 + 5), 6, 3);
+VERIFY (i0 ? (a8 + 0) : (b8 + 5), 5, 3);
+VERIFY (i0 ? (a8 + 0) : (b8 + 5), 4, 3);
+VERIFY (i0 ? (a8 + 0) : (b8 + 6), 3, 2);
+VERIFY (i0 ? (a8 + 0) : (b8 + 7), 2, 1);
+VERIFY (i0 ? (a8 + 1) : (b8 + 0), 8, 8);
+VERIFY (i0 ? (a8 + 2) : (b8 + 0), 7, 7);
+VERIFY (i0 ? (a8 + 1) : (b8 + 1), 8, 7);
+VERIFY (i0 ? (a8 + 1) : (b8 + 2), 7, 6);
+VERIFY (i0 ? (a8 + 2) : (b8 + 1), 8, 7); // FAIL
+VERIFY (i0 ? (a8 + 2) : (b8 + 2), 7, 6);
+VERIFY (i0 ? (a8 + 0) : (b8 + 0), 9, 8);
+VERIFY (i0 ? (a8 + 0) : (b8 + 1), 8, 7);
+VERIFY (i0 ? (a8 + 0) : (b8 + 2), 7, 6);
+VERIFY (i0 ? (a8 + 1) : (b8 + 0), 9, 8);
+VERIFY (i0 ? (a8 + 2) : (b8 + 0), 9, 8);
+VERIFY (i0 ? (a8 + 1) : (b8 + 1), 8, 7);
+VERIFY (i0 ? (a8 + 1) : (b8 + 2), 7, 6);
+VERIFY (i0 ? (a8 + 2) : (b8 + 1), 8, 7); // FAIL
+VERIFY (i0 ? (a8 + 2) : (b8 + 2), 7, 6);
+VERIFY (i0 ? (a8 + 0) : (c4 + 0), 9, 4);
+VERIFY (i0 ? (a8 + 0) : (c4 + 1), 9, 3);
+VERIFY (i0 ? (a8 + 0) : (c4 + 3), 9, 1);
+VERIFY (i0 ? (a8 + 0) : (c4 + 4), 9, 0);
+VERIFY (i0 ? (a8 + 1) : (c4 + 0), 8, 4);
+VERIFY (i0 ? (a8 + 1) : (c4 + 1), 8, 3);
+VERIFY (i0 ? (a8 + 1) : (c4 + 2), 8, 2);
+VERIFY (i0 ? (a8 + 1) : (c4 + 3), 8, 1);
+VERIFY (i0 ? (a8 + 1) : (c4 + 4), 8, 0);
+VERIFY (i0 ? (a8 + 2) : (c4 + 0), 8, 4);
+VERIFY (i0 ? (a8 + 2) : (c4 + 1), 8, 3);
+VERIFY (i0 ? (a8 + 2) : (c4 + 2), 8, 2);
+VERIFY (i0 ? (a8 + 2) : (c4 + 3), 8, 1);
+VERIFY (i0 ? (a8 + 2) : (c4 + 4), 8, 0);
+VERIFY ((i0 ? a8 : b8) + 1, 8, 7);
+VERIFY ((i0 ? a8 : b8) + 2, 8, 6);
+VERIFY ((i0 ? a8 : b8) + 2, 7, 6);
+VERIFY ((i0 ? a8 : b8) + 3, 3, 3);
+VERIFY ((i0 ? a8 : b8) + 3, 1, 1);
+VERIFY ((i0 ? a8 : c4) + 1, 8, 3);
+VERIFY ((i0 ? a8 : c4) + 3, 8, 1);
+VERIFY ((i0 ? a8 : c4) + 4, 8, 0);
+VERIFY ((i0 ? a8 + 1: b8 + 2) + 1, 9, 5);
+VERIFY ((i0 ? a8 + i1: b8 + i2) + 1, 8, 5);
+VERIFY ((i0 ? a8 + i1: b8 + 2) + 1, 8, 5);
+VERIFY ((i0 ? a8 + i2: b8 + i1) + 1, 8, 6);
+VERIFY ((i0 ? a8 + 2: b8 + i1) + 1, 8, 6);
+
+#define T(N) test_ ## N (); memset (buf, 0, sizeof buf)
+
+int main (void)
+{
+ T (1000);
+ T (1001);
+ T (1002);
+ T (1003);
+ T (1004);
+ T (1005);
+ T (1006);
+ T (1007);
+ T (1008);
+ T (1009);
+
+ T (1010);
+ T (1011);
+ T (1012);
+ T (1013);
+ T (1014);
+ T (1015);
+ T (1016);
+ T (1017);
+ T (1018);
+ T (1019);
+
+ T (1020);
+ T (1021);
+ T (1022);
+ T (1023);
+ T (1024);
+ T (1025);
+ T (1026);
+ T (1027);
+ T (1028);
+ T (1029);
+
+ T (1030);
+ T (1031);
+ T (1032);
+ T (1033);
+ T (1034);
+ T (1035);
+ T (1036);
+ T (1037);
+ T (1038);
+ T (1039);
+
+ T (1040);
+ T (1041);
+ T (1042);
+ T (1043);
+ T (1044);
+ T (1045);
+ T (1046);
+ T (1047);
+ T (1048);
+ T (1049);
+
+ T (1050);
+ T (1051);
+ T (1052);
+ T (1053);
+ T (1054);
+ T (1055);
+ T (1056);
+ T (1057);
+ T (1058);
+
+ if (nfails)
+ abort ();
+}
+
diff --git a/gcc/testsuite/gcc.dg/strlenopt-75.c b/gcc/testsuite/gcc.dg/strlenopt-75.c
new file mode 100644
index 0000000..e57f0c4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-75.c
@@ -0,0 +1,118 @@
+/* PR tree-optimization/91294 - strlen result of a conditional with
+ an offset
+ { dg-do run }
+ { dg-options "-O2 -Wall" } */
+
+#include "strlenopt.h"
+
+#define NOIPA __attribute__ ((noclone, noinline, noipa))
+
+int i = 0;
+
+const char s[] = "1234567";
+
+char a[32];
+
+/* Exercise a memcpy overwriting a destination string of known length
+ with a source argument involving a conditional expression with strings
+ of unqual lengths, with the selected one being the longer of the two
+ and resulting in no change to the length of the overwritten destination
+ string. */
+NOIPA void test_memcpy_same_length ()
+{
+ memcpy (a, "123456789a", 11);
+ memcpy (a + 6, i ? "78\0" : "789\0", 4);
+ if (strlen (a) != 9)
+ abort ();
+}
+
+/* Same as above but with strcpy/strcat. */
+
+NOIPA void test_strcpy_strcat_same_length ()
+{
+ strcpy (a, "12345678");
+ strcat (a, "9a");
+ memcpy (a + 6, i ? "78\0" : "789\0", 4);
+ if (strlen (a) != 9)
+ abort ();
+}
+
+/* Same as above but using a memcpy of a power-of-two size that gets
+ (on some targets) transformed into a single MEM_REF assignment. */
+
+NOIPA void test_assign_same_length ()
+{
+ memcpy (a, s, 8);
+ memcpy (a + 5, i ? "67\0" : "678\0", 4);
+ if (strlen (a) != 8)
+ abort ();
+}
+
+/* Same as above but resulting in increasing the length of the destination
+ string. */
+
+NOIPA void test_memcpy_lengthen ()
+{
+ memcpy (a, "123456789a", 11);
+ memcpy (a + 8, i ? "9a\0" : "9ab\0", 4);
+ if (strlen (a) != 11)
+ abort ();
+}
+
+NOIPA void test_strcpy_strcat_lengthen ()
+{
+ strcpy (a, "12345678");
+ strcat (a, "9a");
+ memcpy (a + 8, i ? "9a\0" : "9ab\0", 4);
+ if (strlen (a) != 11)
+ abort ();
+}
+
+NOIPA void test_assign_lengthen ()
+{
+ memcpy (a, s, 8);
+ memcpy (a + 6, i ? "78\0" : "789\0", 4);
+ if (strlen (a) != 9)
+ abort ();
+}
+
+NOIPA void test_memcpy_shorten ()
+{
+ memcpy (a, "123456789a", 11);
+ memcpy (a + 6, i ? "789\0" : "78\0", 4);
+ if (strlen (a) != 8)
+ abort ();
+}
+
+NOIPA void test_strcpy_strcat_shorten ()
+{
+ strcpy (a, "12345678");
+ strcat (a, "9a");
+ memcpy (a + 6, i ? "789\0" : "78\0", 4);
+ if (strlen (a) != 8)
+ abort ();
+}
+
+NOIPA void test_assign_shorten ()
+{
+ memcpy (a, s, 8);
+ memcpy (a + 6, i ? "789\0" : "78\0", 4);
+ if (strlen (a) != 8)
+ abort ();
+}
+
+
+int main (void)
+{
+ test_memcpy_same_length ();
+ test_strcpy_strcat_same_length ();
+ test_assign_same_length ();
+
+ test_memcpy_lengthen ();
+ test_strcpy_strcat_lengthen ();
+ test_assign_lengthen ();
+
+ test_memcpy_shorten ();
+ test_strcpy_strcat_shorten ();
+ test_assign_shorten ();
+}
diff --git a/gcc/testsuite/gcc.dg/strlenopt-76.c b/gcc/testsuite/gcc.dg/strlenopt-76.c
new file mode 100644
index 0000000..30ccd16
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-76.c
@@ -0,0 +1,174 @@
+/* PR tree-optimization/91294 - strlen result of a conditional with
+ an offset
+ { dg-do run }
+ { dg-options "-O2 -Wall" } */
+
+#include "strlenopt.h"
+
+#define NOIPA __attribute__ ((noclone, noinline, noipa))
+
+#define assert(expr) \
+ ((expr) \
+ ? (void)0 \
+ : (__builtin_printf ("line %i %s: assertion failed: %s\n", \
+ __LINE__, __func__, #expr), \
+ __builtin_abort ()))
+
+int i = 0;
+
+const char s[] = "1234567";
+
+char a[32];
+
+NOIPA void lower_bound_assign_into_empty (void)
+{
+ a[0] = '1';
+ a[1] = '2';
+ a[2] = '3';
+ assert (strlen (a) == 3);
+}
+
+NOIPA void lower_bound_assign_into_longest (void)
+{
+ a[0] = '1';
+ a[1] = '2';
+ a[2] = '3';
+ assert (strlen (a) == 31);
+}
+
+
+NOIPA void lower_bound_assign_into_empty_idx_3 (int idx)
+{
+ a[0] = '1';
+ a[1] = '2';
+ a[2] = '3';
+ a[idx] = 'x';
+ assert (strlen (a) == 4);
+}
+
+NOIPA void lower_bound_assign_into_longest_idx_2 (int idx)
+{
+ a[0] = '1';
+ a[1] = '2';
+ a[2] = '3';
+ a[idx] = '\0';
+ assert (strlen (a) == 2);
+}
+
+
+NOIPA void lower_bound_memcpy_into_empty (void)
+{
+ memcpy (a, "123", 3);
+ assert (strlen (a) == 3);
+}
+
+NOIPA void lower_bound_memcpy_into_longest (void)
+{
+ memcpy (a, "123", 3);
+ assert (strlen (a) == 31);
+}
+
+
+NOIPA void lower_bound_memcpy_memcpy_into_empty (void)
+{
+ memcpy (a, "123", 3);
+ memcpy (a + 2, "345", 3);
+ assert (strlen (a) == 5);
+}
+
+NOIPA void lower_bound_memcpy_memcpy_into_longest (void)
+{
+ memcpy (a, "123", 3);
+ memcpy (a + 2, "345", 3);
+ assert (strlen (a) == 31);
+}
+
+
+NOIPA void memove_forward_strlen (void)
+{
+ char a[] = "123456";
+
+ memmove (a, a + 1, sizeof a - 1);
+
+ assert (strlen (a) == 5);
+}
+
+NOIPA void memove_backward_into_empty_strlen (void)
+{
+ strcpy (a, "123456");
+
+ memmove (a + 1, a, 6);
+
+ assert (strlen (a) == 7);
+}
+
+NOIPA void memove_backward_into_longest_strlen (void)
+{
+ memcpy (a, "123456", 6);
+
+ memmove (a + 1, a, 6);
+
+ assert (strlen (a) == 31);
+}
+
+NOIPA void memove_strcmp (void)
+{
+ /* Test derived from libstdc++-v3's
+ 20_util/specialized_algorithms/memory_management_tools/1.cc */
+
+ char a[] = "123456";
+ char b[] = "000000";
+
+ memmove (b, a, sizeof a);
+
+ assert (strlen (a) == 6);
+ assert (strlen (b) == 6);
+ assert (strcmp (a, b) == 0);
+}
+
+
+int main (void)
+{
+ memset (a, '\0', sizeof a);
+ lower_bound_assign_into_empty ();
+
+ memset (a, 'x', sizeof a - 1);
+ a[sizeof a - 1] = '\0';
+ lower_bound_assign_into_longest ();
+
+ memset (a, '\0', sizeof a);
+ lower_bound_assign_into_empty_idx_3 (3);
+
+ memset (a, 'x', sizeof a - 1);
+ a[sizeof a - 1] = '\0';
+ lower_bound_assign_into_longest_idx_2 (2);
+
+ memset (a, '\0', sizeof a);
+ lower_bound_memcpy_into_empty ();
+
+ memset (a, 'x', sizeof a - 1);
+ a[sizeof a - 1] = '\0';
+ lower_bound_memcpy_into_longest ();
+
+ memset (a, 'x', sizeof a - 1);
+ a[sizeof a - 1] = '\0';
+ lower_bound_memcpy_into_longest ();
+
+ memset (a, '\0', sizeof a);
+ lower_bound_memcpy_memcpy_into_empty ();
+
+ memset (a, 'x', sizeof a - 1);
+ a[sizeof a - 1] = '\0';
+ lower_bound_memcpy_memcpy_into_longest ();
+
+ memove_forward_strlen ();
+
+ memset (a, '\0', sizeof a);
+ memove_backward_into_empty_strlen ();
+
+ memset (a, 'x', sizeof a - 1);
+ a[sizeof a - 1] = '\0';
+ memove_backward_into_longest_strlen ();
+
+ memove_strcmp ();
+}
diff --git a/gcc/testsuite/gcc.dg/strlenopt-77.c b/gcc/testsuite/gcc.dg/strlenopt-77.c
new file mode 100644
index 0000000..76cd11d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-77.c
@@ -0,0 +1,84 @@
+/* PR tree-optimization/91315 - missing strlen lower bound of a string
+ known to be at least N characters
+ { dg-do compile }
+ { dg-options "-O2 -Wall -fdump-tree-optimized" } */
+
+#include "strlenopt.h"
+
+#define CAT(x, y) x ## y
+#define CONCAT(x, y) CAT (x, y)
+#define FAILNAME(name) CONCAT (call_ ## name ##_on_line_, __LINE__)
+
+#define FAIL(name) do { \
+ extern void FAILNAME (name) (void); \
+ FAILNAME (name)(); \
+ } while (0)
+
+/* Macro to emit a call to function named
+ call_in_true_branch_not_eliminated_on_line_NNN()
+ for each call that's expected to be eliminated. The dg-final
+ scan-tree-dump-time directive at the bottom of the test verifies
+ that no such call appears in output. */
+#define ASSERT_ELIM(expr) \
+ if (!!(expr)) FAIL (in_true_branch_not_eliminated); else (void)0
+
+char a[32];
+
+void lower_bound_assign_1 (void)
+{
+ a[0] = '1';
+ ASSERT_ELIM (strlen (a) < 1);
+}
+
+void lower_bound_assign_2 (void)
+{
+ a[0] = '1';
+ a[1] = '2';
+ ASSERT_ELIM (strlen (a) < 2);
+}
+
+void lower_bound_assign_3 (void)
+{
+ a[0] = '1';
+ a[1] = '2';
+ a[2] = '3';
+ ASSERT_ELIM (strlen (a) < 3);
+}
+
+void lower_bound_memcpy (void)
+{
+ memcpy (a, "123", 3);
+ ASSERT_ELIM (strlen (a) < 3);
+}
+
+void lower_bound_memcpy_memcpy_2 (void)
+{
+ memcpy (a, "123", 3);
+ memcpy (a + 2, "345", 3);
+ ASSERT_ELIM (strlen (a) < 5);
+}
+
+void lower_bound_memcpy_memcpy_3 (void)
+{
+ memcpy (a, "123", 3);
+ memcpy (a + 3, "456", 3);
+ ASSERT_ELIM (strlen (a) < 6);
+}
+
+/* FIXME: Not optimized yet.
+void lower_bound_stpcpy_stpcpy_assign (void)
+{
+ *stpcpy (strcpy (a, "123"), "4567") = '8';
+ ASSERT_ELIM (strlen (a) < 8);
+}
+*/
+
+void lower_bound_strcpy_strcat_assign (void)
+{
+ strcpy (a, "123");
+ strcat (a, "45");
+ a[5] = '6';
+ ASSERT_ELIM (strlen (a) < 6);
+}
+
+/* { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated_" 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/strlenopt-8.c b/gcc/testsuite/gcc.dg/strlenopt-8.c
index 85c6d38..f43b809 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-8.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-8.c
@@ -43,13 +43,7 @@ main ()
return 0;
}
-/* On non-strict-align targets we inline the memcpy that strcat is turned
- into and end up with a short typed load / store which strlenopt is not
- able to analyze. */
-
-/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" { xfail non_strict_align } } } */
-/* { dg-final { scan-tree-dump-times "memcpy \\(" 2 "strlen" { target { non_strict_align } } } } */
-/* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen" { target { ! non_strict_align } } } } */
+/* { dg-final { scan-tree-dump-times "strlen \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
diff --git a/gcc/testsuite/gcc.dg/struct-ret-1.c b/gcc/testsuite/gcc.dg/struct-ret-1.c
index 23c9e98..330c76a 100644
--- a/gcc/testsuite/gcc.dg/struct-ret-1.c
+++ b/gcc/testsuite/gcc.dg/struct-ret-1.c
@@ -1,5 +1,5 @@
-/* { dg-do run { target hppa*-*-* } } */
-/* { dg-options { -O2 } { target hppa*-*-* } } */
+/* { dg-do run } */
+/* { dg-options { -O2 } } */
extern void abort (void);
extern void exit (int);
typedef struct {
diff --git a/gcc/testsuite/gcc.dg/torture/pr91178-2.c b/gcc/testsuite/gcc.dg/torture/pr91178-2.c
new file mode 100644
index 0000000..0ebb470
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr91178-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+
+int a[100][70304];
+int b[100];
+void c()
+{
+ for (int d = 2; d < 4; d++)
+ for (int e = 2; e <= 50; e++)
+ for (int f = 32; f <= 38; f++)
+ b[d + f] -= a[e][5];
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr91267.c b/gcc/testsuite/gcc.dg/torture/pr91267.c
new file mode 100644
index 0000000..084bd24
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr91267.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+void bar (void);
+void baz (int);
+char *qux (void);
+int a, b;
+
+void
+foo (int f, char *d)
+{
+ char *e;
+ while (d)
+ {
+ if (f)
+ if (e)
+ bar ();
+ baz (e - (d + a));
+ b = e - d;
+ d = qux ();
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr91323.c b/gcc/testsuite/gcc.dg/torture/pr91323.c
new file mode 100644
index 0000000..ce0d7f3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr91323.c
@@ -0,0 +1,51 @@
+/* { dg-do run } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#include <fenv.h>
+
+int
+__attribute__ ((noinline, noclone))
+f1 (float a, float b)
+{
+ return __builtin_isless (a, b) || __builtin_isgreater (a, b);
+}
+
+int
+__attribute__ ((noinline, noclone))
+f2 (float a, float b)
+{
+ return __builtin_islessgreater (a, b);
+}
+
+int
+__attribute__ ((noinline, noclone))
+f3 (float a, float b)
+{
+ return a < b || a > b;
+}
+
+int
+main (void)
+{
+ volatile int r;
+
+ float nanf = __builtin_nanf ("");
+ float argf = 1.0f;
+
+ feclearexcept (FE_INVALID);
+
+ r = f1 (nanf, argf);
+ if (r != 0 || fetestexcept (FE_INVALID))
+ __builtin_abort ();
+
+ r = f2 (nanf, argf);
+ if (r != 0 || fetestexcept (FE_INVALID))
+ __builtin_abort ();
+
+ r = f3 (nanf, argf);
+ if (r != 0 || !fetestexcept (FE_INVALID))
+ __builtin_abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr91445.c b/gcc/testsuite/gcc.dg/torture/pr91445.c
new file mode 100644
index 0000000..1d24d45
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr91445.c
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+
+struct S { _Bool x; };
+
+void
+foo (struct S *s)
+{
+ __builtin_memset (s, 0x11, sizeof (struct S));
+ s->x = 1;
+}
+
+int
+main ()
+{
+ struct S s;
+ foo (&s);
+ char c;
+ __builtin_memcpy (&c, &s.x, 1);
+ if (c != 1)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/ssa-fre-5.c b/gcc/testsuite/gcc.dg/torture/ssa-fre-5.c
index 5ee9d64..180fd72 100644
--- a/gcc/testsuite/gcc.dg/torture/ssa-fre-5.c
+++ b/gcc/testsuite/gcc.dg/torture/ssa-fre-5.c
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-require-effective-target int32 } */
/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
/* { dg-additional-options "-fgimple -fdump-tree-fre1" } */
diff --git a/gcc/testsuite/gcc.dg/torture/ssa-fre-6.c b/gcc/testsuite/gcc.dg/torture/ssa-fre-6.c
index ecdd8f6..2c4235f 100644
--- a/gcc/testsuite/gcc.dg/torture/ssa-fre-6.c
+++ b/gcc/testsuite/gcc.dg/torture/ssa-fre-6.c
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-require-effective-target int32 } */
/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
/* { dg-additional-options "-fgimple -fdump-tree-fre1" } */
diff --git a/gcc/testsuite/gcc.dg/torture/ssa-fre-7.c b/gcc/testsuite/gcc.dg/torture/ssa-fre-7.c
index 07f3c9d..c9259b4 100644
--- a/gcc/testsuite/gcc.dg/torture/ssa-fre-7.c
+++ b/gcc/testsuite/gcc.dg/torture/ssa-fre-7.c
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-require-effective-target int32 } */
/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */
/* { dg-additional-options "-fgimple -fdump-tree-fre1" } */
diff --git a/gcc/testsuite/gcc.dg/tree-prof/ic-misattribution-1.c b/gcc/testsuite/gcc.dg/tree-prof/ic-misattribution-1.c
index 3979b17..0c69045 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/ic-misattribution-1.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/ic-misattribution-1.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -fdump-ipa-profile" } */
+/* { dg-options "-O2 -fdump-ipa-profile-note" } */
/* { dg-additional-sources "ic-misattribution-1a.c" } */
extern void other_caller (void);
diff --git a/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof.c b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof.c
index 53063c3..3ca7893 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile -fdump-ipa-afdo" } */
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized -fdump-ipa-afdo" } */
static int a1 (void)
{
diff --git a/gcc/testsuite/gcc.dg/tree-prof/stringop-1.c b/gcc/testsuite/gcc.dg/tree-prof/stringop-1.c
index d75b254..51e1080 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/stringop-1.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/stringop-1.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile" } */
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized" } */
int a[1000];
int b[1000];
int size=1;
diff --git a/gcc/testsuite/gcc.dg/tree-prof/stringop-2.c b/gcc/testsuite/gcc.dg/tree-prof/stringop-2.c
index c1f7573..0264bb3 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/stringop-2.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/stringop-2.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile" } */
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized" } */
int a[1000];
int b[1000];
int size=1;
diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c
index 492c4c1..8495c4c 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-1.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile" } */
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized" } */
int a[1000];
int b = 256;
int c = 257;
diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c
index b3bbadf..4f758af 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-2.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile" } */
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized" } */
unsigned int a[1000];
unsigned int b = 256;
unsigned int c = 1024;
diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c
index 60953d0..5897d75 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile" } */
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized" } */
unsigned int a[1000];
unsigned int b = 257;
unsigned int c = 1023;
diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c
index 50ae2de..b13601e 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-4.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile" } */
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized" } */
unsigned int a[1000];
unsigned int b = 999;
unsigned int c = 1002;
diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-5.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-5.c
index 80eb320..982bcb1 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-5.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-5.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile" } */
+/* { dg-options "-O2 -fdump-tree-optimized -fdump-ipa-profile-optimized" } */
int a[1000];
int b=997;
int
diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-7.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-7.c
index 18b2b25..5ddb1a8 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-7.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-7.c
@@ -1,4 +1,4 @@
-/* { dg-options "-O2 -fdump-ipa-profile -mtune=core2" } */
+/* { dg-options "-O2 -fdump-ipa-profile-optimized -mtune=core2" } */
/* { dg-skip-if "" { ! { i?86-*-* x86_64-*-* } } } */
char *buffer1;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-31.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-31.c
index e146ade..edf8026 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-31.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-31.c
@@ -9,7 +9,6 @@ int foo (int x)
return w - z; /* becomes 0 */
}
-/* The original y = 0 stmt is also retained. */
-/* { dg-final { scan-tree-dump-times "= 0;" 2 "forwprop1" } } */
-/* { dg-final { scan-tree-dump-times "-" 0 "forwprop1" } } */
-/* { dg-final { scan-tree-dump-times "\\+" 1 "forwprop1" } } */
+/* Only z = x + 1 is retained. */
+/* { dg-final { scan-tree-dump-times " = " 1 "forwprop1" } } */
+/* { dg-final { scan-tree-dump "return 0;" "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr86061.c b/gcc/testsuite/gcc.dg/tree-ssa/pr86061.c
new file mode 100644
index 0000000..f2b0792
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr86061.c
@@ -0,0 +1,20 @@
+/* { dg-options "-O2 -fdump-tree-dse-details -fno-tree-fre" } */
+
+
+struct S { int i; char n[128]; int j; };
+
+void f (char*);
+
+void g (struct S *p)
+{
+ char a[sizeof p->n + 1];
+
+ __builtin_memset (a, 0, sizeof a); // dead store, can be eliminated
+
+ __builtin_strncpy (a, p->n, sizeof a - 1);
+ a[sizeof a - 1] = '\0';
+
+ f (a);
+}
+
+/* { dg-final { scan-tree-dump-times "Deleted dead call" 1 "dse1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr91091-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr91091-2.c
index b578de7..ecc50d3 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr91091-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr91091-2.c
@@ -11,5 +11,5 @@ void swap(struct s* p, struct t* q)
}
/* The second statement is redundant. */
-/* { dg-final { scan-tree-dump-times "x = " 1 "fre1" } } */
-/* { dg-final { scan-tree-dump-times " = \[^;\]*x;" 1 "fre1" } } */
+/* { dg-final { scan-tree-dump-times "x = " 1 "fre1" { xfail { ! natural_alignment_32 } } } } */
+/* { dg-final { scan-tree-dump-times " = \[^;\]*x;" 1 "fre1" { xfail { ! natural_alignment_32 } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c
index a4d9a71..3a0e94d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-61.c
@@ -1,4 +1,4 @@
-/* { dg-do link } */
+/* { dg-do link { target natural_alignment_32 } } */
/* { dg-options "-O -fdump-tree-fre1-details" } */
void link_error (void);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-77.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-77.c
index 115f277..c2d9239 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-77.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-77.c
@@ -10,4 +10,4 @@ int foo (int *p, int *q)
return *p;
}
-/* { dg-final { scan-tree-dump "return 1;" "fre1" } } */
+/* { dg-final { scan-tree-dump "return 1;" "fre1" { xfail { ! natural_alignment_32 } } } } */
diff --git a/gcc/testsuite/gcc.dg/type-convert-var.c b/gcc/testsuite/gcc.dg/type-convert-var.c
new file mode 100644
index 0000000..f7b191c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/type-convert-var.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fexcess-precision=fast -O1 -fdump-tree-optimized" } */
+void foo (float a, float b, float *c)
+{
+ double e = (double)a * (double)b;
+ *c = (float)e;
+}
+
+/* { dg-final { scan-tree-dump-not {double} "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/uninit-pr50476.c b/gcc/testsuite/gcc.dg/uninit-pr50476.c
new file mode 100644
index 0000000..db4146d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/uninit-pr50476.c
@@ -0,0 +1,18 @@
+/* PR middle-end/50476 - Warn of pointer set to object whose lifetime is limited
+ { dg-do compile }
+ { dg-options "-O1 -Wall" } */
+
+int *x = 0;
+
+void f (void)
+{
+ int y = 1;
+ x = &y;
+}
+
+int g (void)
+{
+ f ();
+
+ return *x; // { dg-warning "\\\[-Wuninitialized" }
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr91293-1.c b/gcc/testsuite/gcc.dg/vect/pr91293-1.c
new file mode 100644
index 0000000..dc321f5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr91293-1.c
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-additional-options "-msse4.1" { target { sse4_runtime } } } */
+
+long long a;
+unsigned b, c;
+int d = 62;
+void e(long long *f, int p2) { *f = p2; }
+int main()
+{
+ for (int g = 2; g <= d; g++)
+ {
+ b += g + 4;
+ c += 5 - g;
+ }
+ e(&a, b);
+ if (a != 2196)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr91293-2.c b/gcc/testsuite/gcc.dg/vect/pr91293-2.c
new file mode 100644
index 0000000..b9354bb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr91293-2.c
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+/* { dg-additional-options "-msse4.1" { target { sse4_runtime } } } */
+
+long long a;
+unsigned b, c;
+int d = 62;
+void e(long long *f, int p2) { *f = p2; }
+int main()
+{
+ for (int g = 2; g <= d; g++)
+ {
+ c += 5 - g;
+ b += g + 4;
+ }
+ e(&a, b);
+ if (a != 2196)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr91293-3.c b/gcc/testsuite/gcc.dg/vect/pr91293-3.c
new file mode 100644
index 0000000..c35bc34
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr91293-3.c
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-additional-options "-msse4.1" { target { sse4_runtime } } } */
+
+long long a;
+unsigned b, c;
+int d = 62;
+void e(long long *f, int p2) { *f = p2; }
+int xx = 5, yy = 4;
+int main()
+{
+ for (int g = 2; g <= d; g++)
+ {
+ c += xx - g;
+ b += yy + g;
+ }
+ e(&a, b);
+ if (a != 2196)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-arith-7.c b/gcc/testsuite/gcc.dg/vect/vect-cond-arith-7.c
new file mode 100644
index 0000000..739b98f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-cond-arith-7.c
@@ -0,0 +1,60 @@
+/* { dg-require-effective-target scalar_all_fma } */
+/* { dg-additional-options "-fdump-tree-optimized -ffp-contract=fast" } */
+
+#include "tree-vect.h"
+
+#define N (VECTOR_BITS * 11 / 64 + 3)
+
+#define DEF(INV) \
+ void __attribute__ ((noipa)) \
+ f_##INV (double *restrict a, double *restrict b, \
+ double *restrict c, double *restrict d) \
+ { \
+ for (int i = 0; i < N; ++i) \
+ { \
+ double mb = (INV & 1 ? -b[i] : b[i]); \
+ double mc = c[i]; \
+ double md = (INV & 2 ? -d[i] : d[i]); \
+ a[i] = b[i] < 10 ? mb * mc + md : 10.0; \
+ } \
+ }
+
+#define TEST(INV) \
+ { \
+ f_##INV (a, b, c, d); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ double mb = (INV & 1 ? -b[i] : b[i]); \
+ double mc = c[i]; \
+ double md = (INV & 2 ? -d[i] : d[i]); \
+ double fma = __builtin_fma (mb, mc, md); \
+ if (a[i] != (i % 17 < 10 ? fma : 10.0)) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+#define FOR_EACH_INV(T) \
+ T (0) T (1) T (2) T (3)
+
+FOR_EACH_INV (DEF)
+
+int
+main (void)
+{
+ double a[N], b[N], c[N], d[N];
+ for (int i = 0; i < N; ++i)
+ {
+ b[i] = i % 17;
+ c[i] = i % 9 + 11;
+ d[i] = i % 13 + 14;
+ asm volatile ("" ::: "memory");
+ }
+ FOR_EACH_INV (TEST)
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times { = \.COND_FMA } 1 "optimized" { target vect_double_cond_arith } } } */
+/* { dg-final { scan-tree-dump-times { = \.COND_FMS } 1 "optimized" { target vect_double_cond_arith } } } */
+/* { dg-final { scan-tree-dump-times { = \.COND_FNMA } 1 "optimized" { target vect_double_cond_arith } } } */
+/* { dg-final { scan-tree-dump-times { = \.COND_FNMS } 1 "optimized" { target vect_double_cond_arith } } } */
diff --git a/gcc/testsuite/gcc.misc-tests/help.exp b/gcc/testsuite/gcc.misc-tests/help.exp
index 307f1e9..b8a09fc 100644
--- a/gcc/testsuite/gcc.misc-tests/help.exp
+++ b/gcc/testsuite/gcc.misc-tests/help.exp
@@ -91,6 +91,34 @@ maximum number of
-O
} "" ""
+# Verify that a C++/Objective C++ only option is indicated as such
+# by the C compiler.
+check_for_options c "-Q --help=warnings" {
+-Wclass-memaccess[ \t]+\[available in C\+\+, ObjC\+\+\]
+} "" ""
+
+# Do the same for a C/Objective C only option and the C++ compiler.
+check_for_options c++ "-Q --help=warnings" {
+-Wabsolute-value[ \t]+\[available in C, ObjC\]
+} "" ""
+
+# Verify that an option that's an alias for another option is shown
+# with the other option as the value.
+check_for_options c "-Q --help=warnings" {
+--all-warnings[ \t]+\-Wall
+-W[ \t]+-Wextra
+-Wmissing-format-attribute[ \t]+-Wsuggest-attribute=format
+-Wno-alloc-size-larger-than[ \t]+-Walloc-size-larger-than=[1-9][0-9]+
+-Wno-vla-larger-than[ \t]+-Wvla-larger-than=[1-9][0-9]+
+} "" ""
+
+# Verify that an option that expects a byte-size argument is shown with
+# a meaningful byte-size argument as the value.
+check_for_options c "-Q --help=warnings" {
+-Walloc-size-larger-than=[ \t]+[1-9][0-9]+ bytes
+-Wlarger-than=[^\n\r]+[1-9][0-9]+ bytes
+} "" ""
+
# Ensure PR 37805 is fixed.
# Specify patterns (arguments 3 and later) that match option names
# at the beginning of the line and not when they are referenced by
diff --git a/gcc/testsuite/gcc.misc-tests/options.exp b/gcc/testsuite/gcc.misc-tests/options.exp
index 7953523..c50784c 100644
--- a/gcc/testsuite/gcc.misc-tests/options.exp
+++ b/gcc/testsuite/gcc.misc-tests/options.exp
@@ -65,7 +65,8 @@ proc check_for_all_options {language gcc_options compiler_pattern as_pattern ld_
fail "$test (assembler options)"
return
}
- if {![regexp -- "/collect2(\\.exe)? .*$ld_pattern" $gcc_output]} {
+ # Match /collect2, /ld, or *-ld.
+ if {![regexp -- "(/collect2|\[-/\]ld)(\\.exe)? .*$ld_pattern" $gcc_output]} {
fail "$test (linker options)"
return
}
diff --git a/gcc/testsuite/gcc.target/aarch64/acle/tme.c b/gcc/testsuite/gcc.target/aarch64/acle/tme.c
new file mode 100644
index 0000000..5df93b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/acle/tme.c
@@ -0,0 +1,34 @@
+/* Test the TME intrinsics. */
+
+/* { dg-do compile } */
+/* { dg-options "-save-temps -O2 -march=armv8-a+tme" } */
+
+#include "arm_acle.h"
+
+#define tcancel_reason 0x234
+
+unsigned
+check_tme (void)
+{
+ unsigned status = __tstart ();
+ if (status == 0)
+ {
+ if (__ttest () == 2)
+ {
+ __tcancel (tcancel_reason & _TMFAILURE_REASON);
+ return tcancel_reason;
+ }
+
+ __tcommit ();
+ return 0;
+ }
+ else if (status & _TMFAILURE_NEST)
+ return _TMFAILURE_NEST;
+ else if (status & _TMFAILURE_TRIVIAL)
+ return _TMFAILURE_TRIVIAL;
+}
+
+/* { dg-final { scan-assembler "tstart\tx..?\n" } } */
+/* { dg-final { scan-assembler "tcancel\t#564\n" } } */
+/* { dg-final { scan-assembler "ttest\tx..?\n" } } */
+/* { dg-final { scan-assembler "tcommit\n" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/asm-x-constraint-1.c b/gcc/testsuite/gcc.target/aarch64/asm-x-constraint-1.c
new file mode 100644
index 0000000..a71043b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/asm-x-constraint-1.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+void
+f (void)
+{
+ register float s0 asm ("s0");
+ register float s7 asm ("s7");
+ register float s8 asm ("s8");
+ register float s15 asm ("s15");
+ register float s16 asm ("s16");
+ register float s31 asm ("s31");
+ asm volatile ("// s0 out: %s0" : "=w" (s0));
+ asm volatile ("// s0 in: %s0" :: "x" (s0));
+ asm volatile ("// s7 out: %s0" : "=w" (s7));
+ asm volatile ("// s7 in: %s0" :: "x" (s7));
+ asm volatile ("// s8 out: %s0" : "=w" (s8));
+ asm volatile ("// s8 in: %s0" :: "x" (s8));
+ asm volatile ("// s15 out: %s0" : "=w" (s15));
+ asm volatile ("// s15 in: %s0" :: "x" (s15));
+ asm volatile ("// s16 out: %s0" : "=w" (s16));
+ asm volatile ("// s16 in: %s0" :: "x" (s16));
+ asm volatile ("// s31 out: %s0" : "=w" (s31));
+ asm volatile ("// s31 in: %s0" :: "x" (s31));
+}
+
+/* { dg-final { scan-assembler {\t// s0 out: s0\n.*[/]/ s0 in: s0\n} } } */
+/* { dg-final { scan-assembler {\t// s7 out: s7\n.*[/]/ s7 in: s7\n} } } */
+/* { dg-final { scan-assembler {\t// s8 out: s8\n.*[/]/ s8 in: s8\n} } } */
+/* { dg-final { scan-assembler {\t// s15 out: s15\n.*[/]/ s15 in: s15\n} } } */
+/* { dg-final { scan-assembler {\t// s16 out: s16\n.*\tfmov\t(s[0-7]), s16\n.*[/]/ s16 in: \1\n} } } */
+/* { dg-final { scan-assembler {\t// s31 out: s31\n.*\tfmov\t(s[0-7]), s31\n.*[/]/ s31 in: \1\n} } } */
+/* { dg-final { scan-assembler-not {\t// s16 in: s16\n} } } */
+/* { dg-final { scan-assembler-not {\t// s31 in: s31\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/asm-y-constraint-1.c b/gcc/testsuite/gcc.target/aarch64/asm-y-constraint-1.c
new file mode 100644
index 0000000..4a3fcac
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/asm-y-constraint-1.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+void
+f (void)
+{
+ register float s0 asm ("s0");
+ register float s7 asm ("s7");
+ register float s8 asm ("s8");
+ register float s15 asm ("s15");
+ register float s16 asm ("s16");
+ register float s31 asm ("s31");
+ asm volatile ("// s0 out: %s0" : "=w" (s0));
+ asm volatile ("// s0 in: %s0" :: "y" (s0));
+ asm volatile ("// s7 out: %s0" : "=w" (s7));
+ asm volatile ("// s7 in: %s0" :: "y" (s7));
+ asm volatile ("// s8 out: %s0" : "=w" (s8));
+ asm volatile ("// s8 in: %s0" :: "y" (s8));
+ asm volatile ("// s15 out: %s0" : "=w" (s15));
+ asm volatile ("// s15 in: %s0" :: "y" (s15));
+ asm volatile ("// s16 out: %s0" : "=w" (s16));
+ asm volatile ("// s16 in: %s0" :: "y" (s16));
+ asm volatile ("// s31 out: %s0" : "=w" (s31));
+ asm volatile ("// s31 in: %s0" :: "y" (s31));
+}
+
+/* { dg-final { scan-assembler {\t// s0 out: s0\n.*[/]/ s0 in: s0\n} } } */
+/* { dg-final { scan-assembler {\t// s7 out: s7\n.*[/]/ s7 in: s7\n} } } */
+/* { dg-final { scan-assembler {\t// s8 out: s8\n.*\tfmov\t(s[0-7]), s8\n.*[/]/ s8 in: \1\n} } } */
+/* { dg-final { scan-assembler {\t// s15 out: s15\n.*\tfmov\t(s[0-7]), s15\n.*[/]/ s15 in: \1\n} } } */
+/* { dg-final { scan-assembler {\t// s16 out: s16\n.*\tfmov\t(s[0-7]), s16\n.*[/]/ s16 in: \1\n} } } */
+/* { dg-final { scan-assembler {\t// s31 out: s31\n.*\tfmov\t(s[0-7]), s31\n.*[/]/ s31 in: \1\n} } } */
+/* { dg-final { scan-assembler-not {\t// s8 in: s8\n} } } */
+/* { dg-final { scan-assembler-not {\t// s15 in: s15\n} } } */
+/* { dg-final { scan-assembler-not {\t// s16 in: s16\n} } } */
+/* { dg-final { scan-assembler-not {\t// s31 in: s31\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/fmul_scvtf_1.c b/gcc/testsuite/gcc.target/aarch64/fmul_scvtf_1.c
new file mode 100644
index 0000000..8bfe06a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/fmul_scvtf_1.c
@@ -0,0 +1,140 @@
+/* { dg-do run } */
+/* { dg-options "-save-temps -O2 -fno-inline" } */
+
+#define FUNC_DEFS(__a) \
+float \
+fsfoo##__a (int x) \
+{ \
+ return ((float) x)/(1lu << __a); \
+} \
+float \
+fusfoo##__a (unsigned int x) \
+{ \
+ return ((float) x)/(1lu << __a); \
+} \
+float \
+fslfoo##__a (long long x) \
+{ \
+ return ((float) x)/(1lu << __a); \
+} \
+float \
+fulfoo##__a (unsigned long long x) \
+{ \
+ return ((float) x)/(1lu << __a); \
+} \
+
+#define FUNC_DEFD(__a) \
+double \
+dsfoo##__a (int x) \
+{ \
+ return ((double) x)/(1lu << __a); \
+} \
+double \
+dusfoo##__a (unsigned int x) \
+{ \
+ return ((double) x)/(1lu << __a); \
+} \
+double \
+dslfoo##__a (long long x) \
+{ \
+ return ((double) x)/(1lu << __a); \
+} \
+double \
+dulfoo##__a (unsigned long long x) \
+{ \
+ return ((double) x)/(1lu << __a); \
+}
+
+FUNC_DEFS (4)
+ /* { dg-final { scan-assembler-times "scvtf\ts\[0-9\], w\[0-9\]*.*#4" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\ts\[0-9\], w\[0-9\]*.*#4" 1 } } */
+ /* { dg-final { scan-assembler-times "scvtf\ts\[0-9\], x\[0-9\]*.*#4" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\ts\[0-9\], x\[0-9\]*.*#4" 1 } } */
+
+FUNC_DEFD (4)
+ /* { dg-final { scan-assembler-times "scvtf\td\[0-9\], w\[0-9\]*.*#4" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\td\[0-9\], w\[0-9\]*.*#4" 1 } } */
+ /* { dg-final { scan-assembler-times "scvtf\td\[0-9\], x\[0-9\]*.*#4" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\td\[0-9\], x\[0-9\]*.*#4" 1 } } */
+
+FUNC_DEFS (8)
+ /* { dg-final { scan-assembler-times "scvtf\ts\[0-9\], w\[0-9\]*.*#8" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\ts\[0-9\], w\[0-9\]*.*#8" 1 } } */
+ /* { dg-final { scan-assembler-times "scvtf\ts\[0-9\], x\[0-9\]*.*#8" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\ts\[0-9\], x\[0-9\]*.*#8" 1 } } */
+
+FUNC_DEFD (8)
+ /* { dg-final { scan-assembler-times "scvtf\td\[0-9\], w\[0-9\]*.*#8" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\td\[0-9\], w\[0-9\]*.*#8" 1 } } */
+ /* { dg-final { scan-assembler-times "scvtf\td\[0-9\], x\[0-9\]*.*#8" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\td\[0-9\], x\[0-9\]*.*#8" 1 } } */
+
+FUNC_DEFS (16)
+ /* { dg-final { scan-assembler-times "scvtf\ts\[0-9\], w\[0-9\]*.*#16" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\ts\[0-9\], w\[0-9\]*.*#16" 1 } } */
+ /* { dg-final { scan-assembler-times "scvtf\ts\[0-9\], x\[0-9\]*.*#16" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\ts\[0-9\], x\[0-9\]*.*#16" 1 } } */
+
+FUNC_DEFD (16)
+ /* { dg-final { scan-assembler-times "scvtf\td\[0-9\], w\[0-9\]*.*#16" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\td\[0-9\], w\[0-9\]*.*#16" 1 } } */
+ /* { dg-final { scan-assembler-times "scvtf\td\[0-9\], x\[0-9\]*.*#16" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\td\[0-9\], x\[0-9\]*.*#16" 1 } } */
+
+FUNC_DEFS (32)
+ /* { dg-final { scan-assembler-times "scvtf\ts\[0-9\], w\[0-9\]*.*#32" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\ts\[0-9\], w\[0-9\]*.*#32" 1 } } */
+ /* { dg-final { scan-assembler-times "scvtf\ts\[0-9\], x\[0-9\]*.*#32" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\ts\[0-9\], x\[0-9\]*.*#32" 1 } } */
+
+FUNC_DEFD (32)
+ /* { dg-final { scan-assembler-times "scvtf\td\[0-9\], w\[0-9\]*.*#32" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\td\[0-9\], w\[0-9\]*.*#32" 1 } } */
+ /* { dg-final { scan-assembler-times "scvtf\td\[0-9\], x\[0-9\]*.*#32" 1 } } */
+ /* { dg-final { scan-assembler-times "ucvtf\td\[0-9\], x\[0-9\]*.*#32" 1 } } */
+
+#define FUNC_TESTS(__a, __b) \
+do \
+{ \
+ if (fsfoo##__a (__b) != ((int) i) * (1.0f/(1lu << __a)) ) \
+ __builtin_abort (); \
+ if (fusfoo##__a (__b) != ((int) i) * (1.0f/(1lu << __a)) ) \
+ __builtin_abort (); \
+ if (fslfoo##__a (__b) != ((int) i) * (1.0f/(1lu << __a)) ) \
+ __builtin_abort (); \
+ if (fulfoo##__a (__b) != ((int) i) * (1.0f/(1lu << __a)) ) \
+ __builtin_abort (); \
+} while (0)
+
+#define FUNC_TESTD(__a, __b) \
+do \
+{ \
+ if (dsfoo##__a (__b) != ((int) i) * (1.0d/(1lu << __a)) ) \
+ __builtin_abort (); \
+ if (dusfoo##__a (__b) != ((int) i) * (1.0d/(1lu << __a)) ) \
+ __builtin_abort (); \
+ if (dslfoo##__a (__b) != ((int) i) * (1.0d/(1lu << __a)) ) \
+ __builtin_abort (); \
+ if (dulfoo##__a (__b) != ((int) i) * (1.0d/(1lu << __a)) ) \
+ __builtin_abort (); \
+} while (0)
+
+int
+main (void)
+{
+ int i;
+
+ for (i = 0; i < 32; i ++)
+ {
+ FUNC_TESTS (4, i);
+ FUNC_TESTS (8, i);
+ FUNC_TESTS (16, i);
+ FUNC_TESTS (32, i);
+
+ FUNC_TESTD (4, i);
+ FUNC_TESTD (8, i);
+ FUNC_TESTD (16, i);
+ FUNC_TESTD (32, i);
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_3.c b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_3.c
new file mode 100644
index 0000000..ca772cb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target ilp32 } */
+/* { dg-options "-O3 -fno-math-errno -fno-fp-int-builtin-inexact" } */
+
+#define TEST(name, float_type, int_type, fn) void f_##name (float_type x) \
+{ \
+ volatile int_type b = __builtin_##fn (x); \
+}
+
+TEST (dld, double, long, lrint)
+TEST (flf, float , long, lrintf)
+
+TEST (did, double, int, lrint)
+TEST (fif, float , int, lrintf)
+
+/* { dg-final { scan-assembler-times "fcvtzs\tw\[0-9\]+, \[d,s\]\[0-9\]+" 2 } } */
+/* { dg-final { scan-assembler-times "bl\tlrint" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_2.c b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_2.c
new file mode 100644
index 0000000..608b89d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pragma_cpp_predefs_2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+#pragma GCC push_options
+#pragma GCC target ("arch=armv8-a+tme")
+#ifndef __ARM_FEATURE_TME
+#error "__ARM_FEATURE_TME is not defined but should be!"
+#endif
+
+#pragma GCC pop_options
+
+#ifdef __ARM_FEATURE_TME
+#error "__ARM_FEATURE_TME is defined but should not be!"
+#endif
+
+int
+foo (int a)
+{
+ return a;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-2.c b/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-2.c
new file mode 100644
index 0000000..8eec682
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast" } */
+
+__attribute__ ((__simd__ ("notinbranch")))
+__attribute__ ((__nothrow__ , __leaf__ , __const__))
+extern double foo (double x);
+
+void bar(double * f, int n)
+{
+ int i;
+ for (i = 0; i < n; i++)
+ f[i] = foo(f[i]);
+}
+
+/* { dg-final { scan-assembler-not {\.variant_pcs\tfoo} } } */
+/* { dg-final { scan-assembler-times {\.variant_pcs\t_ZGVnN2v_foo} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-3.c b/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-3.c
new file mode 100644
index 0000000..95f6a68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute-3.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast" } */
+
+__attribute__ ((__simd__))
+__attribute__ ((__nothrow__ , __leaf__ , __const__))
+double foo (double x);
+
+void bar(double *f, int n)
+{
+ int i;
+ for (i = 0; i < n; i++)
+ f[i] = foo(f[i]);
+}
+
+double foo(double x)
+{
+ return x * x / 3.0;
+}
+
+/* { dg-final { scan-assembler-not {\.variant_pcs\tfoo} } } */
+/* { dg-final { scan-assembler-times {\.variant_pcs\t_ZGVnM1v_foo} 1 } } */
+/* { dg-final { scan-assembler-times {\.variant_pcs\t_ZGVnM2v_foo} 1 } } */
+/* { dg-final { scan-assembler-times {\.variant_pcs\t_ZGVnN1v_foo} 1 } } */
+/* { dg-final { scan-assembler-times {\.variant_pcs\t_ZGVnN2v_foo} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute.c b/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute.c
new file mode 100644
index 0000000..eddcef3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/simd_pcs_attribute.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast" } */
+
+__attribute__ ((__simd__ ("notinbranch")))
+__attribute__ ((__nothrow__ , __leaf__ , __const__))
+extern double log (double __x);
+
+void foo(double *f, int n)
+{
+ int i;
+ for (i = 0; i < n; i++)
+ f[i] = log(f[i]);
+}
+
+/* { dg-final { scan-assembler-not {\.variant_pcs\tlog} } } */
+/* { dg-final { scan-assembler-times {\.variant_pcs\t_ZGVnN2v_log} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/adr_1.c b/gcc/testsuite/gcc.target/aarch64/sve/adr_1.c
new file mode 100644
index 0000000..223351c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/adr_1.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#ifndef FACTOR
+#define FACTOR 2
+#endif
+
+#define LOOP(TYPE) \
+ __attribute__ ((noipa)) \
+ void \
+ test_##TYPE (TYPE *restrict dst, TYPE *restrict src, \
+ int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ dst[i] += src[i] * FACTOR; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (int16_t) \
+ T (int32_t) \
+ T (int64_t) \
+ T (uint8_t) \
+ T (uint16_t) \
+ T (uint32_t) \
+ T (uint64_t)
+
+TEST_ALL (LOOP)
+
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]\.b,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]\.b,} 2 } } */
+/* { dg-final { scan-assembler-not {\tadr\tz[0-9]\.b,} } } */
+
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]\.h,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]\.h,} 2 } } */
+/* { dg-final { scan-assembler-not {\tadr\tz[0-9]\.h,} } } */
+
+/* { dg-final { scan-assembler-not {\tadd\tz[0-9]\.s,} } } */
+/* { dg-final { scan-assembler-not {\tlsl\tz[0-9]\.s,} } } */
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]\.s, \[z[0-9]\.s, z[0-9]\.s, lsl 1\]} 2 } } */
+
+/* { dg-final { scan-assembler-not {\tadd\tz[0-9]\.d,} } } */
+/* { dg-final { scan-assembler-not {\tlsl\tz[0-9]\.d,} } } */
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]\.d, \[z[0-9]\.d, z[0-9]\.d, lsl 1\]} 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/adr_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/adr_1_run.c
new file mode 100644
index 0000000..383a90c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/adr_1_run.c
@@ -0,0 +1,31 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "adr_1.c"
+
+#define N 131
+
+#define TEST_LOOP(TYPE) \
+ { \
+ TYPE a[N], b[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (TYPE) i * i + i % 5; \
+ b[i] = (TYPE) i * 3 + i % 7; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE (a, b, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = ((TYPE) (i * i + i % 5) \
+ + ((TYPE) i * 3 + i % 7) * FACTOR); \
+ if (a[i] != expected) \
+ __builtin_abort (); \
+ } \
+ }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/adr_2.c b/gcc/testsuite/gcc.target/aarch64/sve/adr_2.c
new file mode 100644
index 0000000..dc20ddb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/adr_2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#define FACTOR 4
+#include "adr_1.c"
+
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]\.b,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]\.b,} 2 } } */
+/* { dg-final { scan-assembler-not {\tadr\tz[0-9]\.b,} } } */
+
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]\.h,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]\.h,} 2 } } */
+/* { dg-final { scan-assembler-not {\tadr\tz[0-9]\.h,} } } */
+
+/* { dg-final { scan-assembler-not {\tadd\tz[0-9]\.s,} } } */
+/* { dg-final { scan-assembler-not {\tlsl\tz[0-9]\.s,} } } */
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]\.s, \[z[0-9]\.s, z[0-9]\.s, lsl 2\]} 2 } } */
+
+/* { dg-final { scan-assembler-not {\tadd\tz[0-9]\.d,} } } */
+/* { dg-final { scan-assembler-not {\tlsl\tz[0-9]\.d,} } } */
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]\.d, \[z[0-9]\.d, z[0-9]\.d, lsl 2\]} 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/adr_2_run.c b/gcc/testsuite/gcc.target/aarch64/sve/adr_2_run.c
new file mode 100644
index 0000000..e823d3d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/adr_2_run.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#define FACTOR 4
+#include "adr_1_run.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/adr_3.c b/gcc/testsuite/gcc.target/aarch64/sve/adr_3.c
new file mode 100644
index 0000000..b0cb180
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/adr_3.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#define FACTOR 8
+#include "adr_1.c"
+
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]\.b,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]\.b,} 2 } } */
+/* { dg-final { scan-assembler-not {\tadr\tz[0-9]\.b,} } } */
+
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]\.h,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]\.h,} 2 } } */
+/* { dg-final { scan-assembler-not {\tadr\tz[0-9]\.h,} } } */
+
+/* { dg-final { scan-assembler-not {\tadd\tz[0-9]\.s,} } } */
+/* { dg-final { scan-assembler-not {\tlsl\tz[0-9]\.s,} } } */
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]\.s, \[z[0-9]\.s, z[0-9]\.s, lsl 3\]} 2 } } */
+
+/* { dg-final { scan-assembler-not {\tadd\tz[0-9]\.d,} } } */
+/* { dg-final { scan-assembler-not {\tlsl\tz[0-9]\.d,} } } */
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]\.d, \[z[0-9]\.d, z[0-9]\.d, lsl 3\]} 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/adr_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/adr_3_run.c
new file mode 100644
index 0000000..721dd68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/adr_3_run.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#define FACTOR 8
+#include "adr_1_run.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/adr_4.c b/gcc/testsuite/gcc.target/aarch64/sve/adr_4.c
new file mode 100644
index 0000000..7c039ba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/adr_4.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#define FACTOR 16
+#include "adr_1.c"
+
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]\.[bhsd],} 8 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]\.[bhsd],} 8 } } */
+/* { dg-final { scan-assembler-not {\tadr\tz[0-9]\.[bhsd],} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/adr_4_run.c b/gcc/testsuite/gcc.target/aarch64/sve/adr_4_run.c
new file mode 100644
index 0000000..3fb9099
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/adr_4_run.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#define FACTOR 16
+#include "adr_1_run.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/adr_5.c b/gcc/testsuite/gcc.target/aarch64/sve/adr_5.c
new file mode 100644
index 0000000..ce3991c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/adr_5.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define LOOP(FACTOR) \
+ __attribute__ ((noipa)) \
+ void \
+ test_##FACTOR (uint64_t *restrict dst, \
+ uint64_t *restrict src, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ dst[i] += (src[i] & 0xffffffff) * FACTOR; \
+ }
+
+#define TEST_ALL(T) T (1) T (2) T (4) T (8)
+
+TEST_ALL (LOOP)
+
+/* { dg-final { scan-assembler-not {\tadd\tz[0-9]\.d,} } } */
+/* { dg-final { scan-assembler-not {\tlsl\tz[0-9]\.d,} } } */
+/* { dg-final { scan-assembler-not {\tand\tz[0-9]\.d,} } } */
+/* { dg-final { scan-assembler-not {\tuxtw\tz[0-9]\.d,} } } */
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]\.d, \[z[0-9]\.d, z[0-9]\.d, uxtw\]} 1 } } */
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]\.d, \[z[0-9]\.d, z[0-9]\.d, uxtw 1\]} 1 } } */
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]\.d, \[z[0-9]\.d, z[0-9]\.d, uxtw 2\]} 1 } } */
+/* { dg-final { scan-assembler-times {\tadr\tz[0-9]\.d, \[z[0-9]\.d, z[0-9]\.d, uxtw 3\]} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/adr_5_run.c b/gcc/testsuite/gcc.target/aarch64/sve/adr_5_run.c
new file mode 100644
index 0000000..025c38d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/adr_5_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "adr_5.c"
+
+#define N 131
+
+#define TEST_LOOP(FACTOR) \
+ { \
+ uint64_t a[N], b[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (uint64_t) i * i + i % 5; \
+ b[i] = (uint64_t) (i * 3) << ((i & 7) * 8); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##FACTOR (a, b, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ uint64_t expected = ((uint64_t) (i * i + i % 5) \
+ + (((uint64_t) (i * 3) << ((i & 7) * 8)) \
+ & 0xffffffff) * FACTOR); \
+ if (a[i] != expected) \
+ __builtin_abort (); \
+ } \
+ }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/clastb_8.c b/gcc/testsuite/gcc.target/aarch64/sve/clastb_8.c
new file mode 100644
index 0000000..d86a428
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/clastb_8.c
@@ -0,0 +1,25 @@
+/* { dg-do assemble { target aarch64_asm_sve_ok } } */
+/* { dg-options "-O2 -ftree-vectorize -msve-vector-bits=256 --save-temps" } */
+
+#include <stdint.h>
+
+#define TEST_TYPE(TYPE) \
+ void \
+ test_##TYPE (TYPE *ptr, TYPE *a, TYPE *b, TYPE min_v) \
+ { \
+ TYPE last = *ptr; \
+ for (int i = 0; i < 1024; i++) \
+ if (a[i] < min_v) \
+ last = b[i]; \
+ *ptr = last; \
+ }
+
+TEST_TYPE (uint8_t);
+TEST_TYPE (uint16_t);
+TEST_TYPE (uint32_t);
+TEST_TYPE (uint64_t);
+
+/* { dg-final { scan-assembler {\tclastb\t(b[0-9]+), p[0-7], \1, z[0-9]+\.b\n} } } */
+/* { dg-final { scan-assembler {\tclastb\t(h[0-9]+), p[0-7], \1, z[0-9]+\.h\n} } } */
+/* { dg-final { scan-assembler {\tclastb\t(s[0-9]+), p[0-7], \1, z[0-9]+\.s\n} } } */
+/* { dg-final { scan-assembler {\tclastb\t(d[0-9]+), p[0-7], \1, z[0-9]+\.d\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/clrsb_1.c b/gcc/testsuite/gcc.target/aarch64/sve/clrsb_1.c
new file mode 100644
index 0000000..bdc9856
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/clrsb_1.c
@@ -0,0 +1,22 @@
+/* { dg-do assemble { target aarch64_asm_sve_ok } } */
+/* { dg-options "-O2 -ftree-vectorize --save-temps" } */
+
+#include <stdint.h>
+
+void __attribute__ ((noinline, noclone))
+clrsb_32 (unsigned int *restrict dst, uint32_t *restrict src, int size)
+{
+ for (int i = 0; i < size; ++i)
+ dst[i] = __builtin_clrsb (src[i]);
+}
+
+void __attribute__ ((noinline, noclone))
+clrsb_64 (unsigned int *restrict dst, uint64_t *restrict src, int size)
+{
+ for (int i = 0; i < size; ++i)
+ dst[i] = __builtin_clrsbll (src[i]);
+}
+
+/* { dg-final { scan-assembler-times {\tcls\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tcls\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tuzp1\tz[0-9]+\.s, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/clrsb_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/clrsb_1_run.c
new file mode 100644
index 0000000..287630d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/clrsb_1_run.c
@@ -0,0 +1,50 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "clrsb_1.c"
+
+extern void abort (void) __attribute__ ((noreturn));
+
+unsigned int data[] = {
+ 0xffffff80, 24,
+ 0xffffffff, 31,
+ 0x00000000, 31,
+ 0x80000000, 0,
+ 0x7fffffff, 0,
+ 0x000003ff, 21,
+ 0x1fffffff, 2,
+ 0x0000ffff, 15,
+ 0xffff0000, 15
+};
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+ unsigned int count = sizeof (data) / sizeof (data[0]) / 2;
+
+ uint32_t in32[count];
+ unsigned int out32[count];
+ for (unsigned int i = 0; i < count; ++i)
+ {
+ in32[i] = data[i * 2];
+ asm volatile ("" ::: "memory");
+ }
+ clrsb_32 (out32, in32, count);
+ for (unsigned int i = 0; i < count; ++i)
+ if (out32[i] != data[i * 2 + 1])
+ abort ();
+
+ uint64_t in64[count];
+ unsigned int out64[count];
+ for (unsigned int i = 0; i < count; ++i)
+ {
+ in64[i] = (uint64_t) data[i * 2] << 32;
+ asm volatile ("" ::: "memory");
+ }
+ clrsb_64 (out64, in64, count);
+ for (unsigned int i = 0; i < count; ++i)
+ if (out64[i] != (data[i * 2] ? data[i * 2 + 1] : 63))
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/clz_1.c b/gcc/testsuite/gcc.target/aarch64/sve/clz_1.c
new file mode 100644
index 0000000..0c7a4e6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/clz_1.c
@@ -0,0 +1,22 @@
+/* { dg-do assemble { target aarch64_asm_sve_ok } } */
+/* { dg-options "-O2 -ftree-vectorize --save-temps" } */
+
+#include <stdint.h>
+
+void __attribute__ ((noinline, noclone))
+clz_32 (unsigned int *restrict dst, uint32_t *restrict src, int size)
+{
+ for (int i = 0; i < size; ++i)
+ dst[i] = __builtin_clz (src[i]);
+}
+
+void __attribute__ ((noinline, noclone))
+clz_64 (unsigned int *restrict dst, uint64_t *restrict src, int size)
+{
+ for (int i = 0; i < size; ++i)
+ dst[i] = __builtin_clzll (src[i]);
+}
+
+/* { dg-final { scan-assembler-times {\tclz\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tclz\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tuzp1\tz[0-9]+\.s, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/clz_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/clz_1_run.c
new file mode 100644
index 0000000..12d9cf2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/clz_1_run.c
@@ -0,0 +1,50 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "clz_1.c"
+
+extern void abort (void) __attribute__ ((noreturn));
+
+unsigned int data[] = {
+ 0xffffff80, 0,
+ 0xffffffff, 0,
+ 0x00000000, 32,
+ 0x80000000, 0,
+ 0x7fffffff, 1,
+ 0x000003ff, 22,
+ 0x1fffffff, 3,
+ 0x0000ffff, 16,
+ 0xffff0000, 0
+};
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+ unsigned int count = sizeof (data) / sizeof (data[0]) / 2;
+
+ uint32_t in32[count];
+ unsigned int out32[count];
+ for (unsigned int i = 0; i < count; ++i)
+ {
+ in32[i] = data[i * 2];
+ asm volatile ("" ::: "memory");
+ }
+ clz_32 (out32, in32, count);
+ for (unsigned int i = 0; i < count; ++i)
+ if (out32[i] != data[i * 2 + 1])
+ abort ();
+
+ uint64_t in64[count];
+ unsigned int out64[count];
+ for (unsigned int i = 0; i < count; ++i)
+ {
+ in64[i] = (uint64_t) data[i * 2] << 10;
+ asm volatile ("" ::: "memory");
+ }
+ clz_64 (out64, in64, count);
+ for (unsigned int i = 0; i < count; ++i)
+ if (out64[i] != (data[i * 2] ? data[i * 2 + 1] + 22 : 64))
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cnot_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cnot_1.c
new file mode 100644
index 0000000..5fa3346
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cnot_1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *restrict r, TYPE *restrict a, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = !a[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (int16_t) \
+ T (int32_t) \
+ T (int64_t) \
+ T (uint8_t) \
+ T (uint16_t) \
+ T (uint32_t) \
+ T (uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d\n} 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_1.c
new file mode 100644
index 0000000..c02e8ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_1.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define abd(A, B) (((A) < (B) ? (B) : (A)) - ((A) < (B) ? (A) : (B)))
+
+#define DEF_LOOP(TYPE) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict c, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] < 20 ? abd (b[i], c[i]) : b[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (uint8_t) \
+ T (int16_t) \
+ T (uint16_t) \
+ T (int32_t) \
+ T (uint32_t) \
+ T (int64_t) \
+ T (uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_1_run.c
new file mode 100644
index 0000000..a45beef
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_1_run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_abd_1.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ((i + 2) % 3) * (i + 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] < 20 ? abd (b[i], c[i]) : b[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_2.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_2.c
new file mode 100644
index 0000000..97901b6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_2.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define abd(A, B) (((A) < (B) ? (B) : (A)) - ((A) < (B) ? (A) : (B)))
+
+#define DEF_LOOP(TYPE) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict c, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] < 20 ? abd (b[i], c[i]) : c[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (uint8_t) \
+ T (int16_t) \
+ T (uint16_t) \
+ T (int32_t) \
+ T (uint32_t) \
+ T (int64_t) \
+ T (uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_2_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_2_run.c
new file mode 100644
index 0000000..474bc0f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_2_run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_abd_2.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ((i + 2) % 3) * (i + 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] < 20 ? abd (b[i], c[i]) : c[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_3.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_3.c
new file mode 100644
index 0000000..dc8bc3c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_3.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define abd(A, B) (((A) < (B) ? (B) : (A)) - ((A) < (B) ? (A) : (B)))
+
+#define DEF_LOOP(TYPE) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict c, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] < 20 ? abd (b[i], c[i]) : a[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (uint8_t) \
+ T (int16_t) \
+ T (uint16_t) \
+ T (int32_t) \
+ T (uint32_t) \
+ T (int64_t) \
+ T (uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d\n} 2 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_3_run.c
new file mode 100644
index 0000000..9f1ac2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_3_run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_abd_3.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ((i + 2) % 3) * (i + 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] < 20 ? abd (b[i], c[i]) : a[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_4.c
new file mode 100644
index 0000000..5c65e59
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_4.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define abd(A, B) (((A) < (B) ? (B) : (A)) - ((A) < (B) ? (A) : (B)))
+
+#define DEF_LOOP(TYPE) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict c, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] < 20 ? abd (b[i], c[i]) : 79; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (uint8_t) \
+ T (int16_t) \
+ T (uint16_t) \
+ T (int32_t) \
+ T (uint32_t) \
+ T (int64_t) \
+ T (uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-times {\tsel\t} 8 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_4_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_4_run.c
new file mode 100644
index 0000000..47fd9e0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_4_run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_abd_4.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ((i + 2) % 3) * (i + 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] < 20 ? abd (b[i], c[i]) : 79; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_5.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_5.c
new file mode 100644
index 0000000..f2c0131
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_5.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define abd(A, B) (((A) < (B) ? (B) : (A)) - ((A) < (B) ? (A) : (B)))
+
+#define DEF_LOOP(TYPE) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict c, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] < 20 ? abd (b[i], c[i]) : 0; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (uint8_t) \
+ T (int16_t) \
+ T (uint16_t) \
+ T (int32_t) \
+ T (uint32_t) \
+ T (int64_t) \
+ T (uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tsabd\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tuabd\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.b, p[0-7]/z, z[0-9]+\.b\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.h, p[0-7]/z, z[0-9]+\.h\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/z, z[0-9]+\.s\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/z, z[0-9]+\.d\n} 2 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_5_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_5_run.c
new file mode 100644
index 0000000..7cd44be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_abd_5_run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_abd_5.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ((i + 2) % 3) * (i + 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] < 20 ? abd (b[i], c[i]) : 0; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_1.c
new file mode 100644
index 0000000..bd87766
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_1.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] == 0 ? !b[i] : b[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (uint8_t) \
+ T (int16_t) \
+ T (uint16_t) \
+ T (int32_t) \
+ T (uint32_t) \
+ T (int64_t) \
+ T (uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* Currently we canonicalize the ?: so that !b[i] is the "false" value. */
+/* { dg-final { scan-assembler-not {\tsel\t} { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_1_run.c
new file mode 100644
index 0000000..802bcbb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_1_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_cnot_1.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE) \
+ { \
+ TYPE r[N], a[N], b[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i % 3) < (i % 5); \
+ b[i] = i % 7 < 3; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE (r, a, b, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] == 0 ? !b[i] : b[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_2.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_2.c
new file mode 100644
index 0000000..d689e21
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_2.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] == 0 ? !b[i] : a[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (uint8_t) \
+ T (int16_t) \
+ T (uint16_t) \
+ T (int32_t) \
+ T (uint32_t) \
+ T (int64_t) \
+ T (uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* Currently we canonicalize the ?: so that !b[i] is the "false" value. */
+/* { dg-final { scan-assembler-not {\tsel\t} { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_2_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_2_run.c
new file mode 100644
index 0000000..6db8bf1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_2_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_cnot_2.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE) \
+ { \
+ TYPE r[N], a[N], b[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i % 3) < (i % 5); \
+ b[i] = i % 7 < 3; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE (r, a, b, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] == 0 ? !b[i] : a[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_3.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_3.c
new file mode 100644
index 0000000..806e517
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_3.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] == 0 ? !b[i] : 127; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (uint8_t) \
+ T (int16_t) \
+ T (uint16_t) \
+ T (int32_t) \
+ T (uint32_t) \
+ T (int64_t) \
+ T (uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tcnot\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+, z[0-9]+\n} 8 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^\n]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_3_run.c
new file mode 100644
index 0000000..6e025e4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_cnot_3_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_cnot_3.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE) \
+ { \
+ TYPE r[N], a[N], b[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i % 3) < (i % 5); \
+ b[i] = i % 7 < 3; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE (r, a, b, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] == 0 ? !b[i] : 127; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_1.c
new file mode 100644
index 0000000..69468eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_1.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(FLOAT_TYPE, INT_TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##INT_TYPE (FLOAT_TYPE *__restrict r, \
+ INT_TYPE *__restrict a, \
+ FLOAT_TYPE *__restrict b, \
+ INT_TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] ? (FLOAT_TYPE) a[i] : b[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (_Float16, int16_t) \
+ T (_Float16, uint16_t) \
+ T (float, int32_t) \
+ T (float, uint32_t) \
+ T (double, int64_t) \
+ T (double, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tscvtf\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tucvtf\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tscvtf\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tucvtf\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tscvtf\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tucvtf\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* At the moment we don't manage to avoid using MOVPRFX. */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_1_run.c
new file mode 100644
index 0000000..1f712b4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_1_run.c
@@ -0,0 +1,29 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize -ftrapping-math" } */
+
+#include "cond_convert_1.c"
+
+#define N 99
+
+#define TEST_LOOP(FLOAT_TYPE, INT_TYPE) \
+ { \
+ FLOAT_TYPE r[N], b[N]; \
+ INT_TYPE a[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i) * (i % 3 == 0 ? 1 : -1); \
+ b[i] = (i % 9) * (i % 7 + 1); \
+ pred[i] = (i % 7 < 4); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##INT_TYPE (r, a, b, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (pred[i] ? (FLOAT_TYPE) a[i] : b[i])) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_2.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_2.c
new file mode 100644
index 0000000..0e60b43
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_2.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(FLOAT_TYPE, INT_TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##INT_TYPE (FLOAT_TYPE *__restrict r, \
+ INT_TYPE *__restrict a, \
+ INT_TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] ? (FLOAT_TYPE) a[i] : 1.0; \
+ }
+
+#define TEST_ALL(T) \
+ T (_Float16, int16_t) \
+ T (_Float16, uint16_t) \
+ T (float, int32_t) \
+ T (float, uint32_t) \
+ T (double, int64_t) \
+ T (double, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tscvtf\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tucvtf\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tscvtf\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tucvtf\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tscvtf\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tucvtf\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+, z[0-9]+\n} 6 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^\n]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_2_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_2_run.c
new file mode 100644
index 0000000..9a48349
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_2_run.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize -ftrapping-math" } */
+
+#include "cond_convert_2.c"
+
+#define N 99
+
+#define TEST_LOOP(FLOAT_TYPE, INT_TYPE) \
+ { \
+ FLOAT_TYPE r[N]; \
+ INT_TYPE a[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i) * (i % 3 == 0 ? 1 : -1); \
+ pred[i] = (i % 7 < 4); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##INT_TYPE (r, a, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (pred[i] ? (FLOAT_TYPE) a[i] : 1.0)) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_3.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_3.c
new file mode 100644
index 0000000..a294eff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_3.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(FLOAT_TYPE, INT_TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##INT_TYPE (FLOAT_TYPE *__restrict r, \
+ INT_TYPE *__restrict a, \
+ INT_TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] ? (FLOAT_TYPE) a[i] : 0.0; \
+ }
+
+#define TEST_ALL(T) \
+ T (_Float16, int16_t) \
+ T (_Float16, uint16_t) \
+ T (float, int32_t) \
+ T (float, uint32_t) \
+ T (double, int64_t) \
+ T (double, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tscvtf\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tucvtf\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tscvtf\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tucvtf\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tscvtf\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tucvtf\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* Really we should be able to use MOVPRFX /z here, but at the moment
+ we're relying on combine to merge a SEL and an arithmetic operation,
+ and the SEL doesn't allow the "false" value to be zero when the "true"
+ value is a register. */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+, z[0-9]+\n} 6 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^\n]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_3_run.c
new file mode 100644
index 0000000..9002109
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_3_run.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize -ftrapping-math" } */
+
+#include "cond_convert_3.c"
+
+#define N 99
+
+#define TEST_LOOP(FLOAT_TYPE, INT_TYPE) \
+ { \
+ FLOAT_TYPE r[N]; \
+ INT_TYPE a[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i) * (i % 3 == 0 ? 1 : -1); \
+ pred[i] = (i % 7 < 4); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##INT_TYPE (r, a, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (pred[i] ? (FLOAT_TYPE) a[i] : 0.0)) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_4.c
new file mode 100644
index 0000000..55b535f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_4.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(FLOAT_TYPE, INT_TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##INT_TYPE (INT_TYPE *__restrict r, \
+ FLOAT_TYPE *__restrict a, \
+ INT_TYPE *__restrict b, \
+ INT_TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] ? (INT_TYPE) a[i] : b[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (_Float16, int16_t) \
+ T (_Float16, uint16_t) \
+ T (float, int32_t) \
+ T (float, uint32_t) \
+ T (double, int64_t) \
+ T (double, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfcvtzs\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfcvtzu\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfcvtzs\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfcvtzu\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfcvtzs\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfcvtzu\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* At the moment we don't manage to avoid using MOVPRFX. */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_4_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_4_run.c
new file mode 100644
index 0000000..eaadcb7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_4_run.c
@@ -0,0 +1,29 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize -ftrapping-math" } */
+
+#include "cond_convert_4.c"
+
+#define N 99
+
+#define TEST_LOOP(FLOAT_TYPE, INT_TYPE) \
+ { \
+ INT_TYPE r[N], b[N], pred[N]; \
+ FLOAT_TYPE a[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i) * (i % 3 == 0 ? 1 : -1); \
+ b[i] = (i % 9) * (i % 7 + 1); \
+ pred[i] = (i % 7 < 4); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##INT_TYPE (r, a, b, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (pred[i] ? (INT_TYPE) a[i] : b[i])) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_5.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_5.c
new file mode 100644
index 0000000..5f3da83
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_5.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(FLOAT_TYPE, INT_TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##INT_TYPE (INT_TYPE *__restrict r, \
+ FLOAT_TYPE *__restrict a, \
+ INT_TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] ? (INT_TYPE) a[i] : 72; \
+ }
+
+#define TEST_ALL(T) \
+ T (_Float16, int16_t) \
+ T (_Float16, uint16_t) \
+ T (float, int32_t) \
+ T (float, uint32_t) \
+ T (double, int64_t) \
+ T (double, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfcvtzs\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfcvtzu\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfcvtzs\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfcvtzu\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfcvtzs\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfcvtzu\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+, z[0-9]+\n} 6 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^\n]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_5_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_5_run.c
new file mode 100644
index 0000000..a1f2d49
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_5_run.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize -ftrapping-math" } */
+
+#include "cond_convert_5.c"
+
+#define N 99
+
+#define TEST_LOOP(FLOAT_TYPE, INT_TYPE) \
+ { \
+ INT_TYPE r[N], pred[N]; \
+ FLOAT_TYPE a[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i) * (i % 3 == 0 ? 1 : -1); \
+ pred[i] = (i % 7 < 4); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##INT_TYPE (r, a, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (pred[i] ? (INT_TYPE) a[i] : 72)) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_6.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_6.c
new file mode 100644
index 0000000..6541a2e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_6.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(FLOAT_TYPE, INT_TYPE) \
+ void __attribute__ ((noipa)) \
+ test_##INT_TYPE (INT_TYPE *__restrict r, \
+ FLOAT_TYPE *__restrict a, \
+ INT_TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] ? (INT_TYPE) a[i] : 0; \
+ }
+
+#define TEST_ALL(T) \
+ T (_Float16, int16_t) \
+ T (_Float16, uint16_t) \
+ T (float, int32_t) \
+ T (float, uint32_t) \
+ T (double, int64_t) \
+ T (double, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfcvtzs\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfcvtzu\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfcvtzs\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfcvtzu\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfcvtzs\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfcvtzu\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* Really we should be able to use MOVPRFX /z here, but at the moment
+ we're relying on combine to merge a SEL and an arithmetic operation,
+ and the SEL doesn't allow the "false" value to be zero when the "true"
+ value is a register. */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+, z[0-9]+\n} 6 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^\n]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_6_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_6_run.c
new file mode 100644
index 0000000..49a64b4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_convert_6_run.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize -ftrapping-math" } */
+
+#include "cond_convert_6.c"
+
+#define N 99
+
+#define TEST_LOOP(FLOAT_TYPE, INT_TYPE) \
+ { \
+ INT_TYPE r[N], pred[N]; \
+ FLOAT_TYPE a[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i) * (i % 3 == 0 ? 1 : -1); \
+ pred[i] = (i % 7 < 4); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##INT_TYPE (r, a, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (pred[i] ? (INT_TYPE) a[i] : 0)) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_1.c
new file mode 100644
index 0000000..c1f54e3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_1.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, ABS) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict c, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] < 20 ? ABS (b[i] - c[i]) : b[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (_Float16, __builtin_fabsf16) \
+ T (float, __builtin_fabsf) \
+ T (double, __builtin_fabs)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfabd\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabd\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabd\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_1_run.c
new file mode 100644
index 0000000..a4d6972
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_1_run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include "cond_fabd_1.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, ABS) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ((i + 2) % 3) * (i + 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] < 20 ? ABS (b[i] - c[i]) : b[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_2.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_2.c
new file mode 100644
index 0000000..dd6eecc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_2.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, ABS) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict c, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] < 20 ? ABS (b[i] - c[i]) : c[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (_Float16, __builtin_fabsf16) \
+ T (float, __builtin_fabsf) \
+ T (double, __builtin_fabs)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfabd\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabd\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabd\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_2_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_2_run.c
new file mode 100644
index 0000000..28dc7d0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_2_run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include "cond_fabd_2.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, ABS) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ((i + 2) % 3) * (i + 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] < 20 ? ABS (b[i] - c[i]) : c[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_3.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_3.c
new file mode 100644
index 0000000..26fd7b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_3.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, ABS) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict c, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] < 20 ? ABS (b[i] - c[i]) : a[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (_Float16, __builtin_fabsf16) \
+ T (float, __builtin_fabsf) \
+ T (double, __builtin_fabs)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfabd\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabd\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabd\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_3_run.c
new file mode 100644
index 0000000..be21b7f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_3_run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include "cond_fabd_3.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, ABS) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ((i + 2) % 3) * (i + 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] < 20 ? ABS (b[i] - c[i]) : a[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_4.c
new file mode 100644
index 0000000..78f1fd9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_4.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, ABS) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict c, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] < 20 ? ABS (b[i] - c[i]) : 8.0; \
+ }
+
+#define TEST_ALL(T) \
+ T (_Float16, __builtin_fabsf16) \
+ T (float, __builtin_fabsf) \
+ T (double, __builtin_fabs)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfabd\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabd\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabd\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-times {\tsel\t} 3 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_4_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_4_run.c
new file mode 100644
index 0000000..86bdab4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_4_run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include "cond_fabd_4.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, ABS) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ((i + 2) % 3) * (i + 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] < 20 ? ABS (b[i] - c[i]) : 8; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_5.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_5.c
new file mode 100644
index 0000000..e66477b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_5.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, ABS) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict c, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] < 20 ? ABS (b[i] - c[i]) : 0.0; \
+ }
+
+#define TEST_ALL(T) \
+ T (_Float16, __builtin_fabsf16) \
+ T (float, __builtin_fabsf) \
+ T (double, __builtin_fabs)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfabd\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabd\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabd\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* Really we should be able to use MOVPRFX /Z here, but at the moment
+ we're relying on combine to merge a SEL and an arithmetic operation,
+ and the SEL doesn't allow zero operands. */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.h, p[0-7]/z, z[0-9]+\.h\n} 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/z, z[0-9]+\.s\n} 1 { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/z, z[0-9]+\.d\n} 1 { xfail *-*-* } } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_5_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_5_run.c
new file mode 100644
index 0000000..9fb5fbb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fabd_5_run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize -fno-trapping-math" } */
+
+#include "cond_fabd_5.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, ABS) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ((i + 2) % 3) * (i + 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] < 20 ? ABS (b[i] - c[i]) : 0; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_1.c
new file mode 100644
index 0000000..d103e1f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_1.c
@@ -0,0 +1,62 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? y[i] + (TYPE) CONST : y[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+ T (TYPE, PRED_TYPE, half, 0.5) \
+ T (TYPE, PRED_TYPE, one, 1.0) \
+ T (TYPE, PRED_TYPE, two, 2.0) \
+ T (TYPE, PRED_TYPE, minus_half, -0.5) \
+ T (TYPE, PRED_TYPE, minus_one, -1.0) \
+ T (TYPE, PRED_TYPE, minus_two, -2.0)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, _Float16, int16_t) \
+ TEST_TYPE (T, float, int32_t) \
+ TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #-2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #-2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #-2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_1_run.c
new file mode 100644
index 0000000..956ae14
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_1_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fadd_1.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? y[i] + (TYPE) CONST : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_2.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_2.c
new file mode 100644
index 0000000..b7d02f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_2.c
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ TYPE *__restrict z, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = y[i] < 8 ? z[i] + (TYPE) CONST : y[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, half, 0.5) \
+ T (TYPE, one, 1.0) \
+ T (TYPE, two, 2.0) \
+ T (TYPE, minus_half, -0.5) \
+ T (TYPE, minus_one, -1.0) \
+ T (TYPE, minus_two, -2.0)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, float) \
+ TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #-2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #-2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 6 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d\n} 6 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_2_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_2_run.c
new file mode 100644
index 0000000..debf395
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_2_run.c
@@ -0,0 +1,31 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fadd_2.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N], z[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i % 13; \
+ z[i] = i * i; \
+ } \
+ test_##TYPE##_##NAME (x, y, z, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = y[i] < 8 ? z[i] + (TYPE) CONST : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_3.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_3.c
new file mode 100644
index 0000000..aec0e5a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_3.c
@@ -0,0 +1,65 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? y[i] + (TYPE) CONST : 4; \
+ }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+ T (TYPE, PRED_TYPE, half, 0.5) \
+ T (TYPE, PRED_TYPE, one, 1.0) \
+ T (TYPE, PRED_TYPE, two, 2.0) \
+ T (TYPE, PRED_TYPE, minus_half, -0.5) \
+ T (TYPE, PRED_TYPE, minus_one, -1.0) \
+ T (TYPE, PRED_TYPE, minus_two, -2.0)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, _Float16, int16_t) \
+ TEST_TYPE (T, float, int32_t) \
+ TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #-2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #-2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #-2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 6 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 6 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 6 } } */
+
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_3_run.c
new file mode 100644
index 0000000..d5268c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_3_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fadd_3.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? y[i] + (TYPE) CONST : 4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_4.c
new file mode 100644
index 0000000..bb276c1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_4.c
@@ -0,0 +1,64 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? y[i] + (TYPE) CONST : 0; \
+ }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+ T (TYPE, PRED_TYPE, half, 0.5) \
+ T (TYPE, PRED_TYPE, one, 1.0) \
+ T (TYPE, PRED_TYPE, two, 2.0) \
+ T (TYPE, PRED_TYPE, minus_half, -0.5) \
+ T (TYPE, PRED_TYPE, minus_one, -1.0) \
+ T (TYPE, PRED_TYPE, minus_two, -2.0)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, _Float16, int16_t) \
+ TEST_TYPE (T, float, int32_t) \
+ TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #-2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #-2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #-2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tfadd\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/z, z[0-9]+\.s\n} 6 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/z, z[0-9]+\.d\n} 6 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_4_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_4_run.c
new file mode 100644
index 0000000..4ea8be6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fadd_4_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fadd_4.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? y[i] + (TYPE) CONST : 0; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_1.c
new file mode 100644
index 0000000..d0db090
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_1.c
@@ -0,0 +1,55 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#include <stdint.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : y[i]; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t) \
+ TEST_TYPE (T, FN (f32), float, int32_t) \
+ TEST_TYPE (T, FN (f64), double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_1_run.c
new file mode 100644
index 0000000..00a3c41
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_1_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#include "cond_fmaxnm_1.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_2.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_2.c
new file mode 100644
index 0000000..0b535d1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_2.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#include <stdint.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ TYPE *__restrict z, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = y[i] < 8 ? FN (z[i], CONST) : y[i]; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE) \
+ T (FN, TYPE, zero, 0) \
+ T (FN, TYPE, one, 1) \
+ T (FN, TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f32), float) \
+ TEST_TYPE (T, FN (f64), double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d\n} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_2_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_2_run.c
new file mode 100644
index 0000000..9eb4d80
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_2_run.c
@@ -0,0 +1,31 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#include "cond_fmaxnm_2.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N], z[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i % 13; \
+ z[i] = i * i; \
+ } \
+ test_##TYPE##_##NAME (x, y, z, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = y[i] < 8 ? FN (z[i], CONST) : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_3.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_3.c
new file mode 100644
index 0000000..741f8f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_3.c
@@ -0,0 +1,54 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#include <stdint.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : 4; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t) \
+ TEST_TYPE (T, FN (f32), float, int32_t) \
+ TEST_TYPE (T, FN (f64), double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_3_run.c
new file mode 100644
index 0000000..4aac75f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_3_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#include "cond_fmaxnm_3.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : 4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_4.c
new file mode 100644
index 0000000..83a53c7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_4.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#include <stdint.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? FN (y[i], CONST) : 0; \
+ }
+
+#define TEST_TYPE(T, FN, TYPE, PRED_TYPE) \
+ T (FN, TYPE, PRED_TYPE, zero, 0) \
+ T (FN, TYPE, PRED_TYPE, one, 1) \
+ T (FN, TYPE, PRED_TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16, int16_t) \
+ TEST_TYPE (T, FN (f32), float, int32_t) \
+ TEST_TYPE (T, FN (f64), double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/z, z[0-9]+\.s\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/z, z[0-9]+\.d\n} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_4_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_4_run.c
new file mode 100644
index 0000000..e1d9043
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmaxnm_4_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#include "cond_fmaxnm_4.c"
+
+#define N 99
+
+#define TEST_LOOP(FN, TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? FN (y[i], CONST) : 0; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_1.c
new file mode 100644
index 0000000..d667b20
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_1.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_1.c"
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_1_run.c
new file mode 100644
index 0000000..5df2ff8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_1_run.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_1_run.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_2.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_2.c
new file mode 100644
index 0000000..d66a84b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_2.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_2.c"
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d\n} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_2_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_2_run.c
new file mode 100644
index 0000000..79a98bb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_2_run.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_2_run.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_3.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_3.c
new file mode 100644
index 0000000..d39dd18
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_3.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_3.c"
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_3_run.c
new file mode 100644
index 0000000..ca1a047
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_3_run.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_3_run.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_4.c
new file mode 100644
index 0000000..fff6fdd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_4.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_4.c"
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/z, z[0-9]+\.s\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/z, z[0-9]+\.d\n} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_4_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_4_run.c
new file mode 100644
index 0000000..b945d04
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fminnm_4_run.c
@@ -0,0 +1,5 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize -ffast-math" } */
+
+#define FN(X) __builtin_fmin##X
+#include "cond_fmaxnm_4_run.c"
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_1.c
new file mode 100644
index 0000000..ce417ed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_1.c
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? y[i] * (TYPE) CONST : y[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+ T (TYPE, PRED_TYPE, half, 0.5) \
+ T (TYPE, PRED_TYPE, two, 2.0) \
+ T (TYPE, PRED_TYPE, four, 4.0)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, _Float16, int16_t) \
+ TEST_TYPE (T, float, int32_t) \
+ TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #2\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #2\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #2\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #4\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #4\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #4\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_1_run.c
new file mode 100644
index 0000000..9ca5b50
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_1_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fmul_1.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? y[i] * (TYPE) CONST : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_2.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_2.c
new file mode 100644
index 0000000..cbf9d13
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_2.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ TYPE *__restrict z, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = y[i] < 8 ? z[i] * (TYPE) CONST : y[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, half, 0.5) \
+ T (TYPE, two, 2.0) \
+ T (TYPE, four, 4.0)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, float) \
+ TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #2\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #2\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #4\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #4\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d\n} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_2_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_2_run.c
new file mode 100644
index 0000000..44b283b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_2_run.c
@@ -0,0 +1,31 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fmul_2.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N], z[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i % 13; \
+ z[i] = i * i; \
+ } \
+ test_##TYPE##_##NAME (x, y, z, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = y[i] < 8 ? z[i] * (TYPE) CONST : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_3.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_3.c
new file mode 100644
index 0000000..4da147e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_3.c
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? y[i] * (TYPE) CONST : 8; \
+ }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+ T (TYPE, PRED_TYPE, half, 0.5) \
+ T (TYPE, PRED_TYPE, two, 2.0) \
+ T (TYPE, PRED_TYPE, four, 4.0)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, _Float16, int16_t) \
+ TEST_TYPE (T, float, int32_t) \
+ TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #2\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #2\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #2\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #4\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #4\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #4\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_3_run.c
new file mode 100644
index 0000000..9b81d43
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_3_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fmul_3.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? y[i] * (TYPE) CONST : 8; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_4.c
new file mode 100644
index 0000000..c4fdb2b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_4.c
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? y[i] * (TYPE) CONST : 0; \
+ }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+ T (TYPE, PRED_TYPE, half, 0.5) \
+ T (TYPE, PRED_TYPE, two, 2.0) \
+ T (TYPE, PRED_TYPE, four, 4.0)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, _Float16, int16_t) \
+ TEST_TYPE (T, float, int32_t) \
+ TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #2\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #2\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #2\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #4\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #4\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #4\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmul\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/z, z[0-9]+\.s\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/z, z[0-9]+\.d\n} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_4_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_4_run.c
new file mode 100644
index 0000000..b93e031
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fmul_4_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fmul_4.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? y[i] * (TYPE) CONST : 0; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_1.c
new file mode 100644
index 0000000..8e7172a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_1.c
@@ -0,0 +1,47 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? (TYPE) CONST - y[i] : y[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+ T (TYPE, PRED_TYPE, half, 0.5) \
+ T (TYPE, PRED_TYPE, one, 1.0) \
+ T (TYPE, PRED_TYPE, two, 2.0)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, _Float16, int16_t) \
+ TEST_TYPE (T, float, int32_t) \
+ TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_1_run.c
new file mode 100644
index 0000000..61ffac4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_1_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fsubr_1.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? (TYPE) CONST - y[i] : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_2.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_2.c
new file mode 100644
index 0000000..6d2efde
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_2.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ TYPE *__restrict z, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = y[i] < 8 ? (TYPE) CONST - z[i] : y[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, half, 0.5) \
+ T (TYPE, one, 1.0) \
+ T (TYPE, two, 2.0)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, float) \
+ TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d\n} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_2_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_2_run.c
new file mode 100644
index 0000000..1b25392
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_2_run.c
@@ -0,0 +1,31 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fsubr_2.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N], z[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i % 13; \
+ z[i] = i * i; \
+ } \
+ test_##TYPE##_##NAME (x, y, z, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = y[i] < 8 ? (TYPE) CONST - z[i] : y[i]; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_3.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_3.c
new file mode 100644
index 0000000..328af57
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_3.c
@@ -0,0 +1,50 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? (TYPE) CONST - y[i] : 4; \
+ }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+ T (TYPE, PRED_TYPE, half, 0.5) \
+ T (TYPE, PRED_TYPE, one, 1.0) \
+ T (TYPE, PRED_TYPE, two, 2.0)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, _Float16, int16_t) \
+ TEST_TYPE (T, float, int32_t) \
+ TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsub\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_3_run.c
new file mode 100644
index 0000000..8978287
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_3_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fsubr_3.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? (TYPE) CONST - y[i] : 4; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_4.c
new file mode 100644
index 0000000..1d420b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_4.c
@@ -0,0 +1,49 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, \
+ PRED_TYPE *__restrict pred, \
+ int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] != 1 ? (TYPE) CONST - y[i] : 0; \
+ }
+
+#define TEST_TYPE(T, TYPE, PRED_TYPE) \
+ T (TYPE, PRED_TYPE, half, 0.5) \
+ T (TYPE, PRED_TYPE, one, 1.0) \
+ T (TYPE, PRED_TYPE, two, 2.0)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, _Float16, int16_t) \
+ TEST_TYPE (T, float, int32_t) \
+ TEST_TYPE (T, double, int64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.5\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.5\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfsubr\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/z, z[0-9]+\.s\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/z, z[0-9]+\.d\n} 3 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_4_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_4_run.c
new file mode 100644
index 0000000..2cb3409
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_fsubr_4_run.c
@@ -0,0 +1,32 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_fsubr_4.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, PRED_TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], y[N]; \
+ PRED_TYPE pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ y[i] = i * i; \
+ pred[i] = i % 3; \
+ } \
+ test_##TYPE##_##NAME (x, y, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = i % 3 != 1 ? (TYPE) CONST - y[i] : 0; \
+ if (x[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_1.c
new file mode 100644
index 0000000..a1e80b8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_1.c
@@ -0,0 +1,62 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define bit_and(A, B) ((A) & (B))
+#define bit_or(A, B) ((A) | (B))
+#define bit_xor(A, B) ((A) ^ (B))
+#define bit_bic(A, B) ((A) & ~(B))
+
+#define DEF_LOOP(TYPE, OP) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE##_##OP (TYPE *__restrict r, \
+ TYPE *__restrict a, \
+ TYPE *__restrict b, \
+ TYPE *__restrict c, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] < 20 ? OP (b[i], c[i]) : b[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, bit_and) \
+ T (TYPE, bit_or) \
+ T (TYPE, bit_xor) \
+ T (TYPE, bit_bic)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, int8_t) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, int16_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, int32_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, int64_t) \
+ TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_1_run.c
new file mode 100644
index 0000000..cb12e56
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_1_run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_logical_1.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ((i + 2) % 3) * (i + 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##OP (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] < 20 ? OP (b[i], c[i]) : b[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_2.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_2.c
new file mode 100644
index 0000000..c476fe2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_2.c
@@ -0,0 +1,63 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define bit_and(A, B) ((A) & (B))
+#define bit_or(A, B) ((A) | (B))
+#define bit_xor(A, B) ((A) ^ (B))
+#define bit_bic(A, B) ((A) & ~(B))
+
+#define DEF_LOOP(TYPE, OP) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE##_##OP (TYPE *__restrict r, \
+ TYPE *__restrict a, \
+ TYPE *__restrict b, \
+ TYPE *__restrict c, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] < 20 ? OP (b[i], c[i]) : c[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, bit_and) \
+ T (TYPE, bit_or) \
+ T (TYPE, bit_xor) \
+ T (TYPE, bit_bic)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, int8_t) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, int16_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, int32_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, int64_t) \
+ TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* There's no BICR or equivalent, so the BIC functions need a select. */
+/* { dg-final { scan-assembler-times {\tsel\t} 8 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_2_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_2_run.c
new file mode 100644
index 0000000..9b9918c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_2_run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_logical_2.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ((i + 2) % 3) * (i + 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##OP (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] < 20 ? OP (b[i], c[i]) : c[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_3.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_3.c
new file mode 100644
index 0000000..7ad2c4e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_3.c
@@ -0,0 +1,66 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define bit_and(A, B) ((A) & (B))
+#define bit_or(A, B) ((A) | (B))
+#define bit_xor(A, B) ((A) ^ (B))
+#define bit_bic(A, B) ((A) & ~(B))
+
+#define DEF_LOOP(TYPE, OP) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE##_##OP (TYPE *__restrict r, \
+ TYPE *__restrict a, \
+ TYPE *__restrict b, \
+ TYPE *__restrict c, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] < 20 ? OP (b[i], c[i]) : a[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, bit_and) \
+ T (TYPE, bit_or) \
+ T (TYPE, bit_xor) \
+ T (TYPE, bit_bic)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, int8_t) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, int16_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, int32_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, int64_t) \
+ TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b\n} 8 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h\n} 8 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 8 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d\n} 8 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_3_run.c
new file mode 100644
index 0000000..05dc78a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_3_run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_logical_3.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ((i + 2) % 3) * (i + 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##OP (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] < 20 ? OP (b[i], c[i]) : a[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_4.c
new file mode 100644
index 0000000..00217bf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_4.c
@@ -0,0 +1,62 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define bit_and(A, B) ((A) & (B))
+#define bit_or(A, B) ((A) | (B))
+#define bit_xor(A, B) ((A) ^ (B))
+#define bit_bic(A, B) ((A) & ~(B))
+
+#define DEF_LOOP(TYPE, OP) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE##_##OP (TYPE *__restrict r, \
+ TYPE *__restrict a, \
+ TYPE *__restrict b, \
+ TYPE *__restrict c, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] < 20 ? OP (b[i], c[i]) : 42; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, bit_and) \
+ T (TYPE, bit_or) \
+ T (TYPE, bit_xor) \
+ T (TYPE, bit_bic)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, int8_t) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, int16_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, int32_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, int64_t) \
+ TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-times {\tsel\t} 32 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_4_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_4_run.c
new file mode 100644
index 0000000..46fb115
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_4_run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_logical_4.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ((i + 2) % 3) * (i + 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##OP (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] < 20 ? OP (b[i], c[i]) : 42; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_5.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_5.c
new file mode 100644
index 0000000..36b541f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_5.c
@@ -0,0 +1,66 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define bit_and(A, B) ((A) & (B))
+#define bit_or(A, B) ((A) | (B))
+#define bit_xor(A, B) ((A) ^ (B))
+#define bit_bic(A, B) ((A) & ~(B))
+
+#define DEF_LOOP(TYPE, OP) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##TYPE##_##OP (TYPE *__restrict r, \
+ TYPE *__restrict a, \
+ TYPE *__restrict b, \
+ TYPE *__restrict c, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] < 20 ? OP (b[i], c[i]) : 0; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, bit_and) \
+ T (TYPE, bit_or) \
+ T (TYPE, bit_xor) \
+ T (TYPE, bit_bic)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, int8_t) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, int16_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, int32_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, int64_t) \
+ TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tand\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\torr\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\teor\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tbic\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.b, p[0-7]/z, z[0-9]+\.b\n} 8 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.h, p[0-7]/z, z[0-9]+\.h\n} 8 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/z, z[0-9]+\.s\n} 8 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/z, z[0-9]+\.d\n} 8 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_5_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_5_run.c
new file mode 100644
index 0000000..e0da5fe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_logical_5_run.c
@@ -0,0 +1,33 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_logical_5.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ((i + 2) % 3) * (i + 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##OP (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = a[i] < 20 ? OP (b[i], c[i]) : 0; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_1.c
new file mode 100644
index 0000000..cb01d50
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_1.c
@@ -0,0 +1,52 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, \
+ TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE c, \
+ TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] != 1 ? a[i] OP b[i] * c : b[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, add, +) \
+ T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, uint64_t) \
+ TEST_TYPE (T, _Float16) \
+ TEST_TYPE (T, float) \
+ TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tmad\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmad\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmad\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmad\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmsb\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmsb\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmsb\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmsb\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmad\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmad\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmad\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmsb\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmsb\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmsb\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_1_run.c
new file mode 100644
index 0000000..bcfc622
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_1_run.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_mla_1.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ pred[i] = i % 3 < i % 5; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected \
+ = pred[i] != 1 ? a[i] OP b[i] * (TYPE) FACTOR : b[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_2.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_2.c
new file mode 100644
index 0000000..b6ea1a3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_2.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, \
+ TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE c, \
+ TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] != 1 ? a[i] OP b[i] * c : c; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, add, +) \
+ T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, uint64_t) \
+ TEST_TYPE (T, _Float16) \
+ TEST_TYPE (T, float) \
+ TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tmad\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmad\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmad\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmad\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmsb\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmsb\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmsb\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmsb\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmad\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmad\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmad\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmsb\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmsb\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmsb\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+, z[0-9]+\n} 14 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_2_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_2_run.c
new file mode 100644
index 0000000..79998b8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_2_run.c
@@ -0,0 +1,36 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_mla_2.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ pred[i] = i % 3 < i % 5; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = (pred[i] != 1 \
+ ? a[i] OP b[i] * (TYPE) FACTOR \
+ : (TYPE) FACTOR); \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_3.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_3.c
new file mode 100644
index 0000000..085fccf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_3.c
@@ -0,0 +1,52 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, \
+ TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE c, \
+ TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] != 1 ? a[i] OP b[i] * c : a[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, add, +) \
+ T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, uint64_t) \
+ TEST_TYPE (T, _Float16) \
+ TEST_TYPE (T, float) \
+ TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tmla\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmla\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmla\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmla\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmls\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmls\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmls\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmls\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmla\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmla\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmla\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmls\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmls\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmls\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_3_run.c
new file mode 100644
index 0000000..cbd1185
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_3_run.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_mla_3.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ pred[i] = i % 3 < i % 5; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected \
+ = pred[i] != 1 ? a[i] OP b[i] * (TYPE) FACTOR : a[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_4.c
new file mode 100644
index 0000000..ed9f73e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_4.c
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, \
+ TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE c, \
+ TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] == 1 ? a[i] OP b[i] * c : pred[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, add, +) \
+ T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, uint64_t) \
+ TEST_TYPE (T, _Float16) \
+ TEST_TYPE (T, float) \
+ TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tmla\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmla\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmla\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmla\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmls\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmls\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmls\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmls\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmla\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmla\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmla\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmls\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmls\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmls\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.h, p[0-7]/m,} 4 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/m,} 4 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/m,} 4 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_4_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_4_run.c
new file mode 100644
index 0000000..5e07859
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_4_run.c
@@ -0,0 +1,36 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_mla_4.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ pred[i] = i % 3; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected = (pred[i] == 1 \
+ ? a[i] OP b[i] * (TYPE) FACTOR \
+ : pred[i]); \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_5.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_5.c
new file mode 100644
index 0000000..97e2335
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_5.c
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, \
+ TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE c, \
+ TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] ? a[i] OP b[i] * c : 0; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, add, +) \
+ T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, uint64_t) \
+ TEST_TYPE (T, _Float16) \
+ TEST_TYPE (T, float) \
+ TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\t(?:mla|mad)\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\t(?:mla|mad)\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\t(?:mla|mad)\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\t(?:mla|mad)\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\t(?:mls|msb)\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\t(?:mls|msb)\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\t(?:mls|msb)\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\t(?:mls|msb)\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\t(?:fmla|fmad)\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\t(?:fmla|fmad)\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\t(?:fmla|fmad)\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\t(?:fmls|fmsb)\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\t(?:fmls|fmsb)\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\t(?:fmls|fmsb)\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.b, p[0-7]/z,} 2 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.h, p[0-7]/z,} 4 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/z,} 4 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/z,} 4 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_5_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_5_run.c
new file mode 100644
index 0000000..9de46e30
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_5_run.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_mla_5.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ pred[i] = i % 3 < i % 5; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected \
+ = pred[i] ? a[i] OP b[i] * (TYPE) FACTOR : 0; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_6.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_6.c
new file mode 100644
index 0000000..832bdb3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_6.c
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, \
+ TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE c, \
+ TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] ? a[i] OP b[i] * c : 5; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, add, +) \
+ T (TYPE, sub, -)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, uint64_t) \
+ TEST_TYPE (T, _Float16) \
+ TEST_TYPE (T, float) \
+ TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tmla\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmla\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmla\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmla\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmls\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmls\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmls\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tmls\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmla\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmla\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmla\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmls\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmls\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmls\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tsel\t} 14 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_6_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_6_run.c
new file mode 100644
index 0000000..59f57a2d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_6_run.c
@@ -0,0 +1,35 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_mla_6.c"
+
+#define FACTOR 17
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ pred[i] = i % 3 < i % 5; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, FACTOR, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected \
+ = pred[i] ? a[i] OP b[i] * (TYPE) FACTOR : 5; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_7.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_7.c
new file mode 100644
index 0000000..5561f42
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_7.c
@@ -0,0 +1,62 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME##_##CONST (TYPE *__restrict r, \
+ TYPE *__restrict a, \
+ TYPE *__restrict b, \
+ TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] != 1 ? a[i] OP b[i] * CONST : a[i]; \
+ }
+
+#define TEST_COUNT(T, TYPE, CONST) \
+ T (TYPE, add, +, CONST) \
+ T (TYPE, sub, -, CONST)
+
+#define TEST_TYPE(T, TYPE, CONST) \
+ TEST_COUNT (T, TYPE, 2) \
+ TEST_COUNT (T, TYPE, 4) \
+ TEST_COUNT (T, TYPE, CONST)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, uint8_t, 0x80) \
+ TEST_TYPE (T, uint16_t, 0x8000) \
+ TEST_TYPE (T, uint32_t, 0x80000000) \
+ TEST_TYPE (T, uint64_t, 0x8000000000000000ULL)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.b, z[0-9]+\.b, #1\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.b, z[0-9]+\.b, #2\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.b, z[0-9]+\.b, #7\n} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.h, z[0-9]+\.h, #1\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.h, z[0-9]+\.h, #2\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.h, z[0-9]+\.h, #15\n} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.s, z[0-9]+\.s, #1\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.s, z[0-9]+\.s, #2\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.s, z[0-9]+\.s, #31\n} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.d, z[0-9]+\.d, #1\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.d, z[0-9]+\.d, #2\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.d, z[0-9]+\.d, #63\n} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, z[0-9]+\.b\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 4 } } */
+
+/* { dg-final { scan-assembler-times {\tsub\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, z[0-9]+\.b\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tsub\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tsub\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tsub\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_7_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_7_run.c
new file mode 100644
index 0000000..b094f40
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_7_run.c
@@ -0,0 +1,34 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_mla_7.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP, CONST) \
+ { \
+ TYPE r[N], a[N], b[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ pred[i] = i % 3 < i % 5; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME##_##CONST (r, a, b, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected \
+ = pred[i] != 1 ? a[i] OP b[i] * CONST : a[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_8.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_8.c
new file mode 100644
index 0000000..d554927
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_8.c
@@ -0,0 +1,62 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME##_##CONST (TYPE *__restrict r, \
+ TYPE *__restrict a, \
+ TYPE *__restrict b, \
+ TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] != 1 ? a[i] OP b[i] * -CONST : a[i]; \
+ }
+
+#define TEST_COUNT(T, TYPE, CONST) \
+ T (TYPE, add, +, CONST) \
+ T (TYPE, sub, -, CONST)
+
+#define TEST_TYPE(T, TYPE, CONST) \
+ TEST_COUNT (T, TYPE, 2) \
+ TEST_COUNT (T, TYPE, 4) \
+ TEST_COUNT (T, TYPE, CONST)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, uint8_t, 0x80) \
+ TEST_TYPE (T, uint16_t, 0x8000) \
+ TEST_TYPE (T, uint32_t, 0x80000000) \
+ TEST_TYPE (T, uint64_t, 0x8000000000000000ULL)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.b, z[0-9]+\.b, #1\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.b, z[0-9]+\.b, #2\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.b, z[0-9]+\.b, #7\n} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.h, z[0-9]+\.h, #1\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.h, z[0-9]+\.h, #2\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.h, z[0-9]+\.h, #15\n} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.s, z[0-9]+\.s, #1\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.s, z[0-9]+\.s, #2\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.s, z[0-9]+\.s, #31\n} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.d, z[0-9]+\.d, #1\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.d, z[0-9]+\.d, #2\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.d, z[0-9]+\.d, #63\n} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, z[0-9]+\.b\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tadd\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 4 } } */
+
+/* { dg-final { scan-assembler-times {\tsub\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, z[0-9]+\.b\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tsub\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tsub\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tsub\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_8_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_8_run.c
new file mode 100644
index 0000000..7fb58aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_mla_8_run.c
@@ -0,0 +1,34 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_mla_8.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP, CONST) \
+ { \
+ TYPE r[N], a[N], b[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ pred[i] = i % 3 < i % 5; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME##_##CONST (r, a, b, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ TYPE expected \
+ = pred[i] != 1 ? a[i] OP b[i] * -CONST : a[i]; \
+ if (r[i] != expected) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_1.c
new file mode 100644
index 0000000..f2c51b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_1.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] > 20 ? b[i] OP 3 : b[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, shl, <<) \
+ T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, int8_t) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, int16_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, int32_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, int64_t) \
+ TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_1_run.c
new file mode 100644
index 0000000..acc403e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_1_run.c
@@ -0,0 +1,27 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_shift_1.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP 3 : b[i])) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_2.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_2.c
new file mode 100644
index 0000000..c9082c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_2.c
@@ -0,0 +1,52 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] > 20 ? b[i] OP 3 : a[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, shl, <<) \
+ T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, int8_t) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, int16_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, int32_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, int64_t) \
+ TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d\n} 4 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_2_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_2_run.c
new file mode 100644
index 0000000..4917d3a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_2_run.c
@@ -0,0 +1,27 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_shift_2.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP 3 : a[i])) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_3.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_3.c
new file mode 100644
index 0000000..55e0de8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_3.c
@@ -0,0 +1,48 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] > 20 ? b[i] OP 3 : 72; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, shl, <<) \
+ T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, int8_t) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, int16_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, int32_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, int64_t) \
+ TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-times {\tsel\t} 16 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_3_run.c
new file mode 100644
index 0000000..194c75b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_3_run.c
@@ -0,0 +1,27 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_shift_3.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP 3 : 72)) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_4.c
new file mode 100644
index 0000000..32dd681
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_4.c
@@ -0,0 +1,52 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] > 20 ? b[i] OP 3 : 0; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, shl, <<) \
+ T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, int8_t) \
+ TEST_TYPE (T, uint8_t) \
+ TEST_TYPE (T, int16_t) \
+ TEST_TYPE (T, uint16_t) \
+ TEST_TYPE (T, int32_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, int64_t) \
+ TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.b, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.h, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.b, p[0-7]/z, z[0-9]+\.b\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.h, p[0-7]/z, z[0-9]+\.h\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/z, z[0-9]+\.s\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/z, z[0-9]+\.d\n} 4 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_4_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_4_run.c
new file mode 100644
index 0000000..ee26300
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_4_run.c
@@ -0,0 +1,27 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_shift_4.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP 3 : 0)) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_5.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_5.c
new file mode 100644
index 0000000..1d44915
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_5.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict c, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] > 20 ? b[i] OP c[i] : b[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, shl, <<) \
+ T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, int32_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, int64_t) \
+ TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_5_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_5_run.c
new file mode 100644
index 0000000..35bf1b8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_5_run.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_shift_5.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ~i & 7; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP c[i] : b[i])) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_6.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_6.c
new file mode 100644
index 0000000..35cb676
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_6.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict c, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] > 20 ? b[i] OP c[i] : c[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, shl, <<) \
+ T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, int32_t) \
+ TEST_TYPE (T, uint32_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tlslr\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tasrr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tlsrr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_6_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_6_run.c
new file mode 100644
index 0000000..e601c61
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_6_run.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_shift_6.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ~i & 7; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP c[i] : c[i])) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_7.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_7.c
new file mode 100644
index 0000000..80154b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_7.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict c, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] > 20 ? b[i] OP c[i] : a[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, shl, <<) \
+ T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, int32_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, int64_t) \
+ TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d\n} 4 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_7_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_7_run.c
new file mode 100644
index 0000000..d23b009
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_7_run.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_shift_7.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ~i & 7; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP c[i] : a[i])) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_8.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_8.c
new file mode 100644
index 0000000..b478c0c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_8.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict c, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] > 20 ? b[i] OP c[i] : 91; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, shl, <<) \
+ T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, int32_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, int64_t) \
+ TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-times {\tsel\t} 8 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_8_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_8_run.c
new file mode 100644
index 0000000..72e5a7b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_8_run.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_shift_8.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ~i & 7; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP c[i] : 91)) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_9.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_9.c
new file mode 100644
index 0000000..184e93a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_9.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define DEF_LOOP(TYPE, NAME, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, TYPE *__restrict c, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = a[i] > 20 ? b[i] OP c[i] : 0; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, shl, <<) \
+ T (TYPE, shr, >>)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, int32_t) \
+ TEST_TYPE (T, uint32_t) \
+ TEST_TYPE (T, int64_t) \
+ TEST_TYPE (T, uint64_t)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tlslr?\tz[0-9]+\.s, p[0-7]/m,} 2 } } */
+/* { dg-final { scan-assembler-times {\tlslr?\tz[0-9]+\.d, p[0-7]/m,} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tasrr?\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tasrr?\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tlsrr?\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tlsrr?\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.s, p[0-7]/z, z[0-9]+\.s\n} 4 } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+\.d, p[0-7]/z, z[0-9]+\.d\n} 4 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^,]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_9_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_9_run.c
new file mode 100644
index 0000000..6e41ac4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_shift_9_run.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_shift_9.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N], c[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ c[i] = ~i & 7; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, c, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (TYPE) (a[i] > 20 ? b[i] OP c[i] : 0)) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_1.c
new file mode 100644
index 0000000..2b5f9c3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_1.c
@@ -0,0 +1,59 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define abs(A) ((A) < 0 ? -(A) : (A))
+#define neg(A) (-(A))
+
+#define DEF_LOOP(TYPE, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##OP (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] ? OP (a[i]) : a[i]; \
+ }
+
+#define TEST_INT_TYPE(T, TYPE) \
+ T (TYPE, abs) \
+ T (TYPE, neg)
+
+#define TEST_FLOAT_TYPE(T, TYPE, SUFFIX) \
+ T (TYPE, __builtin_fabs##SUFFIX) \
+ T (TYPE, neg)
+
+#define TEST_ALL(T) \
+ TEST_INT_TYPE (T, int8_t) \
+ TEST_INT_TYPE (T, int16_t) \
+ TEST_INT_TYPE (T, int32_t) \
+ TEST_INT_TYPE (T, int64_t) \
+ TEST_FLOAT_TYPE (T, _Float16, f16) \
+ TEST_FLOAT_TYPE (T, float, f) \
+ TEST_FLOAT_TYPE (T, double, )
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfabs\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabs\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabs\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfneg\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfneg\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfneg\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* XFAILed because the ?: gets canonicalized so that the operation is in
+ the false arm. */
+/* { dg-final { scan-assembler-not {\tsel\t} { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_1_run.c
new file mode 100644
index 0000000..a6c1a49
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_1_run.c
@@ -0,0 +1,27 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_unary_1.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP) \
+ { \
+ TYPE r[N], a[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i) * (i % 3 == 0 ? 1 : -1); \
+ pred[i] = (i % 7 < 4); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##OP (r, a, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (pred[i] ? OP (a[i]) : a[i])) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_2.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_2.c
new file mode 100644
index 0000000..adf8283
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_2.c
@@ -0,0 +1,61 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define abs(A) ((A) < 0 ? -(A) : (A))
+#define neg(A) (-(A))
+
+#define DEF_LOOP(TYPE, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##OP (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict b, \
+ TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] ? OP (a[i]) : b[i]; \
+ }
+
+#define TEST_INT_TYPE(T, TYPE) \
+ T (TYPE, abs) \
+ T (TYPE, neg)
+
+#define TEST_FLOAT_TYPE(T, TYPE, SUFFIX) \
+ T (TYPE, __builtin_fabs##SUFFIX) \
+ T (TYPE, neg)
+
+#define TEST_ALL(T) \
+ TEST_INT_TYPE (T, int8_t) \
+ TEST_INT_TYPE (T, int16_t) \
+ TEST_INT_TYPE (T, int32_t) \
+ TEST_INT_TYPE (T, int64_t) \
+ TEST_FLOAT_TYPE (T, _Float16, f16) \
+ TEST_FLOAT_TYPE (T, float, f) \
+ TEST_FLOAT_TYPE (T, double, )
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfabs\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabs\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabs\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfneg\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfneg\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfneg\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* At the moment we don't manage to avoid using MOVPRFX for the
+ floating-point functions. */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} { xfail *-*-* } } } */
+/* { dg-final { scan-assembler-times {\tmovprfx\t} 6 } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_2_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_2_run.c
new file mode 100644
index 0000000..1a385c3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_2_run.c
@@ -0,0 +1,28 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_unary_2.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP) \
+ { \
+ TYPE r[N], a[N], b[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i) * (i % 3 == 0 ? 1 : -1); \
+ b[i] = (i % 9) * (i % 7 + 1); \
+ pred[i] = (i % 7 < 4); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##OP (r, a, b, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (pred[i] ? OP (a[i]) : b[i])) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_3.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_3.c
new file mode 100644
index 0000000..dde0fdd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_3.c
@@ -0,0 +1,58 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define abs(A) ((A) < 0 ? -(A) : (A))
+#define neg(A) (-(A))
+
+#define DEF_LOOP(TYPE, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##OP (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] ? OP (a[i]) : 5; \
+ }
+
+#define TEST_INT_TYPE(T, TYPE) \
+ T (TYPE, abs) \
+ T (TYPE, neg)
+
+#define TEST_FLOAT_TYPE(T, TYPE, SUFFIX) \
+ T (TYPE, __builtin_fabs##SUFFIX) \
+ T (TYPE, neg)
+
+#define TEST_ALL(T) \
+ TEST_INT_TYPE (T, int8_t) \
+ TEST_INT_TYPE (T, int16_t) \
+ TEST_INT_TYPE (T, int32_t) \
+ TEST_INT_TYPE (T, int64_t) \
+ TEST_FLOAT_TYPE (T, _Float16, f16) \
+ TEST_FLOAT_TYPE (T, float, f) \
+ TEST_FLOAT_TYPE (T, double, )
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfabs\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabs\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabs\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfneg\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfneg\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfneg\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+, z[0-9]+\n} 14 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^\n]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_3_run.c
new file mode 100644
index 0000000..3c72b23
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_3_run.c
@@ -0,0 +1,27 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_unary_3.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP) \
+ { \
+ TYPE r[N], a[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i) * (i % 3 == 0 ? 1 : -1); \
+ pred[i] = (i % 7 < 4); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##OP (r, a, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (pred[i] ? OP (a[i]) : 5)) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_4.c
new file mode 100644
index 0000000..4604365
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_4.c
@@ -0,0 +1,62 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define abs(A) ((A) < 0 ? -(A) : (A))
+#define neg(A) (-(A))
+
+#define DEF_LOOP(TYPE, OP) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##OP (TYPE *__restrict r, TYPE *__restrict a, \
+ TYPE *__restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = pred[i] ? OP (a[i]) : 0; \
+ }
+
+#define TEST_INT_TYPE(T, TYPE) \
+ T (TYPE, abs) \
+ T (TYPE, neg)
+
+#define TEST_FLOAT_TYPE(T, TYPE, SUFFIX) \
+ T (TYPE, __builtin_fabs##SUFFIX) \
+ T (TYPE, neg)
+
+#define TEST_ALL(T) \
+ TEST_INT_TYPE (T, int8_t) \
+ TEST_INT_TYPE (T, int16_t) \
+ TEST_INT_TYPE (T, int32_t) \
+ TEST_INT_TYPE (T, int64_t) \
+ TEST_FLOAT_TYPE (T, _Float16, f16) \
+ TEST_FLOAT_TYPE (T, float, f) \
+ TEST_FLOAT_TYPE (T, double, )
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tabs\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.b, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tneg\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfabs\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabs\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfabs\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfneg\tz[0-9]+\.h, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfneg\tz[0-9]+\.s, p[0-7]/m,} 1 } } */
+/* { dg-final { scan-assembler-times {\tfneg\tz[0-9]+\.d, p[0-7]/m,} 1 } } */
+
+/* Really we should be able to use MOVPRFX /z here, but at the moment
+ we're relying on combine to merge a SEL and an arithmetic operation,
+ and the SEL doesn't allow the "false" value to be zero when the "true"
+ value is a register. */
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+, z[0-9]+\n} 14 } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^\n]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_4_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_4_run.c
new file mode 100644
index 0000000..48d2541
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_unary_4_run.c
@@ -0,0 +1,27 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_unary_4.c"
+
+#define N 99
+
+#define TEST_LOOP(TYPE, OP) \
+ { \
+ TYPE r[N], a[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i) * (i % 3 == 0 ? 1 : -1); \
+ pred[i] = (i % 7 < 4); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##OP (r, a, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ if (r[i] != (pred[i] ? OP (a[i]) : 0)) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_1.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_1.c
new file mode 100644
index 0000000..0564119
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_1.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define NUM_ELEMS(TYPE) (320 / sizeof (TYPE))
+
+#define DEF_LOOP(TYPE, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##CONST##_##TYPE (TYPE *restrict r, TYPE *restrict a, \
+ TYPE *restrict b) \
+ { \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ r[i] = a[i] > 20 ? b[i] & CONST : b[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (uint16_t, 0xff) \
+ \
+ T (uint32_t, 0xff) \
+ T (uint32_t, 0xffff) \
+ \
+ T (uint64_t, 0xff) \
+ T (uint64_t, 0xffff) \
+ T (uint64_t, 0xffffffff)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+\.h), p[0-7]/z, \[x2,[^L]*\tuxtb\t\1, p[0-7]/m, \1\n} } } */
+
+/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+\.s), p[0-7]/z, \[x2,[^L]*\tuxtb\t\1, p[0-7]/m, \1\n} } } */
+/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+\.s), p[0-7]/z, \[x2,[^L]*\tuxth\t\1, p[0-7]/m, \1\n} } } */
+
+/* { dg-final { scan-assembler {\tld1d\t(z[0-9]+\.d), p[0-7]/z, \[x2,[^L]*\tuxtb\t\1, p[0-7]/m, \1\n} } } */
+/* { dg-final { scan-assembler {\tld1d\t(z[0-9]+\.d), p[0-7]/z, \[x2,[^L]*\tuxth\t\1, p[0-7]/m, \1\n} } } */
+/* { dg-final { scan-assembler {\tld1d\t(z[0-9]+\.d), p[0-7]/z, \[x2,[^L]*\tuxtw\t\1, p[0-7]/m, \1\n} } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_1_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_1_run.c
new file mode 100644
index 0000000..685f394
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_1_run.c
@@ -0,0 +1,27 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_uxt_1.c"
+
+#define TEST_LOOP(TYPE, CONST) \
+ { \
+ TYPE r[NUM_ELEMS (TYPE)]; \
+ TYPE a[NUM_ELEMS (TYPE)]; \
+ TYPE b[NUM_ELEMS (TYPE)]; \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##CONST##_##TYPE (r, a, b); \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ if (r[i] != (a[i] > 20 ? b[i] & CONST : b[i])) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_2.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_2.c
new file mode 100644
index 0000000..c900498
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_2.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define NUM_ELEMS(TYPE) (320 / sizeof (TYPE))
+
+#define DEF_LOOP(TYPE, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##CONST##_##TYPE (TYPE *restrict r, TYPE *restrict a, \
+ TYPE *restrict b) \
+ { \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ r[i] = a[i] > 20 ? b[i] & CONST : a[i]; \
+ }
+
+#define TEST_ALL(T) \
+ T (uint16_t, 0xff) \
+ \
+ T (uint32_t, 0xff) \
+ T (uint32_t, 0xffff) \
+ \
+ T (uint64_t, 0xff) \
+ T (uint64_t, 0xffff) \
+ T (uint64_t, 0xffffffff)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler {\tld1h\t(z[0-9]+\.h), p[0-7]/z, \[x1,[^L]*\tld1h\t(z[0-9]+\.h), p[0-7]/z, \[x2,[^L]*\tuxtb\t\1, p[0-7]/m, \2\n} } } */
+
+/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+\.s), p[0-7]/z, \[x1,[^L]*\tld1w\t(z[0-9]+\.s), p[0-7]/z, \[x2,[^L]*\tuxtb\t\1, p[0-7]/m, \2\n} } } */
+/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+\.s), p[0-7]/z, \[x1,[^L]*\tld1w\t(z[0-9]+\.s), p[0-7]/z, \[x2,[^L]*\tuxth\t\1, p[0-7]/m, \2\n} } } */
+
+/* { dg-final { scan-assembler {\tld1d\t(z[0-9]+\.d), p[0-7]/z, \[x1,[^L]*\tld1d\t(z[0-9]+\.d), p[0-7]/z, \[x2,[^L]*\tuxtb\t\1, p[0-7]/m, \2\n} } } */
+/* { dg-final { scan-assembler {\tld1d\t(z[0-9]+\.d), p[0-7]/z, \[x1,[^L]*\tld1d\t(z[0-9]+\.d), p[0-7]/z, \[x2,[^L]*\tuxth\t\1, p[0-7]/m, \2\n} } } */
+/* { dg-final { scan-assembler {\tld1d\t(z[0-9]+\.d), p[0-7]/z, \[x1,[^L]*\tld1d\t(z[0-9]+\.d), p[0-7]/z, \[x2,[^L]*\tuxtw\t\1, p[0-7]/m, \2\n} } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz} } } */
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_2_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_2_run.c
new file mode 100644
index 0000000..75679cd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_2_run.c
@@ -0,0 +1,27 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_uxt_2.c"
+
+#define TEST_LOOP(TYPE, CONST) \
+ { \
+ TYPE r[NUM_ELEMS (TYPE)]; \
+ TYPE a[NUM_ELEMS (TYPE)]; \
+ TYPE b[NUM_ELEMS (TYPE)]; \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##CONST##_##TYPE (r, a, b); \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ if (r[i] != (a[i] > 20 ? b[i] & CONST : a[i])) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_3.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_3.c
new file mode 100644
index 0000000..cf1fd00
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_3.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define NUM_ELEMS(TYPE) (320 / sizeof (TYPE))
+
+#define DEF_LOOP(TYPE, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##CONST##_##TYPE (TYPE *restrict r, TYPE *restrict a, \
+ TYPE *restrict b) \
+ { \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ r[i] = a[i] > 20 ? b[i] & CONST : 127; \
+ }
+
+#define TEST_ALL(T) \
+ T (uint16_t, 0xff) \
+ \
+ T (uint32_t, 0xff) \
+ T (uint32_t, 0xffff) \
+ \
+ T (uint64_t, 0xff) \
+ T (uint64_t, 0xffff) \
+ T (uint64_t, 0xffffffff)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+), z[0-9]+\n\tuxtb\t\1\.h, p[0-7]/m, z[0-9]+\.h\n} } } */
+
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+), z[0-9]+\n\tuxtb\t\1\.s, p[0-7]/m, z[0-9]+\.s\n} } } */
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+), z[0-9]+\n\tuxth\t\1\.s, p[0-7]/m, z[0-9]+\.s\n} } } */
+
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+), z[0-9]+\n\tuxtb\t\1\.d, p[0-7]/m, z[0-9]+\.d\n} } } */
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+), z[0-9]+\n\tuxth\t\1\.d, p[0-7]/m, z[0-9]+\.d\n} } } */
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+), z[0-9]+\n\tuxtw\t\1\.d, p[0-7]/m, z[0-9]+\.d\n} } } */
+
+/* { dg-final { scan-assembler-not {\tmov\tz[^\n]*z} } } */
+/* { dg-final { scan-assembler-not {\tsel\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_3_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_3_run.c
new file mode 100644
index 0000000..3d33d3a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_3_run.c
@@ -0,0 +1,27 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_uxt_3.c"
+
+#define TEST_LOOP(TYPE, CONST) \
+ { \
+ TYPE r[NUM_ELEMS (TYPE)]; \
+ TYPE a[NUM_ELEMS (TYPE)]; \
+ TYPE b[NUM_ELEMS (TYPE)]; \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##CONST##_##TYPE (r, a, b); \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ if (r[i] != (a[i] > 20 ? b[i] & CONST : 127)) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_4.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_4.c
new file mode 100644
index 0000000..25c6647
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_4.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define NUM_ELEMS(TYPE) (320 / sizeof (TYPE))
+
+#define DEF_LOOP(TYPE, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##CONST##_##TYPE (TYPE *restrict r, TYPE *restrict a, \
+ TYPE *restrict b) \
+ { \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ r[i] = a[i] > 20 ? b[i] & CONST : 0; \
+ }
+
+#define TEST_ALL(T) \
+ T (uint16_t, 0xff) \
+ \
+ T (uint32_t, 0xff) \
+ T (uint32_t, 0xffff) \
+ \
+ T (uint64_t, 0xff) \
+ T (uint64_t, 0xffff) \
+ T (uint64_t, 0xffffffff)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+\.h), (p[0-7])/z, z[0-9]+\.h\n\tuxtb\t\1, \2/m, z[0-9]+\.h\n} } } */
+
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+\.s), (p[0-7])/z, z[0-9]+\.s\n\tuxtb\t\1, \2/m, z[0-9]+\.s\n} } } */
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+\.s), (p[0-7])/z, z[0-9]+\.s\n\tuxth\t\1, \2/m, z[0-9]+\.s\n} } } */
+
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+\.d), (p[0-7])/z, z[0-9]+\.d\n\tuxtb\t\1, \2/m, z[0-9]+\.d\n} } } */
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+\.d), (p[0-7])/z, z[0-9]+\.d\n\tuxth\t\1, \2/m, z[0-9]+\.d\n} } } */
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+\.d), (p[0-7])/z, z[0-9]+\.d\n\tuxtw\t\1, \2/m, z[0-9]+\.d\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_4_run.c b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_4_run.c
new file mode 100644
index 0000000..f3c4374
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/cond_uxt_4_run.c
@@ -0,0 +1,27 @@
+/* { dg-do run { target { aarch64_sve_hw } } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "cond_uxt_4.c"
+
+#define TEST_LOOP(TYPE, CONST) \
+ { \
+ TYPE r[NUM_ELEMS (TYPE)]; \
+ TYPE a[NUM_ELEMS (TYPE)]; \
+ TYPE b[NUM_ELEMS (TYPE)]; \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ { \
+ a[i] = (i & 1 ? i : 3 * i); \
+ b[i] = (i >> 4) << (i & 15); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##CONST##_##TYPE (r, a, b); \
+ for (int i = 0; i < NUM_ELEMS (TYPE); ++i) \
+ if (r[i] != (a[i] > 20 ? b[i] & CONST : 0)) \
+ __builtin_abort (); \
+ }
+
+int main ()
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/const_1.c b/gcc/testsuite/gcc.target/aarch64/sve/const_1.c
new file mode 100644
index 0000000..ae25dcb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/const_1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+#include <stdint.h>
+
+void
+set (uint64_t *dst, int count)
+{
+ for (int i = 0; i < count; ++i)
+ dst[i] = 0xffff00ff00ffff00ULL;
+}
+
+/* { dg-final { scan-assembler {\tmovi\tv([0-9]+)\.2d, 0xffff00ff00ffff00\n.*\tdup\tz[0-9]+\.q, z\1\.q\[0\]\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/const_2.c b/gcc/testsuite/gcc.target/aarch64/sve/const_2.c
new file mode 100644
index 0000000..7b2b5c2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/const_2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+#include <stdint.h>
+
+#define TEST(TYPE, CONST) \
+ void \
+ set_##TYPE (TYPE *dst, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ dst[i] = CONST; \
+ }
+
+TEST (uint16_t, 129)
+TEST (uint32_t, 129)
+TEST (uint64_t, 129)
+
+/* { dg-final { scan-assembler {\tmovi\tv([0-9]+)\.8h, 0x81\n[^:]*\tdup\tz[0-9]+\.q, z\1\.q\[0\]\n} } } */
+/* { dg-final { scan-assembler {\tmovi\tv([0-9]+)\.4s, 0x81\n[^:]*\tdup\tz[0-9]+\.q, z\1\.q\[0\]\n} } } */
+/* { dg-final { scan-assembler {\tmov\t(x[0-9]+), 129\n[^:]*\tmov\tz[0-9]+\.d, \1\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/const_3.c b/gcc/testsuite/gcc.target/aarch64/sve/const_3.c
new file mode 100644
index 0000000..c18ceae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/const_3.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+#include <stdint.h>
+
+#define TEST(TYPE, CONST) \
+ void \
+ set_##TYPE (TYPE *dst, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ dst[i] = CONST; \
+ }
+
+TEST (uint16_t, 0x1234)
+TEST (uint32_t, 0x1234)
+TEST (uint64_t, 0x1234)
+
+/* { dg-final { scan-assembler {\tmov\t(w[0-9]+), 4660\n[^:]*\tmov\tz[0-9]+\.h, \1\n} } } */
+/* { dg-final { scan-assembler {\tmov\t(w[0-9]+), 4660\n[^:]*\tmov\tz[0-9]+\.s, \1\n} } } */
+/* { dg-final { scan-assembler {\tmov\t(x[0-9]+), 4660\n[^:]*\tmov\tz[0-9]+\.d, \1\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/ext_2.c b/gcc/testsuite/gcc.target/aarch64/sve/ext_2.c
index 0fe7e4c..5593b07 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/ext_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/ext_2.c
@@ -14,5 +14,4 @@ foo (void)
asm volatile ("" :: "w" (x));
}
-/* { dg-final { scan-assembler {\tmov\tz0\.d, z1\.d\n} } } */
-/* { dg-final { scan-assembler {\text\tz0\.b, z0\.b, z[01]\.b, #4\n} } } */
+/* { dg-final { scan-assembler {\tmovprfx\tz0, z1\n\text\tz0\.b, z0\.b, z1\.b, #4\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/ext_3.c b/gcc/testsuite/gcc.target/aarch64/sve/ext_3.c
new file mode 100644
index 0000000..83c04c8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/ext_3.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O -msve-vector-bits=1024" } */
+
+typedef int vnx4si __attribute__((vector_size (128)));
+
+void
+foo (void)
+{
+ register int x asm ("z0");
+ register vnx4si y asm ("z1");
+
+ asm volatile ("" : "=w" (y));
+ x = y[21];
+ asm volatile ("" :: "w" (x));
+}
+
+/* { dg-final { scan-assembler {\tmovprfx\tz0, z1\n\text\tz0\.b, z0\.b, z1\.b, #84\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/fmaxnm_1.c b/gcc/testsuite/gcc.target/aarch64/sve/fmaxnm_1.c
new file mode 100644
index 0000000..2f0d64b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/fmaxnm_1.c
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#ifndef FN
+#define FN(X) __builtin_fmax##X
+#endif
+
+#define DEF_LOOP(FN, TYPE, NAME, CONST) \
+ void __attribute__ ((noipa)) \
+ test_##TYPE##_##NAME (TYPE *__restrict x, \
+ TYPE *__restrict y, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = FN (y[i], CONST); \
+ }
+
+#define TEST_TYPE(T, FN, TYPE) \
+ T (FN, TYPE, zero, 0) \
+ T (FN, TYPE, one, 1) \
+ T (FN, TYPE, two, 2)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, FN (f16), _Float16) \
+ TEST_TYPE (T, FN (f32), float) \
+ TEST_TYPE (T, FN (f64), double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmaxnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/fminnm_1.c b/gcc/testsuite/gcc.target/aarch64/sve/fminnm_1.c
new file mode 100644
index 0000000..547772e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/fminnm_1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#define FN(X) __builtin_fmin##X
+#include "fmaxnm_1.c"
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #0\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #0\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, #1\.0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, #1\.0\n} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.h, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0} 1 } } */
+/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #2\.0} 1 } } */
+
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tfminnm\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/init_1.c b/gcc/testsuite/gcc.target/aarch64/sve/init_1.c
index 14abc22..8e60043 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/init_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/init_1.c
@@ -1,5 +1,6 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
/* Case 1.1: Trailing constants with stepped sequence. */
@@ -7,20 +8,15 @@
typedef int32_t vnx4si __attribute__((vector_size (32)));
+/*
+** foo:
+** index (z[0-9]+\.s), #1, #1
+** insr \1, w1
+** insr \1, w0
+** ...
+*/
__attribute__((noipa))
vnx4si foo(int a, int b)
{
return (vnx4si) { a, b, 1, 2, 3, 4, 5, 6 };
}
-
-/*
-foo:
-.LFB0:
- .cfi_startproc
- index z0.s, #1, #1
- insr z0.s, w1
- insr z0.s, w0
- ret
-*/
-
-/* { dg-final { scan-assembler {\tindex\t(z[0-9]+\.s), #1, #1\n\tinsr\t\1, w1\n\tinsr\t\1, w0} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/init_10.c b/gcc/testsuite/gcc.target/aarch64/sve/init_10.c
index c83debe..bee0394 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/init_10.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/init_10.c
@@ -1,5 +1,6 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
/* Case 5.4: Interleaved repeating elements and non-repeating elements. */
@@ -7,22 +8,17 @@
typedef int32_t vnx4si __attribute__((vector_size (32)));
+/*
+** foo:
+** mov (z[0-9]+\.s), w3
+** mov (z[0-9]+\.s), w2
+** insr \2, w1
+** insr \2, w0
+** zip1 \2, \2, \1
+** ...
+*/
__attribute__((noipa))
vnx4si foo(int a, int b, int c, int f)
{
return (vnx4si) { a, f, b, f, c, f, c, f };
}
-
-/*
-foo:
-.LFB0:
- .cfi_startproc
- mov z1.s, w3
- mov z0.s, w2
- insr z0.s, w1
- insr z0.s, w0
- zip1 z0.s, z0.s, z1.s
- ret
-*/
-
-/* { dg-final { scan-assembler {\tmov\t(z[0-9]+\.s), w3\n\tmov\t(z[0-9]+\.s), w2\n\tinsr\t\2, w1\n\tinsr\t\2, w0\n\tzip1\t\2, \2, \1} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/init_11.c b/gcc/testsuite/gcc.target/aarch64/sve/init_11.c
index 90627b4..8a9496f 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/init_11.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/init_11.c
@@ -1,5 +1,6 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
/* Case 5.5: Interleaved repeating elements and trailing same elements. */
@@ -7,21 +8,16 @@
typedef int32_t vnx4si __attribute__((vector_size (32)));
+/*
+** foo:
+** mov (z[0-9]+\.s), w1
+** insr \1, w0
+** mov (z[0-9]+\.s), w2
+** zip1 \1, \1, \2
+** ...
+*/
__attribute__((noipa))
vnx4si foo(int a, int b, int f)
{
return (vnx4si) { a, f, b, f, b, f, b, f };
}
-
-/*
-foo:
-.LFB0:
- .cfi_startproc
- mov z0.s, w1
- insr z0.s, w0
- mov z1.s, w2
- zip1 z0.s, z0.s, z1.s
- ret
-*/
-
-/* { dg-final { scan-assembler {\tmov\t(z[0-9]+\.s), w1\n\tinsr\t\1, w0\n\tmov\t(z[0-9]+\.s), w2\n\tzip1\t\1, \1, \2} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/init_12.c b/gcc/testsuite/gcc.target/aarch64/sve/init_12.c
index dc20e86..bc698dd 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/init_12.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/init_12.c
@@ -1,5 +1,6 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
/* Case 5.5: Interleaved repeating elements and trailing same elements. */
@@ -7,23 +8,19 @@
typedef int32_t vnx4si __attribute__((vector_size (32)));
+/*
+** foo:
+** fmov (s[0-9]+), w1
+** mov (z[0-9]+\.s), w2
+** mov (z[0-9]+\.s), w0
+** insr \3, \1
+** insr \3, \1
+** insr \3, \1
+** zip1 \3, \3, \2
+** ...
+*/
__attribute__((noipa))
vnx4si foo(int a, int b, int f)
{
return (vnx4si) { b, f, b, f, b, f, a, f };
}
-
-/*
-foo:
-.LFB0:
- .cfi_startproc
- mov z1.s, w2
- mov z0.s, w0
- insr z0.s, w1
- insr z0.s, w1
- insr z0.s, w1
- zip1 z0.s, z0.s, z1.s
- ret
-*/
-
-/* { dg-final { scan-assembler {\tmov\t(z[0-9]+\.s), w2\n\tmov\t(z[0-9]+\.s), w0\n\tinsr\t\2, w1\n\tinsr\t\2, w1\n\tinsr\t\2, w1\n\tzip1\t\2, \2, \1} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/init_13.c b/gcc/testsuite/gcc.target/aarch64/sve/init_13.c
new file mode 100644
index 0000000..eea4170
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/init_13.c
@@ -0,0 +1,17 @@
+/* { dg-do assemble { target aarch64_asm_sve_ok } } */
+/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
+
+typedef float vnx4sf __attribute__((vector_size (32)));
+
+/*
+** foo:
+** mov (z[0-9]+\.s), s0
+** insr \1, wzr
+** ...
+*/
+vnx4sf
+foo (float a)
+{
+ return (vnx4sf) { 0.0f, a, a, a, a, a, a, a };
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/init_2.c b/gcc/testsuite/gcc.target/aarch64/sve/init_2.c
index 5b4ba10..0a8aa8d 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/init_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/init_2.c
@@ -1,5 +1,6 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
/* Case 1.2: Trailing constants with repeating sequence. */
@@ -7,23 +8,16 @@
typedef int32_t vnx4si __attribute__((vector_size (32)));
+/*
+** foo:
+** ...
+** ld1rd (z[0-9]+)\.d, p[0-9]+/z, \[x[0-9]+\]
+** insr \1\.s, w1
+** insr \1\.s, w0
+** ...
+*/
__attribute__((noipa))
vnx4si foo(int a, int b)
{
return (vnx4si) { a, b, 2, 3, 2, 3, 2, 3 };
}
-
-/*
-foo:
-.LFB0:
- .cfi_startproc
- ptrue p0.s, vl8
- adrp x2, .LANCHOR0
- add x2, x2, :lo12:.LANCHOR0
- ld1w z0.s, p0/z, [x2]
- insr z0.s, w1
- insr z0.s, w0
- ret
-*/
-
-/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+\.s), p[0-9]+/z, \[x[0-9]+\]\n\tinsr\t\1, w1\n\tinsr\t\1, w0} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/init_3.c b/gcc/testsuite/gcc.target/aarch64/sve/init_3.c
index 28d218c..4a418b63 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/init_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/init_3.c
@@ -1,5 +1,6 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
/* Case 2.1: Leading constants with stepped sequence. */
@@ -7,21 +8,17 @@
typedef int32_t vnx4si __attribute__((vector_size (32)));
+/*
+** foo:
+** index (z[0-9]+\.s), #6, #-1
+** insr \1, w0
+** insr \1, w1
+** rev \1, \1
+** ...
+*/
__attribute__((noipa))
vnx4si foo(int a, int b)
{
return (vnx4si) { 1, 2, 3, 4, 5, 6, a, b };
}
-/*
-foo:
-.LFB0:
- .cfi_startproc
- index z0.s, #6, #-1
- insr z0.s, w0
- insr z0.s, w1
- rev z0.s, z0.s
- ret
-*/
-
-/* { dg-final { scan-assembler {\tindex\t(z[0-9]+\.s), #6, #-1\n\tinsr\t\1, w0\n\tinsr\t\1, w1\n\trev\t\1, \1} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/init_4.c b/gcc/testsuite/gcc.target/aarch64/sve/init_4.c
index 94484b1..0fa99c1 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/init_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/init_4.c
@@ -1,5 +1,6 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
/* Case 2.2: Leading constants with stepped sequence. */
@@ -7,24 +8,17 @@
typedef int32_t vnx4si __attribute__((vector_size (32)));
+/*
+** foo:
+** ...
+** ld1rd (z[0-9]+)\.d, p[0-9]+/z, \[x[0-9]+\]
+** insr \1\.s, w1
+** insr \1\.s, w0
+** rev \1\.s, \1\.s
+** ...
+*/
__attribute__((noipa))
vnx4si foo(int a, int b)
{
return (vnx4si) { 3, 2, 3, 2, 3, 2, b, a };
}
-
-/*
-foo:
-.LFB0:
- .cfi_startproc
- ptrue p0.s, vl8
- adrp x2, .LANCHOR0
- add x2, x2, :lo12:.LANCHOR0
- ld1w z0.s, p0/z, [x2]
- insr z0.s, w1
- insr z0.s, w0
- rev z0.s, z0.s
- ret
-*/
-
-/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+\.s), p[0-9]+/z, \[x[0-9]+\]\n\tinsr\t\1, w1\n\tinsr\t\1, w0\n\trev\t\1, \1} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/init_5.c b/gcc/testsuite/gcc.target/aarch64/sve/init_5.c
index a43dd7a..794e265 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/init_5.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/init_5.c
@@ -1,5 +1,6 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
/* Case 3: Trailing same element. */
@@ -7,20 +8,15 @@
typedef int32_t vnx4si __attribute__((vector_size (32)));
+/*
+** foo:
+** mov (z[0-9]+\.s), w2
+** insr \1, w1
+** insr \1, w0
+** ...
+*/
__attribute__((noipa))
vnx4si foo(int a, int b, int c)
{
return (vnx4si) { a, b, c, c, c, c, c, c };
}
-
-/*
-foo:
-.LFB0:
- .cfi_startproc
- mov z0.s, w2
- insr z0.s, w1
- insr z0.s, w0
- ret
-*/
-
-/* { dg-final { scan-assembler {\tmov\t(z[0-9]+\.s), w2\n\tinsr\t\1, w1\n\tinsr\t\1, w0} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/init_6.c b/gcc/testsuite/gcc.target/aarch64/sve/init_6.c
index b8e30fb..8443fc0 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/init_6.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/init_6.c
@@ -1,5 +1,6 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
/* Case 3: Trailing same element. */
@@ -7,21 +8,16 @@
typedef int32_t vnx4si __attribute__((vector_size (32)));
+/*
+** foo:
+** mov (z[0-9]+\.s), w2
+** insr \1, w1
+** insr \1, w0
+** rev \1, \1
+** ...
+*/
__attribute__((noipa))
vnx4si foo(int a, int b, int c)
{
return (vnx4si) { c, c, c, c, c, c, b, a };
}
-
-/*
-foo:
-.LFB0:
- .cfi_startproc
- mov z0.s, w2
- insr z0.s, w1
- insr z0.s, w0
- rev z0.s, z0.s
- ret
-*/
-
-/* { dg-final { scan-assembler {\tmov\t(z[0-9]+\.s), w2\n\tinsr\t\1, w1\n\tinsr\t\1, w0\n\trev\t\1, \1} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/init_7.c b/gcc/testsuite/gcc.target/aarch64/sve/init_7.c
index dd27978..63dbbbe 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/init_7.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/init_7.c
@@ -1,5 +1,6 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
/* Case 5.1: All elements. */
@@ -7,25 +8,20 @@
typedef int32_t vnx4si __attribute__((vector_size (32)));
+/*
+** foo:
+** mov (z[0-9]+\.s), w7
+** insr \1, w6
+** insr \1, w5
+** insr \1, w4
+** insr \1, w3
+** insr \1, w2
+** insr \1, w1
+** insr \1, w0
+** ...
+*/
__attribute__((noipa))
vnx4si foo(int a, int b, int c, int d, int e, int f, int g, int h)
{
return (vnx4si) { a, b, c, d, e, f, g, h };
}
-
-/*
-foo:
-.LFB0:
- .cfi_startproc
- mov z0.s, w7
- insr z0.s, w6
- insr z0.s, w5
- insr z0.s, w4
- insr z0.s, w3
- insr z0.s, w2
- insr z0.s, w1
- insr z0.s, w0
- ret
-*/
-
-/* { dg-final { scan-assembler {\tmov\t(z[0-9]+\.s), w7\n\tinsr\t\1, w6\n\tinsr\t\1, w5\n\tinsr\t\1, w4\n\tinsr\t\1, w3\n\tinsr\t\1, w2\n\tinsr\t\1, w1\n\tinsr\t\1, w0} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/init_8.c b/gcc/testsuite/gcc.target/aarch64/sve/init_8.c
index 73f7aba..9c24567 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/init_8.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/init_8.c
@@ -1,5 +1,6 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
/* Case 5.2: Interleaved elements and constants. */
@@ -7,26 +8,19 @@
typedef int32_t vnx4si __attribute__((vector_size (32)));
+/*
+** foo:
+** ...
+** ld1w (z[0-9]+\.s), p[0-9]+/z, \[x[0-9]+\]
+** mov (z[0-9]+\.s), w3
+** insr \2, w2
+** insr \2, w1
+** insr \2, w0
+** zip1 \2, \2, \1
+** ...
+*/
__attribute__((noipa))
vnx4si foo(int a, int b, int c, int d)
{
return (vnx4si) { a, 1, b, 2, c, 3, d, 4 };
}
-
-/*
-foo:
-.LFB0:
- .cfi_startproc
- ptrue p0.s, vl8
- adrp x4, .LANCHOR0
- add x4, x4, :lo12:.LANCHOR0
- ld1w z1.s, p0/z, [x4]
- mov z0.s, w3
- insr z0.s, w2
- insr z0.s, w1
- insr z0.s, w0
- zip1 z0.s, z0.s, z1.s
- ret
-*/
-
-/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+\.s), p[0-9]+/z, \[x[0-9]+\]\n\tmov\t(z[0-9]+\.s), w3\n\tinsr\t\2, w2\n\tinsr\t\2, w1\n\tinsr\t\2, w0\n\tzip1\t\2, \2, \1} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/init_9.c b/gcc/testsuite/gcc.target/aarch64/sve/init_9.c
index 2cc564a..d22ab71 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/init_9.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/init_9.c
@@ -1,5 +1,6 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-final { check-function-bodies "**" "" } } */
/* Case 5.3: Repeated elements. */
@@ -7,20 +8,15 @@
typedef int32_t vnx4si __attribute__((vector_size (32)));
+/*
+** foo:
+** mov (z[0-9]+\.s), w0
+** mov (z[0-9]+\.s), w1
+** zip1 \1, \1, \2
+** ...
+*/
__attribute__((noipa))
vnx4si foo(int a, int b)
{
return (vnx4si) { a, b, a, b, a, b, a, b };
}
-
-/*
-foo:
-.LFB0:
- .cfi_startproc
- mov z0.s, w0
- mov z1.s, w1
- zip1 z0.s, z0.s, z1.s
- ret
-*/
-
-/* { dg-final { scan-assembler {\tmov\t(z[0-9]+\.s), w0\n\tmov\t(z[0-9]+\.s), w1\n\tzip1\t\1, \1, \2} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/ld1r_2.c b/gcc/testsuite/gcc.target/aarch64/sve/ld1r_2.c
index 2e6b59a..e0e0f4e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/ld1r_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/ld1r_2.c
@@ -28,22 +28,6 @@
T (int64_t)
#define FOR_EACH_LOAD_BROADCAST_IMM(T) \
- T (int16_t, 129, imm_129) \
- T (int32_t, 129, imm_129) \
- T (int64_t, 129, imm_129) \
- \
- T (int16_t, -130, imm_m130) \
- T (int32_t, -130, imm_m130) \
- T (int64_t, -130, imm_m130) \
- \
- T (int16_t, 0x1234, imm_0x1234) \
- T (int32_t, 0x1234, imm_0x1234) \
- T (int64_t, 0x1234, imm_0x1234) \
- \
- T (int16_t, 0xFEDC, imm_0xFEDC) \
- T (int32_t, 0xFEDC, imm_0xFEDC) \
- T (int64_t, 0xFEDC, imm_0xFEDC) \
- \
T (int32_t, 0x12345678, imm_0x12345678) \
T (int64_t, 0x12345678, imm_0x12345678) \
\
@@ -56,6 +40,6 @@ FOR_EACH_LOAD_BROADCAST (DEF_LOAD_BROADCAST)
FOR_EACH_LOAD_BROADCAST_IMM (DEF_LOAD_BROADCAST_IMM)
/* { dg-final { scan-assembler-times {\tld1rb\tz[0-9]+\.b, p[0-7]/z, } 1 } } */
-/* { dg-final { scan-assembler-times {\tld1rh\tz[0-9]+\.h, p[0-7]/z, } 5 } } */
-/* { dg-final { scan-assembler-times {\tld1rw\tz[0-9]+\.s, p[0-7]/z, } 7 } } */
-/* { dg-final { scan-assembler-times {\tld1rd\tz[0-9]+\.d, p[0-7]/z, } 8 } } */
+/* { dg-final { scan-assembler-times {\tld1rh\tz[0-9]+\.h, p[0-7]/z, } 1 } } */
+/* { dg-final { scan-assembler-times {\tld1rw\tz[0-9]+\.s, p[0-7]/z, } 3 } } */
+/* { dg-final { scan-assembler-times {\tld1rd\tz[0-9]+\.d, p[0-7]/z, } 4 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/loop_add_4.c b/gcc/testsuite/gcc.target/aarch64/sve/loop_add_4.c
index 7f02497..9ead9c2 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/loop_add_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/loop_add_4.c
@@ -68,7 +68,8 @@ TEST_ALL (LOOP)
/* { dg-final { scan-assembler-times {\tindex\tz[0-9]+\.s, w[0-9]+, w[0-9]+\n} 3 } } */
/* { dg-final { scan-assembler-times {\tld1w\tz[0-9]+\.s, p[0-7]+/z, \[x[0-9]+, x[0-9]+, lsl 2\]} 8 } } */
/* { dg-final { scan-assembler-times {\tst1w\tz[0-9]+\.s, p[0-7]+, \[x[0-9]+, x[0-9]+, lsl 2\]} 8 } } */
-/* { dg-final { scan-assembler-times {\tincw\tx[0-9]+\n} 8 } } */
+/* 2 for the calculations of -17 and 17. */
+/* { dg-final { scan-assembler-times {\tincw\tx[0-9]+\n} 10 } } */
/* { dg-final { scan-assembler-times {\tdecw\tz[0-9]+\.s, all, mul #16\n} 1 } } */
/* { dg-final { scan-assembler-times {\tdecw\tz[0-9]+\.s, all, mul #15\n} 1 } } */
@@ -85,7 +86,8 @@ TEST_ALL (LOOP)
/* { dg-final { scan-assembler-times {\tindex\tz[0-9]+\.d, x[0-9]+, x[0-9]+\n} 3 } } */
/* { dg-final { scan-assembler-times {\tld1d\tz[0-9]+\.d, p[0-7]+/z, \[x[0-9]+, x[0-9]+, lsl 3\]} 8 } } */
/* { dg-final { scan-assembler-times {\tst1d\tz[0-9]+\.d, p[0-7]+, \[x[0-9]+, x[0-9]+, lsl 3\]} 8 } } */
-/* { dg-final { scan-assembler-times {\tincd\tx[0-9]+\n} 8 } } */
+/* 2 for the calculations of -17 and 17. */
+/* { dg-final { scan-assembler-times {\tincd\tx[0-9]+\n} 10 } } */
/* { dg-final { scan-assembler-times {\tdecd\tz[0-9]+\.d, all, mul #16\n} 1 } } */
/* { dg-final { scan-assembler-times {\tdecd\tz[0-9]+\.d, all, mul #15\n} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/mask_load_1.c b/gcc/testsuite/gcc.target/aarch64/sve/mask_load_1.c
new file mode 100644
index 0000000..e76d365
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/mask_load_1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -msve-vector-bits=256 -fdump-tree-optimized" } */
+
+void
+f (int *x)
+{
+ for (int i = 0; i < 8; ++i)
+ x[i] += 1;
+}
+
+/* { dg-final { scan-tree-dump { = MEM <vector\(8\) int>} "optimized" } } */
+/* { dg-final { scan-tree-dump { MEM <vector\(8\) int> \[[^]]*\] = } "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_1.c b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_1.c
index a064c33..156d04a 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_1.c
@@ -25,3 +25,4 @@ foo (void)
/* We should use an induction that starts at -5, with only the last
7 elements of the first iteration being active. */
/* { dg-final { scan-assembler {\tindex\tz[0-9]+\.s, #-5, #5\n} } } */
+/* { dg-final { scan-assembler {\tptrue\t(p[0-9]+\.b), vl1\n.*\tnot\tp[0-7]\.b, p[0-7]/z, \1\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_2.c b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_2.c
index f2113be..e792cdf 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/peel_ind_2.c
@@ -20,3 +20,4 @@ foo (void)
/* { dg-final { scan-assembler {\t(adrp|adr)\tx[0-9]+, x\n} } } */
/* We should unroll the loop three times. */
/* { dg-final { scan-assembler-times "\tst1w\t" 3 } } */
+/* { dg-final { scan-assembler {\tptrue\t(p[0-9]+)\.s, vl7\n.*\teor\tp[0-7]\.b, (p[0-7])/z, (\1\.b, \2\.b|\2\.b, \1\.b)\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/pr91166.c b/gcc/testsuite/gcc.target/aarch64/sve/pr91166.c
new file mode 100644
index 0000000..42654be
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/pr91166.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=armv8.2-a+sve -fdump-tree-optimized" } */
+
+void
+f1 (double x[][4])
+{
+ for (int i = 0; i < 4; ++i)
+ for (int j = 0; j < 4; ++j)
+ x[i][j] = 0;
+}
+
+void
+f2 (double x[][4], double y)
+{
+ for (int i = 0; i < 4; ++i)
+ for (int j = 0; j < 4; ++j)
+ x[i][j] = y;
+}
+
+/* { dg-final { scan-tree-dump-not "VEC_PERM_EXPR" "optimized"} } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/revb_1.c b/gcc/testsuite/gcc.target/aarch64/sve/revb_1.c
index 1a3d9b4..9cf2f27 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/revb_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/revb_1.c
@@ -1,9 +1,7 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
-/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-options "-O -msve-vector-bits=256 --save-temps -mlittle-endian" } */
-#include <stdint.h>
-
-typedef int8_t vnx16qi __attribute__((vector_size (32)));
+typedef __INT8_TYPE__ vnx16qi __attribute__((vector_size (32)));
#define MASK_2(X, Y) (X) ^ (Y), (X + 1) ^ (Y)
#define MASK_4(X, Y) MASK_2 (X, Y), MASK_2 (X + 2, Y)
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/revb_2.c b/gcc/testsuite/gcc.target/aarch64/sve/revb_2.c
new file mode 100644
index 0000000..389739c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/revb_2.c
@@ -0,0 +1,10 @@
+/* { dg-do assemble { target aarch64_asm_sve_ok } } */
+/* { dg-options "-O -msve-vector-bits=256 --save-temps -mbig-endian" } */
+
+#include "revb_1.c"
+
+/* { dg-final { scan-assembler-not {\ttbl\t} } } */
+
+/* { dg-final { scan-assembler-times {\trevb\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d} 1 } } */
+/* { dg-final { scan-assembler-times {\trevb\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s} 1 } } */
+/* { dg-final { scan-assembler-times {\trevb\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/revh_1.c b/gcc/testsuite/gcc.target/aarch64/sve/revh_1.c
index 7614581..28a0399 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/revh_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/revh_1.c
@@ -1,9 +1,7 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
-/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-options "-O -msve-vector-bits=256 --save-temps -mlittle-endian" } */
-#include <stdint.h>
-
-typedef uint16_t vnx8hi __attribute__((vector_size (32)));
+typedef __UINT16_TYPE__ vnx8hi __attribute__((vector_size (32)));
typedef _Float16 vnx8hf __attribute__((vector_size (32)));
#define MASK_2(X, Y) (X) ^ (Y), (X + 1) ^ (Y)
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/revh_2.c b/gcc/testsuite/gcc.target/aarch64/sve/revh_2.c
new file mode 100644
index 0000000..e821b64
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/revh_2.c
@@ -0,0 +1,9 @@
+/* { dg-do assemble { target aarch64_asm_sve_ok } } */
+/* { dg-options "-O -msve-vector-bits=256 --save-temps -mbig-endian" } */
+
+#include "revh_1.c"
+
+/* { dg-final { scan-assembler-not {\ttbl\t} } } */
+
+/* { dg-final { scan-assembler-times {\trevh\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d} 2 } } */
+/* { dg-final { scan-assembler-times {\trevh\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s} 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/revw_1.c b/gcc/testsuite/gcc.target/aarch64/sve/revw_1.c
index 8ac68b7..de92675 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/revw_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/revw_1.c
@@ -1,9 +1,7 @@
/* { dg-do assemble { target aarch64_asm_sve_ok } } */
-/* { dg-options "-O -msve-vector-bits=256 --save-temps" } */
+/* { dg-options "-O -msve-vector-bits=256 --save-temps -mlittle-endian" } */
-#include <stdint.h>
-
-typedef uint32_t vnx4si __attribute__((vector_size (32)));
+typedef __UINT32_TYPE__ vnx4si __attribute__((vector_size (32)));
typedef float vnx4sf __attribute__((vector_size (32)));
#define MASK_2(X, Y) (X) ^ (Y), (X + 1) ^ (Y)
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/revw_2.c b/gcc/testsuite/gcc.target/aarch64/sve/revw_2.c
new file mode 100644
index 0000000..17243c0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/revw_2.c
@@ -0,0 +1,8 @@
+/* { dg-do assemble { target aarch64_asm_sve_ok } } */
+/* { dg-options "-O -msve-vector-bits=256 --save-temps -mbig-endian" } */
+
+#include "revw_1.c"
+
+/* { dg-final { scan-assembler-not {\ttbl\t} } } */
+
+/* { dg-final { scan-assembler-times {\trevw\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d} 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/shift_1.c b/gcc/testsuite/gcc.target/aarch64/sve/shift_1.c
index f4c5ebd..5ee66da 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/shift_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/shift_1.c
@@ -75,9 +75,9 @@ DO_IMMEDIATE_OPS (63, int64_t, 63);
/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */
/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tlsl\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tasrr?\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlsrr?\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tlslr?\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
/* { dg-final { scan-assembler-times {\tasr\tz[0-9]+\.b, z[0-9]+\.b, #5\n} 1 } } */
/* { dg-final { scan-assembler-times {\tlsr\tz[0-9]+\.b, z[0-9]+\.b, #5\n} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/single_1.c b/gcc/testsuite/gcc.target/aarch64/sve/single_1.c
index e3a8409..d9bb97e 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/single_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/single_1.c
@@ -40,10 +40,7 @@ TEST_LOOP (double, 3.0)
/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0e\+0\n} 1 } } */
/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #3\.0e\+0\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.b, vl32\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.h, vl16\n} 3 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.s, vl8\n} 3 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.d, vl4\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.b, vl32\n} 11 } } */
/* { dg-final { scan-assembler-times {\tst1b\tz[0-9]+\.b,} 2 } } */
/* { dg-final { scan-assembler-times {\tst1h\tz[0-9]+\.h,} 3 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/single_2.c b/gcc/testsuite/gcc.target/aarch64/sve/single_2.c
index 195ee20..d27eead 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/single_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/single_2.c
@@ -16,10 +16,7 @@
/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0e\+0\n} 1 } } */
/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #3\.0e\+0\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.b, vl64\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.h, vl32\n} 3 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.s, vl16\n} 3 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.d, vl8\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.b, vl64\n} 11 } } */
/* { dg-final { scan-assembler-times {\tst1b\tz[0-9]+\.b,} 2 } } */
/* { dg-final { scan-assembler-times {\tst1h\tz[0-9]+\.h,} 3 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/single_3.c b/gcc/testsuite/gcc.target/aarch64/sve/single_3.c
index e031276..313a72d 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/single_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/single_3.c
@@ -16,10 +16,7 @@
/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0e\+0\n} 1 } } */
/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #3\.0e\+0\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.b, vl128\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.h, vl64\n} 3 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.s, vl32\n} 3 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.d, vl16\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.b, vl128\n} 11 } } */
/* { dg-final { scan-assembler-times {\tst1b\tz[0-9]+\.b,} 2 } } */
/* { dg-final { scan-assembler-times {\tst1h\tz[0-9]+\.h,} 3 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/single_4.c b/gcc/testsuite/gcc.target/aarch64/sve/single_4.c
index 01ff7f6..4f46654 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/single_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/single_4.c
@@ -16,10 +16,7 @@
/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.s, #2\.0e\+0\n} 1 } } */
/* { dg-final { scan-assembler-times {\tfmov\tz[0-9]+\.d, #3\.0e\+0\n} 1 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.b, vl256\n} 2 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.h, vl128\n} 3 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.s, vl64\n} 3 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.d, vl32\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.b, vl256\n} 11 } } */
/* { dg-final { scan-assembler-times {\tst1b\tz[0-9]+\.b,} 2 } } */
/* { dg-final { scan-assembler-times {\tst1h\tz[0-9]+\.h,} 3 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/slp_2.c b/gcc/testsuite/gcc.target/aarch64/sve/slp_2.c
index 413532c..d4b9776 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/slp_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/slp_2.c
@@ -29,12 +29,9 @@ vec_slp_##TYPE (TYPE *restrict a, int n) \
TEST_ALL (VEC_PERM)
-/* { dg-final { scan-assembler-times {\tld1rh\tz[0-9]+\.h, } 2 { target aarch64_little_endian } } } */
-/* { dg-final { scan-assembler-times {\tld1rqb\tz[0-9]+\.b, } 2 { target aarch64_big_endian } } } */
-/* { dg-final { scan-assembler-times {\tld1rw\tz[0-9]+\.s, } 3 { target aarch64_little_endian } } } */
-/* { dg-final { scan-assembler-times {\tld1rqh\tz[0-9]+\.h, } 3 { target aarch64_big_endian } } } */
-/* { dg-final { scan-assembler-times {\tld1rd\tz[0-9]+\.d, } 3 { target aarch64_little_endian } } } */
-/* { dg-final { scan-assembler-times {\tld1rqw\tz[0-9]+\.s, } 3 { target aarch64_big_endian } } } */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, w[0-9]+\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tld1rw\tz[0-9]+\.s, } 3 } } */
+/* { dg-final { scan-assembler-times {\tld1rd\tz[0-9]+\.d, } 3 } } */
/* { dg-final { scan-assembler-times {\tld1rqd\tz[0-9]+\.d, } 3 } } */
/* { dg-final { scan-assembler-not {\tzip1\t} } } */
/* { dg-final { scan-assembler-not {\tzip2\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/slp_3.c b/gcc/testsuite/gcc.target/aarch64/sve/slp_3.c
index 0f9f01a..82dd43a 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/slp_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/slp_3.c
@@ -32,18 +32,17 @@ vec_slp_##TYPE (TYPE *restrict a, int n) \
TEST_ALL (VEC_PERM)
/* 1 for each 8-bit type. */
-/* { dg-final { scan-assembler-times {\tld1rw\tz[0-9]+\.s, } 2 { target aarch64_little_endian } } } */
-/* { dg-final { scan-assembler-times {\tld1rqb\tz[0-9]+\.b, } 2 { target aarch64_big_endian } } } */
-/* 1 for each 16-bit type and 4 for double. */
-/* { dg-final { scan-assembler-times {\tld1rd\tz[0-9]+\.d, } 7 { target aarch64_little_endian } } } */
-/* { dg-final { scan-assembler-times {\tld1rqh\tz[0-9]+\.h, } 3 { target aarch64_big_endian } } } */
-/* { dg-final { scan-assembler-times {\tld1rd\tz[0-9]+\.d, } 4 { target aarch64_big_endian } } } */
+/* { dg-final { scan-assembler-times {\tld1rw\tz[0-9]+\.s, } 2 } } */
+/* 1 for each 16-bit type plus 1 for double. */
+/* { dg-final { scan-assembler-times {\tld1rd\tz[0-9]+\.d, } 4 } } */
/* 1 for each 32-bit type. */
/* { dg-final { scan-assembler-times {\tld1rqw\tz[0-9]+\.s, } 3 } } */
/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #41\n} 2 } } */
/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #25\n} 2 } } */
/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #31\n} 2 } } */
/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #62\n} 2 } } */
+/* 3 for double. */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, x[0-9]+\n} 3 } } */
/* The 64-bit types need:
ZIP1 ZIP1 (2 ZIP2s optimized away)
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/slp_4.c b/gcc/testsuite/gcc.target/aarch64/sve/slp_4.c
index 8d9d5ab..49fb828 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/slp_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/slp_4.c
@@ -35,10 +35,8 @@ vec_slp_##TYPE (TYPE *restrict a, int n) \
TEST_ALL (VEC_PERM)
-/* 1 for each 8-bit type, 4 for each 32-bit type and 8 for double. */
-/* { dg-final { scan-assembler-times {\tld1rd\tz[0-9]+\.d, } 22 { target aarch64_little_endian } } } */
-/* { dg-final { scan-assembler-times {\tld1rqb\tz[0-9]+\.b, } 2 { target aarch64_big_endian } } } */
-/* { dg-final { scan-assembler-times {\tld1rd\tz[0-9]+\.d, } 20 { target aarch64_big_endian } } } */
+/* 1 for each 8-bit type, 4 for each 32-bit type and 4 for double. */
+/* { dg-final { scan-assembler-times {\tld1rd\tz[0-9]+\.d, } 18 } } */
/* 1 for each 16-bit type. */
/* { dg-final { scan-assembler-times {\tld1rqh\tz[0-9]\.h, } 3 } } */
/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #99\n} 2 } } */
@@ -49,6 +47,8 @@ TEST_ALL (VEC_PERM)
/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #37\n} 2 } } */
/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #24\n} 2 } } */
/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, #81\n} 2 } } */
+/* 4 for double. */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.d, x[0-9]+\n} 4 } } */
/* The 32-bit types need:
ZIP1 ZIP1 (2 ZIP2s optimized away)
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/smax_1.c b/gcc/testsuite/gcc.target/aarch64/sve/smax_1.c
new file mode 100644
index 0000000..050248c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/smax_1.c
@@ -0,0 +1,71 @@
+/* { dg-do assemble { target aarch64_asm_sve_ok } } */
+/* { dg-options "-O3 --save-temps" } */
+
+#include <stdint.h>
+
+#define DO_REGREG_OPS(TYPE) \
+void varith_##TYPE##_reg (TYPE *dst, TYPE *src, int count) \
+{ \
+ for (int i = 0; i < count; ++i) \
+ dst[i] = dst[i] > src[i] ? dst[i] : src[i]; \
+}
+
+#define DO_IMMEDIATE_OPS(VALUE, TYPE, NAME) \
+void varithimm_##NAME##_##TYPE (TYPE *dst, int count) \
+{ \
+ for (int i = 0; i < count; ++i) \
+ dst[i] = dst[i] > (TYPE) VALUE ? dst[i] : (TYPE) VALUE; \
+}
+
+#define DO_ARITH_OPS(TYPE) \
+ DO_REGREG_OPS (TYPE); \
+ DO_IMMEDIATE_OPS (0, TYPE, 0); \
+ DO_IMMEDIATE_OPS (86, TYPE, 86); \
+ DO_IMMEDIATE_OPS (109, TYPE, 109); \
+ DO_IMMEDIATE_OPS (141, TYPE, 141); \
+ DO_IMMEDIATE_OPS (-1, TYPE, minus1); \
+ DO_IMMEDIATE_OPS (-110, TYPE, minus110); \
+ DO_IMMEDIATE_OPS (-141, TYPE, minus141);
+
+DO_ARITH_OPS (int8_t)
+DO_ARITH_OPS (int16_t)
+DO_ARITH_OPS (int32_t)
+DO_ARITH_OPS (int64_t)
+
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, z[0-9]+\.b\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.b, z[0-9]+\.b, #0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.b, z[0-9]+\.b, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.b, z[0-9]+\.b, #109\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.b, z[0-9]+\.b, #115\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmax\tz[0-9]+\.b, z[0-9]+\.b, #141\n} } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.b, z[0-9]+\.b, #-1\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.b, z[0-9]+\.b, #-110\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.b, z[0-9]+\.b, #-115\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmax\tz[0-9]+\.b, z[0-9]+\.b, #-141\n} } } */
+
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.h, z[0-9]+\.h, #0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.h, z[0-9]+\.h, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.h, z[0-9]+\.h, #109\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmax\tz[0-9]+\.h, z[0-9]+\.h, #141\n} } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.h, z[0-9]+\.h, #-1\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.h, z[0-9]+\.h, #-110\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmax\tz[0-9]+\.h, z[0-9]+\.h, #-141\n} } } */
+
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.s, z[0-9]+\.s, #0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.s, z[0-9]+\.s, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.s, z[0-9]+\.s, #109\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmax\tz[0-9]+\.s, z[0-9]+\.s, #141\n} } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.s, z[0-9]+\.s, #-1\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.s, z[0-9]+\.s, #-110\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmax\tz[0-9]+\.s, z[0-9]+\.s, #-141\n} } } */
+
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.d, z[0-9]+\.d, #0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.d, z[0-9]+\.d, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.d, z[0-9]+\.d, #109\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmax\tz[0-9]+\.d, z[0-9]+\.d, #141\n} } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.d, z[0-9]+\.d, #-1\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmax\tz[0-9]+\.d, z[0-9]+\.d, #-110\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmax\tz[0-9]+\.d, z[0-9]+\.d, #-141\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/smin_1.c b/gcc/testsuite/gcc.target/aarch64/sve/smin_1.c
new file mode 100644
index 0000000..d6a9e94
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/smin_1.c
@@ -0,0 +1,71 @@
+/* { dg-do assemble { target aarch64_asm_sve_ok } } */
+/* { dg-options "-O3 --save-temps" } */
+
+#include <stdint.h>
+
+#define DO_REGREG_OPS(TYPE) \
+void varith_##TYPE##_reg (TYPE *dst, TYPE *src, int count) \
+{ \
+ for (int i = 0; i < count; ++i) \
+ dst[i] = dst[i] < src[i] ? dst[i] : src[i]; \
+}
+
+#define DO_IMMEDIATE_OPS(VALUE, TYPE, NAME) \
+void varithimm_##NAME##_##TYPE (TYPE *dst, int count) \
+{ \
+ for (int i = 0; i < count; ++i) \
+ dst[i] = dst[i] < (TYPE) VALUE ? dst[i] : (TYPE) VALUE; \
+}
+
+#define DO_ARITH_OPS(TYPE) \
+ DO_REGREG_OPS (TYPE); \
+ DO_IMMEDIATE_OPS (0, TYPE, 0); \
+ DO_IMMEDIATE_OPS (86, TYPE, 86); \
+ DO_IMMEDIATE_OPS (109, TYPE, 109); \
+ DO_IMMEDIATE_OPS (141, TYPE, 141); \
+ DO_IMMEDIATE_OPS (-1, TYPE, minus1); \
+ DO_IMMEDIATE_OPS (-110, TYPE, minus110); \
+ DO_IMMEDIATE_OPS (-141, TYPE, minus141);
+
+DO_ARITH_OPS (int8_t)
+DO_ARITH_OPS (int16_t)
+DO_ARITH_OPS (int32_t)
+DO_ARITH_OPS (int64_t)
+
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, z[0-9]+\.b\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.b, z[0-9]+\.b, #0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.b, z[0-9]+\.b, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.b, z[0-9]+\.b, #109\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.b, z[0-9]+\.b, #115\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmin\tz[0-9]+\.b, z[0-9]+\.b, #141\n} } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.b, z[0-9]+\.b, #-1\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.b, z[0-9]+\.b, #-110\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.b, z[0-9]+\.b, #-115\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmin\tz[0-9]+\.b, z[0-9]+\.b, #-141\n} } } */
+
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.h, z[0-9]+\.h, #0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.h, z[0-9]+\.h, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.h, z[0-9]+\.h, #109\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmin\tz[0-9]+\.h, z[0-9]+\.h, #141\n} } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.h, z[0-9]+\.h, #-1\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.h, z[0-9]+\.h, #-110\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmin\tz[0-9]+\.h, z[0-9]+\.h, #-141\n} } } */
+
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.s, z[0-9]+\.s, #0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.s, z[0-9]+\.s, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.s, z[0-9]+\.s, #109\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmin\tz[0-9]+\.s, z[0-9]+\.s, #141\n} } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.s, z[0-9]+\.s, #-1\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.s, z[0-9]+\.s, #-110\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmin\tz[0-9]+\.s, z[0-9]+\.s, #-141\n} } } */
+
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 3 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.d, z[0-9]+\.d, #0\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.d, z[0-9]+\.d, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.d, z[0-9]+\.d, #109\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmin\tz[0-9]+\.d, z[0-9]+\.d, #141\n} } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.d, z[0-9]+\.d, #-1\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsmin\tz[0-9]+\.d, z[0-9]+\.d, #-110\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tsmin\tz[0-9]+\.d, z[0-9]+\.d, #-141\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/spill_2.c b/gcc/testsuite/gcc.target/aarch64/sve/spill_2.c
index 28fcc44..fcd4816 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/spill_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/spill_2.c
@@ -9,29 +9,30 @@ void consumer (void *);
void \
multi_loop_##TYPE (TYPE *x, TYPE val) \
{ \
- for (int i = 0; i < 7; ++i) \
+ for (int i = 0; i < 9; ++i) \
x[i] += val; \
consumer (x); \
- for (int i = 0; i < 7; ++i) \
+ for (int i = 0; i < 9; ++i) \
x[i] += val; \
consumer (x); \
- for (int i = 0; i < 7; ++i) \
+ for (int i = 0; i < 9; ++i) \
x[i] += val; \
consumer (x); \
}
/* One iteration is enough. */
TEST_LOOP (uint8_t);
+/* Two iterations are enough. We specialize the second two loops based
+ on whether the first executes once or twice. */
TEST_LOOP (uint16_t);
-/* Two iterations are enough. Complete unrolling makes sense
- even at -O2. */
+/* Three iterations are needed; ought to stay a loop. */
TEST_LOOP (uint32_t);
-/* Four iterations are needed; ought to stay a loop. */
+/* Five iterations are needed; ought to stay a loop. */
TEST_LOOP (uint64_t);
/* { dg-final { scan-assembler-times {\twhilelo\tp[0-9]\.b} 3 } } */
-/* { dg-final { scan-assembler-times {\twhilelo\tp[0-9]\.h} 3 } } */
-/* { dg-final { scan-assembler {\twhilelo\tp[0-9]\.s} } } */
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-9]\.h} 8 } } */
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-9]\.s} 6 } } */
/* { dg-final { scan-assembler-times {\twhilelo\tp[0-9]\.d} 6 } } */
/* { dg-final { scan-assembler-not {\tldr\tz[0-9]} } } */
/* { dg-final { scan-assembler-not {\tstr\tz[0-9]} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/spill_4.c b/gcc/testsuite/gcc.target/aarch64/sve/spill_4.c
index 29e1a49..81b3f64 100644
--- a/gcc/testsuite/gcc.target/aarch64/sve/spill_4.c
+++ b/gcc/testsuite/gcc.target/aarch64/sve/spill_4.c
@@ -24,10 +24,11 @@ TEST_LOOP (uint16_t, 0x1234);
TEST_LOOP (uint32_t, 0x12345);
TEST_LOOP (uint64_t, 0x123456);
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-9]+\.h,} 3 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-9]+\.s,} 3 } } */
-/* { dg-final { scan-assembler-times {\tptrue\tp[0-9]+\.d,} 3 } } */
-/* { dg-final { scan-assembler-times {\tld1rh\tz[0-9]+\.h,} 3 } } */
+/* { dg-final { scan-assembler-times {\tptrue\tp[0-9]+\.b,} 6 } } */
+/* { dg-final { scan-assembler-not {\tptrue\tp[0-9]+\.h,} } } */
+/* { dg-final { scan-assembler-not {\tptrue\tp[0-9]+\.s,} } } */
+/* { dg-final { scan-assembler-not {\tptrue\tp[0-9]+\.d,} } } */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, w[0-9]+\n} 3 } } */
/* { dg-final { scan-assembler-times {\tld1rw\tz[0-9]+\.s,} 3 } } */
/* { dg-final { scan-assembler-times {\tld1rd\tz[0-9]+\.d,} 3 } } */
/* { dg-final { scan-assembler-not {\tldr\tz[0-9]} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/umax_1.c b/gcc/testsuite/gcc.target/aarch64/sve/umax_1.c
new file mode 100644
index 0000000..fffedb9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/umax_1.c
@@ -0,0 +1,65 @@
+/* { dg-do assemble { target aarch64_asm_sve_ok } } */
+/* { dg-options "-O3 --save-temps" } */
+
+#include <stdint.h>
+
+#define DO_REGREG_OPS(TYPE) \
+void varith_##TYPE##_reg (TYPE *dst, TYPE *src, int count) \
+{ \
+ for (int i = 0; i < count; ++i) \
+ dst[i] = dst[i] > src[i] ? dst[i] : src[i]; \
+}
+
+#define DO_IMMEDIATE_OPS(VALUE, TYPE) \
+void varithimm_##VALUE##_##TYPE (TYPE *dst, int count) \
+{ \
+ for (int i = 0; i < count; ++i) \
+ dst[i] = dst[i] > (TYPE) VALUE ? dst[i] : (TYPE) VALUE; \
+}
+
+#define DO_ARITH_OPS(TYPE) \
+ DO_REGREG_OPS (TYPE); \
+ DO_IMMEDIATE_OPS (2, TYPE); \
+ DO_IMMEDIATE_OPS (86, TYPE); \
+ DO_IMMEDIATE_OPS (109, TYPE); \
+ DO_IMMEDIATE_OPS (141, TYPE); \
+ DO_IMMEDIATE_OPS (229, TYPE); \
+ DO_IMMEDIATE_OPS (255, TYPE); \
+ DO_IMMEDIATE_OPS (256, TYPE);
+
+DO_ARITH_OPS (uint8_t)
+DO_ARITH_OPS (uint16_t)
+DO_ARITH_OPS (uint32_t)
+DO_ARITH_OPS (uint64_t)
+
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, z[0-9]+\.b\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.b, z[0-9]+\.b, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.b, z[0-9]+\.b, #109\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.b, z[0-9]+\.b, #141\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.b, z[0-9]+\.b, #229\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tumax\tz[0-9]+\.b, z[0-9]+\.b, #255\n} } } */
+/* { dg-final { scan-assembler-not {\tumax\tz[0-9]+\.b, z[0-9]+\.b, #256\n} } } */
+
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.h, z[0-9]+\.h, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.h, z[0-9]+\.h, #109\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.h, z[0-9]+\.h, #141\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.h, z[0-9]+\.h, #229\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.h, z[0-9]+\.h, #255\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tumax\tz[0-9]+\.h, z[0-9]+\.h, #256\n} } } */
+
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.s, z[0-9]+\.s, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.s, z[0-9]+\.s, #109\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.s, z[0-9]+\.s, #141\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.s, z[0-9]+\.s, #229\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.s, z[0-9]+\.s, #255\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tumax\tz[0-9]+\.s, z[0-9]+\.s, #256\n} } } */
+
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.d, z[0-9]+\.d, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.d, z[0-9]+\.d, #109\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.d, z[0-9]+\.d, #141\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.d, z[0-9]+\.d, #229\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumax\tz[0-9]+\.d, z[0-9]+\.d, #255\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tumax\tz[0-9]+\.d, z[0-9]+\.d, #256\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/umin_1.c b/gcc/testsuite/gcc.target/aarch64/sve/umin_1.c
new file mode 100644
index 0000000..f7cdba3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/umin_1.c
@@ -0,0 +1,65 @@
+/* { dg-do assemble { target aarch64_asm_sve_ok } } */
+/* { dg-options "-O3 --save-temps" } */
+
+#include <stdint.h>
+
+#define DO_REGREG_OPS(TYPE) \
+void varith_##TYPE##_reg (TYPE *dst, TYPE *src, int count) \
+{ \
+ for (int i = 0; i < count; ++i) \
+ dst[i] = dst[i] < src[i] ? dst[i] : src[i]; \
+}
+
+#define DO_IMMEDIATE_OPS(VALUE, TYPE) \
+void varithimm_##VALUE##_##TYPE (TYPE *dst, int count) \
+{ \
+ for (int i = 0; i < count; ++i) \
+ dst[i] = dst[i] < (TYPE) VALUE ? dst[i] : (TYPE) VALUE; \
+}
+
+#define DO_ARITH_OPS(TYPE) \
+ DO_REGREG_OPS (TYPE); \
+ DO_IMMEDIATE_OPS (2, TYPE); \
+ DO_IMMEDIATE_OPS (86, TYPE); \
+ DO_IMMEDIATE_OPS (109, TYPE); \
+ DO_IMMEDIATE_OPS (141, TYPE); \
+ DO_IMMEDIATE_OPS (229, TYPE); \
+ DO_IMMEDIATE_OPS (255, TYPE); \
+ DO_IMMEDIATE_OPS (256, TYPE);
+
+DO_ARITH_OPS (uint8_t)
+DO_ARITH_OPS (uint16_t)
+DO_ARITH_OPS (uint32_t)
+DO_ARITH_OPS (uint64_t)
+
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.b, p[0-7]/m, z[0-9]+\.b, z[0-9]+\.b\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.b, z[0-9]+\.b, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.b, z[0-9]+\.b, #109\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.b, z[0-9]+\.b, #141\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.b, z[0-9]+\.b, #229\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tumin\tz[0-9]+\.b, z[0-9]+\.b, #255\n} } } */
+/* { dg-final { scan-assembler-not {\tumin\tz[0-9]+\.b, z[0-9]+\.b, #256\n} } } */
+
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.h, p[0-7]/m, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.h, z[0-9]+\.h, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.h, z[0-9]+\.h, #109\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.h, z[0-9]+\.h, #141\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.h, z[0-9]+\.h, #229\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.h, z[0-9]+\.h, #255\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tumin\tz[0-9]+\.h, z[0-9]+\.h, #256\n} } } */
+
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.s, p[0-7]/m, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.s, z[0-9]+\.s, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.s, z[0-9]+\.s, #109\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.s, z[0-9]+\.s, #141\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.s, z[0-9]+\.s, #229\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.s, z[0-9]+\.s, #255\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tumin\tz[0-9]+\.s, z[0-9]+\.s, #256\n} } } */
+
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.d, p[0-7]/m, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.d, z[0-9]+\.d, #86\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.d, z[0-9]+\.d, #109\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.d, z[0-9]+\.d, #141\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.d, z[0-9]+\.d, #229\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tumin\tz[0-9]+\.d, z[0-9]+\.d, #255\n} 1 } } */
+/* { dg-final { scan-assembler-not {\tumin\tz[0-9]+\.d, z[0-9]+\.d, #256\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vcond_17.c b/gcc/testsuite/gcc.target/aarch64/sve/vcond_17.c
new file mode 100644
index 0000000..cabcfa7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vcond_17.c
@@ -0,0 +1,94 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include <stdint.h>
+
+#define eq(A, B) ((A) == (B))
+#define ne(A, B) ((A) != (B))
+#define olt(A, B) ((A) < (B))
+#define ole(A, B) ((A) <= (B))
+#define oge(A, B) ((A) >= (B))
+#define ogt(A, B) ((A) > (B))
+#define ordered(A, B) (!__builtin_isunordered (A, B))
+#define unordered(A, B) (__builtin_isunordered (A, B))
+#define ueq(A, B) (!__builtin_islessgreater (A, B))
+#define ult(A, B) (__builtin_isless (A, B))
+#define ule(A, B) (__builtin_islessequal (A, B))
+#define uge(A, B) (__builtin_isgreaterequal (A, B))
+#define ugt(A, B) (__builtin_isgreater (A, B))
+#define nueq(A, B) (__builtin_islessgreater (A, B))
+#define nult(A, B) (!__builtin_isless (A, B))
+#define nule(A, B) (!__builtin_islessequal (A, B))
+#define nuge(A, B) (!__builtin_isgreaterequal (A, B))
+#define nugt(A, B) (!__builtin_isgreater (A, B))
+
+#define DEF_LOOP(CMP, EXPECT_INVALID) \
+ void __attribute__ ((noinline, noclone)) \
+ test_##CMP##_var (__fp16 *restrict dest, __fp16 *restrict src, \
+ __fp16 fallback, __fp16 *restrict a, \
+ __fp16 *restrict b, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ dest[i] = CMP (a[i], b[i]) ? src[i] : fallback; \
+ } \
+ \
+ void __attribute__ ((noinline, noclone)) \
+ test_##CMP##_zero (__fp16 *restrict dest, __fp16 *restrict src, \
+ __fp16 fallback, __fp16 *restrict a, \
+ int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ dest[i] = CMP (a[i], (__fp16) 0) ? src[i] : fallback; \
+ } \
+ \
+ void __attribute__ ((noinline, noclone)) \
+ test_##CMP##_sel (__fp16 *restrict dest, __fp16 if_true, \
+ __fp16 if_false, __fp16 *restrict a, \
+ __fp16 b, int count) \
+ { \
+ for (int i = 0; i < count; ++i) \
+ dest[i] = CMP (a[i], b) ? if_true : if_false; \
+ }
+
+#define TEST_ALL(T) \
+ T (eq, 0) \
+ T (ne, 0) \
+ T (olt, 1) \
+ T (ole, 1) \
+ T (oge, 1) \
+ T (ogt, 1) \
+ T (ordered, 0) \
+ T (unordered, 0) \
+ T (ueq, 0) \
+ T (ult, 0) \
+ T (ule, 0) \
+ T (uge, 0) \
+ T (ugt, 0) \
+ T (nueq, 0) \
+ T (nult, 0) \
+ T (nule, 0) \
+ T (nuge, 0) \
+ T (nugt, 0)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler {\tfcmeq\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, #0\.0\n} { xfail *-*-* } } } */
+/* { dg-final { scan-assembler {\tfcmeq\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} } } */
+
+/* { dg-final { scan-assembler {\tfcmne\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, #0\.0\n} } } */
+/* { dg-final { scan-assembler {\tfcmne\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} } } */
+
+/* { dg-final { scan-assembler {\tfcmlt\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, #0\.0\n} } } */
+/* { dg-final { scan-assembler {\tfcmlt\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} } } */
+
+/* { dg-final { scan-assembler {\tfcmle\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, #0\.0\n} } } */
+/* { dg-final { scan-assembler {\tfcmle\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} } } */
+
+/* { dg-final { scan-assembler {\tfcmgt\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, #0\.0\n} } } */
+/* { dg-final { scan-assembler {\tfcmgt\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} } } */
+
+/* { dg-final { scan-assembler {\tfcmge\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, #0\.0\n} } } */
+/* { dg-final { scan-assembler {\tfcmge\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} } } */
+
+/* { dg-final { scan-assembler-not {\tfcmuo\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, #0\.0\n} } } */
+/* { dg-final { scan-assembler {\tfcmuo\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vcond_17_run.c b/gcc/testsuite/gcc.target/aarch64/sve/vcond_17_run.c
new file mode 100644
index 0000000..4a228c8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vcond_17_run.c
@@ -0,0 +1,54 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#include <fenv.h>
+
+#include "vcond_17.c"
+
+#define N 401
+
+#define TEST_LOOP(CMP, EXPECT_INVALID) \
+ { \
+ __fp16 dest1[N], dest2[N], dest3[N], src[N]; \
+ __fp16 a[N], b[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ src[i] = i * i; \
+ if (i % 5 == 0) \
+ a[i] = 0; \
+ else if (i % 3) \
+ a[i] = i * 0.1; \
+ else \
+ a[i] = i; \
+ if (i % 7 == 0) \
+ b[i] = __builtin_nan (""); \
+ else if (i % 6) \
+ b[i] = i * 0.1; \
+ else \
+ b[i] = i; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ feclearexcept (FE_ALL_EXCEPT); \
+ test_##CMP##_var (dest1, src, 11, a, b, N); \
+ test_##CMP##_zero (dest2, src, 22, a, N); \
+ test_##CMP##_sel (dest3, 33, 44, a, 9, N); \
+ if (!fetestexcept (FE_INVALID) != !(EXPECT_INVALID)) \
+ __builtin_abort (); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ if (dest1[i] != (CMP (a[i], b[i]) ? src[i] : 11)) \
+ __builtin_abort (); \
+ if (dest2[i] != (CMP (a[i], 0) ? src[i] : 22)) \
+ __builtin_abort (); \
+ if (dest3[i] != (CMP (a[i], 9) ? 33 : 44)) \
+ __builtin_abort (); \
+ } \
+ }
+
+int __attribute__ ((optimize (1)))
+main (void)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vcond_18.c b/gcc/testsuite/gcc.target/aarch64/sve/vcond_18.c
new file mode 100644
index 0000000..a2590b9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vcond_18.c
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#define DEF_LOOP(TYPE, NAME, CONST) \
+ void \
+ test_##TYPE##_##NAME (TYPE *restrict x, \
+ TYPE *restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] > 0 ? CONST : 0; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, 2, 2.0) \
+ T (TYPE, 1p25, 1.25) \
+ T (TYPE, 32p25, 32.25) \
+ T (TYPE, m4, -4.0) \
+ T (TYPE, m2p5, -2.5) \
+ T (TYPE, m64p5, -64.5)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, _Float16) \
+ TEST_TYPE (T, float) \
+ TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, p[0-7]/z, #16384\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, p[0-7]/z, #15616\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, p[0-7]/z, #-15360\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, p[0-7]/z, #-16128\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */
+
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+\.s), (p[0-7])/z, \1\n\tfmov\t\1, \2/m, #2\.0(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+\.s), (p[0-7])/z, \1\n\tfmov\t\1, \2/m, #1\.25(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+\.s), (p[0-7])/z, \1\n\tfmov\t\1, \2/m, #-4\.0(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+\.s), (p[0-7])/z, \1\n\tfmov\t\1, \2/m, #-2\.5(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.s, p[0-7], z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */
+
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+\.d), (p[0-7])/z, \1\n\tfmov\t\1, \2/m, #2\.0(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+\.d), (p[0-7])/z, \1\n\tfmov\t\1, \2/m, #1\.25(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+\.d), (p[0-7])/z, \1\n\tfmov\t\1, \2/m, #-4\.0(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tmovprfx\t(z[0-9]+\.d), (p[0-7])/z, \1\n\tfmov\t\1, \2/m, #-2\.5(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.d, p[0-7], z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vcond_18_run.c b/gcc/testsuite/gcc.target/aarch64/sve/vcond_18_run.c
new file mode 100644
index 0000000..279b0a3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vcond_18_run.c
@@ -0,0 +1,30 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "vcond_18.c"
+
+#define N 97
+
+#define TEST_LOOP(TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ pred[i] = i % 5 <= i % 6; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (x, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ if (x[i] != (TYPE) (pred[i] > 0 ? CONST : 0)) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int __attribute__ ((optimize (1)))
+main (int argc, char **argv)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vcond_19.c b/gcc/testsuite/gcc.target/aarch64/sve/vcond_19.c
new file mode 100644
index 0000000..2347b7f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vcond_19.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#define DEF_LOOP(TYPE, NAME, CONST) \
+ void \
+ test_##TYPE##_##NAME (TYPE *restrict x, \
+ TYPE *restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] > 0 ? CONST : pred[i]; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, 2, 2.0) \
+ T (TYPE, 1p25, 1.25) \
+ T (TYPE, 32p25, 32.25) \
+ T (TYPE, m4, -4.0) \
+ T (TYPE, m2p5, -2.5) \
+ T (TYPE, m64p5, -64.5)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, _Float16) \
+ TEST_TYPE (T, float) \
+ TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, p[0-7]/m, #16384\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, p[0-7]/m, #15616\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, p[0-7]/m, #-15360\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, p[0-7]/m, #-16128\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */
+
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.s), p[0-7]/m, #2\.0(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.s), p[0-7]/m, #1\.25(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.s), p[0-7]/m, #-4\.0(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.s), p[0-7]/m, #-2\.5(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.s, p[0-7], z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */
+
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.d), p[0-7]/m, #2\.0(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.d), p[0-7]/m, #1\.25(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.d), p[0-7]/m, #-4\.0(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.d), p[0-7]/m, #-2\.5(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.d, p[0-7], z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
+
+/* { dg-final { scan-assembler-not {\tmovprfx\t} } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vcond_19_run.c b/gcc/testsuite/gcc.target/aarch64/sve/vcond_19_run.c
new file mode 100644
index 0000000..d93d8aa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vcond_19_run.c
@@ -0,0 +1,30 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "vcond_19.c"
+
+#define N 97
+
+#define TEST_LOOP(TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ pred[i] = i % 5 <= i % 6 ? i : 0; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (x, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ if (x[i] != (TYPE) (pred[i] > 0 ? CONST : pred[i])) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int __attribute__ ((optimize (1)))
+main (int argc, char **argv)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vcond_20.c b/gcc/testsuite/gcc.target/aarch64/sve/vcond_20.c
new file mode 100644
index 0000000..bf2af1c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vcond_20.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#define DEF_LOOP(TYPE, NAME, CONST) \
+ void \
+ test_##TYPE##_##NAME (TYPE *restrict x, \
+ TYPE *restrict pred, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ x[i] = pred[i] > 0 ? CONST : 12.0; \
+ }
+
+#define TEST_TYPE(T, TYPE) \
+ T (TYPE, 2, 2.0) \
+ T (TYPE, 1p25, 1.25) \
+ T (TYPE, 32p25, 32.25) \
+ T (TYPE, m4, -4.0) \
+ T (TYPE, m2p5, -2.5) \
+ T (TYPE, m64p5, -64.5)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, _Float16) \
+ TEST_TYPE (T, float) \
+ TEST_TYPE (T, double)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, p[0-7]/m, #16384\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, p[0-7]/m, #15616\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, p[0-7]/m, #-15360\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tmov\tz[0-9]+\.h, p[0-7]/m, #-16128\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.h, p[0-7], z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */
+
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.s), p[0-7]/m, #2\.0(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.s), p[0-7]/m, #1\.25(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.s), p[0-7]/m, #-4\.0(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.s), p[0-7]/m, #-2\.5(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.s, p[0-7], z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */
+
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.d), p[0-7]/m, #2\.0(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.d), p[0-7]/m, #1\.25(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.d), p[0-7]/m, #-4\.0(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler {\tfmov\t(z[0-9]+\.d), p[0-7]/m, #-2\.5(?:e[+]0)?\n} } } */
+/* { dg-final { scan-assembler-times {\tsel\tz[0-9]+\.d, p[0-7], z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tmovprfx\tz[0-9]+, z[0-9]+\n} 12 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vcond_20_run.c b/gcc/testsuite/gcc.target/aarch64/sve/vcond_20_run.c
new file mode 100644
index 0000000..33c81de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vcond_20_run.c
@@ -0,0 +1,30 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "vcond_20.c"
+
+#define N 97
+
+#define TEST_LOOP(TYPE, NAME, CONST) \
+ { \
+ TYPE x[N], pred[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ pred[i] = i % 5 <= i % 6; \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (x, pred, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ if (x[i] != (TYPE) (pred[i] > 0 ? CONST : 12.0)) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int __attribute__ ((optimize (1)))
+main (int argc, char **argv)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vcond_21.c b/gcc/testsuite/gcc.target/aarch64/sve/vcond_21.c
new file mode 100644
index 0000000..d5df2e1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vcond_21.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#define DEF_LOOP(TYPE, ABS, NAME, OP) \
+ void \
+ test_##TYPE##_##NAME (TYPE *restrict r, \
+ TYPE *restrict a, \
+ TYPE *restrict b, int n) \
+ { \
+ for (int i = 0; i < n; ++i) \
+ r[i] = ABS (a[i]) OP ABS (b[i]) ? 1.0 : 0.0; \
+ }
+
+#define TEST_TYPE(T, TYPE, ABS) \
+ T (TYPE, ABS, lt, <) \
+ T (TYPE, ABS, le, <=) \
+ T (TYPE, ABS, ge, >=) \
+ T (TYPE, ABS, gt, >)
+
+#define TEST_ALL(T) \
+ TEST_TYPE (T, _Float16, __builtin_fabsf16) \
+ TEST_TYPE (T, float, __builtin_fabsf) \
+ TEST_TYPE (T, double, __builtin_fabs)
+
+TEST_ALL (DEF_LOOP)
+
+/* { dg-final { scan-assembler-times {\tfac[lg]t\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tfac[lg]e\tp[0-9]+\.h, p[0-7]/z, z[0-9]+\.h, z[0-9]+\.h\n} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tfac[lg]t\tp[0-9]+\.s, p[0-7]/z, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tfac[lg]e\tp[0-9]+\.s, p[0-7]/z, z[0-9]+\.s, z[0-9]+\.s\n} 2 } } */
+
+/* { dg-final { scan-assembler-times {\tfac[lg]t\tp[0-9]+\.d, p[0-7]/z, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
+/* { dg-final { scan-assembler-times {\tfac[lg]e\tp[0-9]+\.d, p[0-7]/z, z[0-9]+\.d, z[0-9]+\.d\n} 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/vcond_21_run.c b/gcc/testsuite/gcc.target/aarch64/sve/vcond_21_run.c
new file mode 100644
index 0000000..15c5513
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/vcond_21_run.c
@@ -0,0 +1,31 @@
+/* { dg-do run { target aarch64_sve_hw } } */
+/* { dg-options "-O2 -ftree-vectorize" } */
+
+#include "vcond_21.c"
+
+#define N 97
+
+#define TEST_LOOP(TYPE, ABS, NAME, OP) \
+ { \
+ TYPE r[N], a[N], b[N]; \
+ for (int i = 0; i < N; ++i) \
+ { \
+ a[i] = i % 5 * (i & 1 ? -1 : 1); \
+ b[i] = i % 9 * (i & 2 ? -1 : 1); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ test_##TYPE##_##NAME (r, a, b, N); \
+ for (int i = 0; i < N; ++i) \
+ { \
+ if (r[i] != (ABS (a[i]) OP ABS (b[i]) ? 1.0 : 0.0)) \
+ __builtin_abort (); \
+ asm volatile ("" ::: "memory"); \
+ } \
+ }
+
+int __attribute__ ((optimize (1)))
+main (int argc, char **argv)
+{
+ TEST_ALL (TEST_LOOP)
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/while_10.c b/gcc/testsuite/gcc.target/aarch64/sve/while_10.c
new file mode 100644
index 0000000..eaed326
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/while_10.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -msve-vector-bits=512" } */
+
+#include <stdint.h>
+
+#define ADD_LOOP(TYPE, COUNT) \
+ TYPE __attribute__ ((noinline, noclone)) \
+ vec_while_##TYPE (TYPE *restrict a) \
+ { \
+ for (int i = 0; i < COUNT; ++i) \
+ a[i] += 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t, 63) \
+ T (int16_t, 30) \
+ T (int32_t, 15) \
+ T (int64_t, 6)
+
+TEST_ALL (ADD_LOOP)
+
+/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.b, mul3\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.h, mul3\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.s, mul3\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.d, vl6\n} 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/while_6.c b/gcc/testsuite/gcc.target/aarch64/sve/while_6.c
new file mode 100644
index 0000000..b4cc596
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/while_6.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -msve-vector-bits=scalable" } */
+
+#include <stdint.h>
+
+#define ADD_LOOP(TYPE) \
+ TYPE __attribute__ ((noinline, noclone)) \
+ vec_while_##TYPE (TYPE *restrict a) \
+ { \
+ for (int i = 0; i < 7; ++i) \
+ a[i] += 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (int16_t) \
+ T (int32_t) \
+ T (int64_t)
+
+TEST_ALL (ADD_LOOP)
+
+/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.b, vl7\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.h, vl7\n} 1 } } */
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.s,} 2 } } */
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.d,} 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/while_7.c b/gcc/testsuite/gcc.target/aarch64/sve/while_7.c
new file mode 100644
index 0000000..d5ffb66
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/while_7.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -msve-vector-bits=scalable" } */
+
+#include <stdint.h>
+
+#define ADD_LOOP(TYPE) \
+ TYPE __attribute__ ((noinline, noclone)) \
+ vec_while_##TYPE (TYPE *restrict a) \
+ { \
+ for (int i = 0; i < 8; ++i) \
+ a[i] += 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (int16_t) \
+ T (int32_t) \
+ T (int64_t)
+
+TEST_ALL (ADD_LOOP)
+
+/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.b, vl8\n} 1 } } */
+/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.h, vl8\n} 1 } } */
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.s,} 2 } } */
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.d,} 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/while_8.c b/gcc/testsuite/gcc.target/aarch64/sve/while_8.c
new file mode 100644
index 0000000..1c11aa8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/while_8.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -msve-vector-bits=scalable" } */
+
+#include <stdint.h>
+
+#define ADD_LOOP(TYPE) \
+ TYPE __attribute__ ((noinline, noclone)) \
+ vec_while_##TYPE (TYPE *restrict a) \
+ { \
+ for (int i = 0; i < 9; ++i) \
+ a[i] += 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (int16_t) \
+ T (int32_t) \
+ T (int64_t)
+
+TEST_ALL (ADD_LOOP)
+
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.b,} 1 } } */
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.h,} 2 } } */
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.s,} 2 } } */
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.d,} 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/sve/while_9.c b/gcc/testsuite/gcc.target/aarch64/sve/while_9.c
new file mode 100644
index 0000000..9a8e5fe
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/sve/while_9.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -msve-vector-bits=scalable" } */
+
+#include <stdint.h>
+
+#define ADD_LOOP(TYPE) \
+ TYPE __attribute__ ((noinline, noclone)) \
+ vec_while_##TYPE (TYPE *restrict a) \
+ { \
+ for (int i = 0; i < 16; ++i) \
+ a[i] += 1; \
+ }
+
+#define TEST_ALL(T) \
+ T (int8_t) \
+ T (int16_t) \
+ T (int32_t) \
+ T (int64_t)
+
+TEST_ALL (ADD_LOOP)
+
+/* { dg-final { scan-assembler-times {\tptrue\tp[0-7]\.b, vl16\n} 1 } } */
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.h,} 2 } } */
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.s,} 2 } } */
+/* { dg-final { scan-assembler-times {\twhilelo\tp[0-7]\.d,} 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/vect-clz.c b/gcc/testsuite/gcc.target/aarch64/vect-clz.c
index 044fa9e..cd181c3 100644
--- a/gcc/testsuite/gcc.target/aarch64/vect-clz.c
+++ b/gcc/testsuite/gcc.target/aarch64/vect-clz.c
@@ -1,6 +1,8 @@
/* { dg-do run } */
/* { dg-options "-O3 -save-temps -fno-inline -fno-vect-cost-model" } */
+#pragma GCC target "+nosve"
+
extern void abort ();
void
diff --git a/gcc/testsuite/gcc.target/arc/arc.exp b/gcc/testsuite/gcc.target/arc/arc.exp
index a1b86b5..55e1213 100644
--- a/gcc/testsuite/gcc.target/arc/arc.exp
+++ b/gcc/testsuite/gcc.target/arc/arc.exp
@@ -94,6 +94,24 @@ proc check_effective_target_barrelshifter { } {
}]
}
+#return 1 if we use ARCv2 Accumulator registers
+proc check_effective_target_accregs { } {
+ return [check_no_compiler_messages accregs assembly {
+ #if !defined(__ARC_MPY_DMPY__) \
+ && !defined(__ARC_MPY_MACD__) && !defined(__ARC_MPY_QMACW__)
+ #error No accumulator available for this config
+ #endif
+ }]
+}
+
+proc check_effective_target_dpfp { } {
+ return [check_no_compiler_messages dpfp assembly {
+ #if !defined(__ARC_FPX_DP__) && !defined(__ARC_FPU_ASSIST__)
+ #error No FPX available for this config
+ #endif
+ }]
+}
+
# If a testcase doesn't have special options, use these.
global DEFAULT_CFLAGS
if ![info exists DEFAULT_CFLAGS] then {
diff --git a/gcc/testsuite/gcc.target/arc/builtin_special.c b/gcc/testsuite/gcc.target/arc/builtin_special.c
index 7590b17..829528c 100644
--- a/gcc/testsuite/gcc.target/arc/builtin_special.c
+++ b/gcc/testsuite/gcc.target/arc/builtin_special.c
@@ -21,7 +21,9 @@
NORET (nop)
+#if !defined (__ARC600__) && !defined (__ARC601__)
NORET (rtie)
+#endif
#ifdef __A7__
NORET (sync)
diff --git a/gcc/testsuite/gcc.target/arc/interrupt-1.c b/gcc/testsuite/gcc.target/arc/interrupt-1.c
index 8a2002b..5a5139a 100644
--- a/gcc/testsuite/gcc.target/arc/interrupt-1.c
+++ b/gcc/testsuite/gcc.target/arc/interrupt-1.c
@@ -6,5 +6,5 @@ void __attribute__ ((interrupt("ilink1")))
handler1 (void)
{
}
-/* { dg-final { scan-assembler-times "j.*\[ilink1\]" 1 { target { arc700 || arc6xx } } } } */
-/* { dg-final { scan-assembler-times "rtie" 1 { target { arcem || archs } } } } */
+/* { dg-final { scan-assembler-times "j.*\[ilink1\]" 1 { target { arc6xx } } } } */
+/* { dg-final { scan-assembler-times "rtie" 1 { target { ! { arc6xx } } } } } */
diff --git a/gcc/testsuite/gcc.target/arc/interrupt-10.c b/gcc/testsuite/gcc.target/arc/interrupt-10.c
new file mode 100644
index 0000000..605c19f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/interrupt-10.c
@@ -0,0 +1,36 @@
+/* { dg-options "-O2" } */
+extern void will_trig_exception(void);
+
+#if defined (__ARCHS__) || defined (__ARCEM__)
+__attribute__ ((interrupt("ilink")))
+#else
+__attribute__ ((interrupt("ilink1")))
+#endif
+void isr_0 (void)
+{
+ will_trig_exception();
+}
+
+/* { dg-final { scan-assembler-times "j.*\[ilink1\]" 1 { target { arc6xx } } } } */
+/* { dg-final { scan-assembler-times "rtie" 1 { target { ! { arc6xx } } } } } */
+/* { dg-final { scan-assembler-times "blink" 2 } } */
+/* { dg-final { scan-assembler-times "fp" 2 { target { ! { archs } } } } } */
+/* { dg-final { scan-assembler-times "r30" 2 { target { archs || arcem } } } } */
+/* { dg-final { scan-assembler-times "r24" 2 } } */
+/* { dg-final { scan-assembler-times "r22" 2 } } */
+/* { dg-final { scan-assembler-times "r20" 2 } } */
+/* { dg-final { scan-assembler-times "r18" 2 } } */
+/* { dg-final { scan-assembler-times "r16" 2 } } */
+/* { dg-final { scan-assembler-times "r14" 2 } } */
+/* { dg-final { scan-assembler-times "r12" 2 } } */
+/* { dg-final { scan-assembler-times "r10" 2 } } */
+/* { dg-final { scan-assembler-times "r8" 2 } } */
+/* { dg-final { scan-assembler-times "r6" 2 } } */
+/* { dg-final { scan-assembler-times "r4" 2 } } */
+/* { dg-final { scan-assembler-times "r2\[,\n\]" 2 } } */
+/* { dg-final { scan-assembler-times "lp_count" 2 } } */
+/* { dg-final { scan-assembler-times "sr\\s+r\[0-9\]," 2 { target { ! { dpfp } } } } } */
+/* { dg-final { scan-assembler-times "lr\\s+r\[0-9\]" 2 { target { ! { dpfp } } } } } */
+/* { dg-final { scan-assembler-times "sr\\s+r\[0-9\]," 6 { target { dpfp } } } } */
+/* { dg-final { scan-assembler-times "lr\\s+r\[0-9\]" 6 { target { dpfp } } } } */
+/* { dg-final { scan-assembler-times "r58" 2 { target { accregs } } } } */
diff --git a/gcc/testsuite/gcc.target/arc/interrupt-11.c b/gcc/testsuite/gcc.target/arc/interrupt-11.c
new file mode 100644
index 0000000..ca340ee
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/interrupt-11.c
@@ -0,0 +1,16 @@
+extern int a;
+
+#if defined (__ARCHS__) || defined (__ARCEM__)
+__attribute__ ((interrupt("ilink")))
+#else
+__attribute__ ((interrupt("ilink2")))
+#endif
+void isr_1 (void)
+{
+ a++;
+}
+
+/* { dg-final { scan-assembler-times "j.*\[ilink2\]" 1 { target { arc6xx } } } } */
+/* { dg-final { scan-assembler-times "rtie" 1 { target { ! { arc6xx } } } } } */
+/* { dg-final { scan-assembler-times "push_s\\s+r\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-times "pop_s\\s+r\[0-9\]" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arc/interrupt-12.c b/gcc/testsuite/gcc.target/arc/interrupt-12.c
new file mode 100644
index 0000000..da3e26c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/interrupt-12.c
@@ -0,0 +1,16 @@
+/* { dg-options "-O0 -g" } */
+
+typedef void (*isr_routine)(void);
+isr_routine will_trig_exception;
+
+ #if defined (__ARCHS__) || defined (__ARCEM__)
+void __attribute__ ((interrupt("ilink")))
+#else
+void __attribute__ ((interrupt("ilink1")))
+#endif
+isr_template(void)
+{
+ will_trig_exception();
+}
+
+/* { dg-final { scan-assembler-times "\\\.cfi_offset 0" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arc/interrupt-6.c b/gcc/testsuite/gcc.target/arc/interrupt-6.c
index d82bd67..9cb0565 100644
--- a/gcc/testsuite/gcc.target/arc/interrupt-6.c
+++ b/gcc/testsuite/gcc.target/arc/interrupt-6.c
@@ -1,8 +1,7 @@
/* { dg-do compile } */
/* { dg-skip-if "Not available for ARCv1" { arc700 || arc6xx } } */
/* { dg-options "-O2 -mirq-ctrl-saved=r0-ilink" } */
-
-#include <alloca.h>
+/* { dg-require-effective-target alloca } */
/* Check if ilink is recognized. Check how FP and BLINK are saved.
BLINK is saved last on the stack because the IRQ autosave will do
@@ -14,7 +13,7 @@ extern int bar (void *);
void __attribute__ ((interrupt("ilink")))
foo(void)
{
- int *p = alloca (10);
+ int *p = __builtin_alloca (10);
bar (p);
}
/* { dg-final { scan-assembler-not ".*fp,\\\[sp" } } */
diff --git a/gcc/testsuite/gcc.target/arm/cmse/cmse-17.c b/gcc/testsuite/gcc.target/arm/cmse/cmse-17.c
new file mode 100644
index 0000000..a2cce09
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/cmse/cmse-17.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mcmse"} */
+
+#include <arm_cmse.h>
+
+void foo()
+{
+ int *data;
+ cmse_check_address_range((int*)data, 0, 0); /* { dg-warning "ignoring return value" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/asm-4.c b/gcc/testsuite/gcc.target/i386/asm-4.c
index b868010..69dd1d3 100644
--- a/gcc/testsuite/gcc.target/i386/asm-4.c
+++ b/gcc/testsuite/gcc.target/i386/asm-4.c
@@ -29,7 +29,7 @@ baz (void)
{
/* Darwin loads 64-bit regions above the 4GB boundary so
we need to use this instead. */
-#if defined (__LP64__) && defined (__MACH__)
+#if defined (__LP64__)
__asm ("leaq foo(%%rip), %0" : "=r" (fn));
#else
__asm ("movl $foo, %k0" : "=r" (fn));
diff --git a/gcc/testsuite/gcc.target/i386/avx-ceil-sfix-2-vec.c b/gcc/testsuite/gcc.target/i386/avx-ceil-sfix-2-vec.c
index 45b7af7..8d3b0a6 100644
--- a/gcc/testsuite/gcc.target/i386/avx-ceil-sfix-2-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-ceil-sfix-2-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "avx-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern double ceil (double);
diff --git a/gcc/testsuite/gcc.target/i386/avx-ceil-sfix-vec.c b/gcc/testsuite/gcc.target/i386/avx-ceil-sfix-vec.c
index ac0911f..7466041 100644
--- a/gcc/testsuite/gcc.target/i386/avx-ceil-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-ceil-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-ceil-vec.c b/gcc/testsuite/gcc.target/i386/avx-ceil-vec.c
index 0e76ab8..3edc17e 100644
--- a/gcc/testsuite/gcc.target/i386/avx-ceil-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-ceil-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-ceilf-sfix-vec.c b/gcc/testsuite/gcc.target/i386/avx-ceilf-sfix-vec.c
index 789b78e..07e2b80 100644
--- a/gcc/testsuite/gcc.target/i386/avx-ceilf-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-ceilf-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-ceilf-vec.c b/gcc/testsuite/gcc.target/i386/avx-ceilf-vec.c
index c324a9b..641e34f 100644
--- a/gcc/testsuite/gcc.target/i386/avx-ceilf-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-ceilf-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-cvt-2-vec.c b/gcc/testsuite/gcc.target/i386/avx-cvt-2-vec.c
index 0081dcf..ad381c0 100644
--- a/gcc/testsuite/gcc.target/i386/avx-cvt-2-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-cvt-2-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "avx-check.h"
@@ -13,7 +12,7 @@
#include CHECK_H
-#include <math.h>
+#include "math_m_pi.h"
#define NUM 4
diff --git a/gcc/testsuite/gcc.target/i386/avx-cvt-vec.c b/gcc/testsuite/gcc.target/i386/avx-cvt-vec.c
index 4dcfa39..72e8b1d 100644
--- a/gcc/testsuite/gcc.target/i386/avx-cvt-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-cvt-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-floor-sfix-2-vec.c b/gcc/testsuite/gcc.target/i386/avx-floor-sfix-2-vec.c
index 0a28c76..928a4a2 100644
--- a/gcc/testsuite/gcc.target/i386/avx-floor-sfix-2-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-floor-sfix-2-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "avx-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern double floor (double);
diff --git a/gcc/testsuite/gcc.target/i386/avx-floor-sfix-vec.c b/gcc/testsuite/gcc.target/i386/avx-floor-sfix-vec.c
index efa557c..7ec690b 100644
--- a/gcc/testsuite/gcc.target/i386/avx-floor-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-floor-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-floor-vec.c b/gcc/testsuite/gcc.target/i386/avx-floor-vec.c
index 1d7fe50..9fcab1d 100644
--- a/gcc/testsuite/gcc.target/i386/avx-floor-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-floor-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-floorf-sfix-vec.c b/gcc/testsuite/gcc.target/i386/avx-floorf-sfix-vec.c
index 0c1587a..02c8177 100644
--- a/gcc/testsuite/gcc.target/i386/avx-floorf-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-floorf-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-floorf-vec.c b/gcc/testsuite/gcc.target/i386/avx-floorf-vec.c
index 73da85b..b2e707e 100644
--- a/gcc/testsuite/gcc.target/i386/avx-floorf-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-floorf-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-loadu2-m128-1.c b/gcc/testsuite/gcc.target/i386/avx-loadu2-m128-1.c
new file mode 100644
index 0000000..d5b5ad2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-loadu2-m128-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-final { scan-assembler "\tvmovups\t" } } */
+/* { dg-final { scan-assembler "\tvinsertf128\t" } } */
+
+#include <immintrin.h>
+
+__m256
+foo (float const *hi, float const *lo)
+{
+ return _mm256_loadu2_m128 (hi, lo);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-loadu2-m128-2.c b/gcc/testsuite/gcc.target/i386/avx-loadu2-m128-2.c
new file mode 100644
index 0000000..b962c2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-loadu2-m128-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-require-effective-target avx } */
+
+#include "avx-check.h"
+
+static void
+avx_test (void)
+{
+ union256 u;
+ float e[8] = { 1.5f, -9.5f, 13.25f, -24.75f, -18.75f, 12.0f, 0.0f, 9.0f };
+ float f[8] = { -24.75f, -18.75f, 12.0f, 0.0f, -9.5f, 13.25f, -24.75f, -18.75f };
+
+ u.x = _mm256_loadu2_m128 (e + 1, e + 3);
+ if (check_union256 (u, f))
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-loadu2-m128d-1.c b/gcc/testsuite/gcc.target/i386/avx-loadu2-m128d-1.c
new file mode 100644
index 0000000..3cdd497
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-loadu2-m128d-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-final { scan-assembler "\tvmovupd\t" } } */
+/* { dg-final { scan-assembler "\tvinsertf128\t" } } */
+
+#include <immintrin.h>
+
+__m256d
+foo (double const *hi, double const *lo)
+{
+ return _mm256_loadu2_m128d (hi, lo);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-loadu2-m128d-2.c b/gcc/testsuite/gcc.target/i386/avx-loadu2-m128d-2.c
new file mode 100644
index 0000000..d342fdc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-loadu2-m128d-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-require-effective-target avx } */
+
+#include "avx-check.h"
+
+static void
+avx_test (void)
+{
+ union256d u;
+ double e[8] = { 1.5, -9.5, 13.25, -24.75, -18.75, 12.0, 0.0, 9.0 };
+ double f[4] = { 12.0, 0.0, -9.5, 13.25 };
+
+ u.x = _mm256_loadu2_m128d (e + 1, e + 5);
+ if (check_union256d (u, f))
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-loadu2-m128i-1.c b/gcc/testsuite/gcc.target/i386/avx-loadu2-m128i-1.c
new file mode 100644
index 0000000..32d5444
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-loadu2-m128i-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-final { scan-assembler "\tvmovdqu\t" } } */
+/* { dg-final { scan-assembler "\tvinsert\[fi]128\t" } } */
+
+#include <immintrin.h>
+
+__m256i
+foo (__m128i_u const *hi, __m128i_u const *lo)
+{
+ return _mm256_loadu2_m128i (hi, lo);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-loadu2-m128i-2.c b/gcc/testsuite/gcc.target/i386/avx-loadu2-m128i-2.c
new file mode 100644
index 0000000..e090b98
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-loadu2-m128i-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-require-effective-target avx } */
+
+#include "avx-check.h"
+
+static void
+avx_test (void)
+{
+ union256i_d u;
+ int e[8] = { 1, -9, 13, -24, -18, 12, 0, 9 };
+ int f[8] = { -24, -18, 12, 0, -9, 13, -24, -18 };
+
+ u.x = _mm256_loadu2_m128i ((__m128i_u *) (e + 1), (__m128i_u *) (e + 3));
+ if (check_union256i_d (u, f))
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-rint-sfix-2-vec.c b/gcc/testsuite/gcc.target/i386/avx-rint-sfix-2-vec.c
index e6c47b8..dce850d 100644
--- a/gcc/testsuite/gcc.target/i386/avx-rint-sfix-2-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-rint-sfix-2-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "avx-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern double rint (double);
diff --git a/gcc/testsuite/gcc.target/i386/avx-rint-sfix-vec.c b/gcc/testsuite/gcc.target/i386/avx-rint-sfix-vec.c
index 824f2eb..4a7f67d 100644
--- a/gcc/testsuite/gcc.target/i386/avx-rint-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-rint-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-rint-vec.c b/gcc/testsuite/gcc.target/i386/avx-rint-vec.c
index c1d420c6..3af517a 100644
--- a/gcc/testsuite/gcc.target/i386/avx-rint-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-rint-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-rintf-sfix-vec.c b/gcc/testsuite/gcc.target/i386/avx-rintf-sfix-vec.c
index e5ddf790..3dfbb60 100644
--- a/gcc/testsuite/gcc.target/i386/avx-rintf-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-rintf-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-rintf-vec.c b/gcc/testsuite/gcc.target/i386/avx-rintf-vec.c
index caf365d..8b5f5e0 100644
--- a/gcc/testsuite/gcc.target/i386/avx-rintf-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-rintf-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-round-sfix-2-vec.c b/gcc/testsuite/gcc.target/i386/avx-round-sfix-2-vec.c
index dc0a7db..fe6970b 100644
--- a/gcc/testsuite/gcc.target/i386/avx-round-sfix-2-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-round-sfix-2-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "avx-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern double round (double);
diff --git a/gcc/testsuite/gcc.target/i386/avx-round-sfix-vec.c b/gcc/testsuite/gcc.target/i386/avx-round-sfix-vec.c
index 5adfffa..5670636 100644
--- a/gcc/testsuite/gcc.target/i386/avx-round-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-round-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-round-vec.c b/gcc/testsuite/gcc.target/i386/avx-round-vec.c
index c43c057..26a6878 100644
--- a/gcc/testsuite/gcc.target/i386/avx-round-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-round-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-roundf-sfix-vec.c b/gcc/testsuite/gcc.target/i386/avx-roundf-sfix-vec.c
index 1fd4591..827e476 100644
--- a/gcc/testsuite/gcc.target/i386/avx-roundf-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-roundf-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-roundf-vec.c b/gcc/testsuite/gcc.target/i386/avx-roundf-vec.c
index 978013e..3dae330 100644
--- a/gcc/testsuite/gcc.target/i386/avx-roundf-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-roundf-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-storeu2-m128-1.c b/gcc/testsuite/gcc.target/i386/avx-storeu2-m128-1.c
new file mode 100644
index 0000000..cca79c5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-storeu2-m128-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-final { scan-assembler "\tvmovups\t" } } */
+/* { dg-final { scan-assembler "\tvextractf128\t" } } */
+
+#include <immintrin.h>
+
+void
+foo (float *hi, float *lo, __m256 a)
+{
+ _mm256_storeu2_m128 (hi, lo, a);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-storeu2-m128-2.c b/gcc/testsuite/gcc.target/i386/avx-storeu2-m128-2.c
new file mode 100644
index 0000000..81c823a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-storeu2-m128-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-require-effective-target avx } */
+
+#include "avx-check.h"
+
+static void
+avx_test (void)
+{
+ float e[12] = { -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f };
+ float f[12] = { -1.0f, -18.75f, 12.0f, 0.0f, 9.0f, -1.0f, 1.5f, -9.5f, 13.25f, -24.75f, -1.0f, -1.0f };
+ int i;
+ __m256 x = _mm256_set_ps (1.5f, -9.5f, 13.25f, -24.75f, -18.75f, 12.0f, 0.0f, 9.0f);
+ _mm256_storeu2_m128 (e + 1, e + 6, x);
+ for (i = 0; i < 12; i++)
+ if (e[i] != f[i])
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-storeu2-m128d-1.c b/gcc/testsuite/gcc.target/i386/avx-storeu2-m128d-1.c
new file mode 100644
index 0000000..01cb223
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-storeu2-m128d-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-final { scan-assembler "\tvmovup\[sd]\t" } } */
+/* { dg-final { scan-assembler "\tvextractf128\t" } } */
+
+#include <immintrin.h>
+
+void
+foo (double *hi, double *lo, __m256d a)
+{
+ _mm256_storeu2_m128d (hi, lo, a);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-storeu2-m128d-2.c b/gcc/testsuite/gcc.target/i386/avx-storeu2-m128d-2.c
new file mode 100644
index 0000000..37c23c2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-storeu2-m128d-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-require-effective-target avx } */
+
+#include "avx-check.h"
+
+static void
+avx_test (void)
+{
+ double e[8] = { -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0 };
+ double f[8] = { -1.0, 13.25, -24.75, -1.0, 1.5, -9.5, -1.0, -1.0 };
+ int i;
+ __m256d x = _mm256_set_pd (1.5, -9.5, 13.25, -24.75);
+ _mm256_storeu2_m128d (e + 1, e + 4, x);
+ for (i = 0; i < 8; i++)
+ if (e[i] != f[i])
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-storeu2-m128i-1.c b/gcc/testsuite/gcc.target/i386/avx-storeu2-m128i-1.c
new file mode 100644
index 0000000..bf2e72a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-storeu2-m128i-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-final { scan-assembler "\tvmov(dqu|ups)\t" } } */
+/* { dg-final { scan-assembler "\tvextract\[if]128\t" } } */
+
+#include <immintrin.h>
+
+void
+foo (__m128i_u *hi, __m128i_u *lo, __m256i a)
+{
+ _mm256_storeu2_m128i (hi, lo, a);
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-storeu2-m128i-2.c b/gcc/testsuite/gcc.target/i386/avx-storeu2-m128i-2.c
new file mode 100644
index 0000000..dd1825f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-storeu2-m128i-2.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-require-effective-target avx } */
+
+#include "avx-check.h"
+
+static void
+avx_test (void)
+{
+ int e[12] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
+ int f[12] = { -1, -18, 12, 0, 9, -1, 1, -9, 13, -24, -1, -1 };
+ int i;
+ __m256i x = _mm256_set_epi32 (1, -9, 13, -24, -18, 12, 0, 9);
+ _mm256_storeu2_m128i ((__m128i_u *) (e + 1), (__m128i_u *) (e + 6), x);
+ for (i = 0; i < 12; i++)
+ if (e[i] != f[i])
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-trunc-vec.c b/gcc/testsuite/gcc.target/i386/avx-trunc-vec.c
index a1ee6d4..8e193af 100644
--- a/gcc/testsuite/gcc.target/i386/avx-trunc-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-trunc-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-truncf-vec.c b/gcc/testsuite/gcc.target/i386/avx-truncf-vec.c
index a1ee6d4..8e193af 100644
--- a/gcc/testsuite/gcc.target/i386/avx-truncf-vec.c
+++ b/gcc/testsuite/gcc.target/i386/avx-truncf-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx" } */
/* { dg-require-effective-target avx } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define CHECK_H "avx-check.h"
#define TEST avx_test
diff --git a/gcc/testsuite/gcc.target/i386/avx-typecast-1.c b/gcc/testsuite/gcc.target/i386/avx-typecast-1.c
new file mode 100644
index 0000000..3b59326
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-typecast-1.c
@@ -0,0 +1,83 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-require-effective-target avx } */
+
+#include "avx-check.h"
+
+extern int memcmp (const void *, const void *, __SIZE_TYPE__);
+
+void
+avx_test (void)
+{
+ union256i_d a, ad;
+ union256 b, bd;
+ union256d c, cd;
+ union128i_d d, dd;
+ union128 e, ed;
+ union128d f, fd;
+ int i;
+
+ for (i = 0; i < 8; i++)
+ {
+ a.a[i] = 7146908634 + i;
+ b.a[i] = 45.12f + i;
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ c.a[i] = 41234512513451345.0905 + i;
+ d.a[i] = 109534 + i;
+ e.a[i] = 85034.095f + i;
+ }
+
+ for (i = 0; i < 2; i++)
+ f.a[i] = 41234512451345.0905 + i;
+
+ bd.x = _mm256_castpd_ps (c.x);
+ if (memcmp (bd.a, c.a, 32))
+ abort ();
+
+ ad.x = _mm256_castpd_si256 (c.x);
+ if (memcmp (ad.a, c.a, 32))
+ abort ();
+
+ cd.x = _mm256_castps_pd (b.x);
+ if (memcmp (cd.a, b.a, 32))
+ abort ();
+
+ ad.x = _mm256_castps_si256 (b.x);
+ if (memcmp (ad.a, b.a, 32))
+ abort ();
+
+ bd.x = _mm256_castsi256_ps (a.x);
+ if (memcmp (bd.a, a.a, 32))
+ abort ();
+
+ cd.x = _mm256_castsi256_pd (a.x);
+ if (memcmp (cd.a, a.a, 32))
+ abort ();
+
+ fd.x = _mm256_castpd256_pd128 (c.x);
+ if (memcmp (fd.a, c.a, 16))
+ abort ();
+
+ ed.x = _mm256_castps256_ps128 (b.x);
+ if (memcmp (ed.a, b.a, 16))
+ abort ();
+
+ dd.x = _mm256_castsi256_si128 (a.x);
+ if (memcmp (dd.a, a.a, 16))
+ abort ();
+
+ cd.x = _mm256_castpd128_pd256 (f.x);
+ if (memcmp (cd.a, f.a, 16))
+ abort ();
+
+ bd.x = _mm256_castps128_ps256 (e.x);
+ if (memcmp (bd.a, e.a, 16))
+ abort ();
+
+ ad.x = _mm256_castsi128_si256 (d.x);
+ if (memcmp (ad.a, d.a, 16))
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx-typecast-2.c b/gcc/testsuite/gcc.target/i386/avx-typecast-2.c
new file mode 100644
index 0000000..6799067
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx-typecast-2.c
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx" } */
+/* { dg-require-effective-target avx } */
+
+#include "avx-check.h"
+
+extern int memcmp (const void *, const void *, __SIZE_TYPE__);
+
+void
+avx_test (void)
+{
+ union256i_d ad, zero;
+ union256 bd;
+ union256d cd;
+ union128i_d d;
+ union128 e;
+ union128d f;
+ int i;
+
+ for (i = 0; i < 8; i++)
+ zero.a[i] = 0;
+
+ for (i = 0; i < 4; i++)
+ {
+ d.a[i] = 109534 + i;
+ e.a[i] = 85034.095f + i;
+ }
+
+ for (i = 0; i < 2; i++)
+ f.a[i] = 41234512451345.0905 + i;
+
+ cd.x = _mm256_zextpd128_pd256 (f.x);
+ if (memcmp (cd.a, f.a, 16)
+ || memcmp (&cd.a[2], &zero.a, 16))
+ abort ();
+
+ bd.x = _mm256_zextps128_ps256 (e.x);
+ if (memcmp (bd.a, e.a, 16)
+ || memcmp (&bd.a[4], &zero.a, 16))
+ abort ();
+
+ ad.x = _mm256_zextsi128_si256 (d.x);
+ if (memcmp (ad.a, d.a, 16)
+ || memcmp (&ad.a[4], &zero.a, 16))
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx2-pr91201.c b/gcc/testsuite/gcc.target/i386/avx2-pr91201.c
new file mode 100644
index 0000000..4cf0a3a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx2-pr91201.c
@@ -0,0 +1,6 @@
+/* PR tree-optimization/91201 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -mavx2 -mno-avx512f" } */
+/* { dg-final { scan-assembler "\tvpsadbw\t" } } */
+
+#include "sse2-pr91201.c"
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-pr91150.c b/gcc/testsuite/gcc.target/i386/avx512bw-pr91150.c
new file mode 100644
index 0000000..8c68622
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-pr91150.c
@@ -0,0 +1,37 @@
+/* PR target/91150 */
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx512bw" } */
+/* { dg-require-effective-target avx512bw } */
+
+#include "avx512bw-check.h"
+
+typedef unsigned char V __attribute__((vector_size (64)));
+
+__attribute__((noipa)) void
+foo (V *x, V *y, V *z)
+{
+ *x = __builtin_shuffle (*y, *z, (V) { 0, 1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127 });
+}
+
+static void
+avx512bw_test (void)
+{
+ union U { unsigned char a[64]; V v; } a, b, c;
+ int i;
+ for (i = 0; i < 64; i++)
+ {
+ b.a[i] = i + 1;
+ c.a[i] = i + 65;
+ }
+ foo (&a.v, &b.v, &c.v);
+ for (i = 0; i < 64; i++)
+ if (a.a[i] != (i < 16 ? i + 1 : i + 65))
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-pr91201.c b/gcc/testsuite/gcc.target/i386/avx512bw-pr91201.c
new file mode 100644
index 0000000..9829a5c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-pr91201.c
@@ -0,0 +1,6 @@
+/* PR tree-optimization/91201 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -mavx512bw -mprefer-vector-width=512" } */
+/* { dg-final { scan-assembler "\tvpsadbw\t" } } */
+
+#include "sse2-pr91201.c"
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-ceil-sfix-vec-1.c b/gcc/testsuite/gcc.target/i386/avx512f-ceil-sfix-vec-1.c
index d7d6916..ab05833 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-ceil-sfix-vec-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-ceil-sfix-vec-1.c
@@ -1,10 +1,9 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx512f" } */
/* { dg-require-effective-target avx512f } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#include "avx512f-check.h"
extern double ceil (double);
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-ceil-vec-1.c b/gcc/testsuite/gcc.target/i386/avx512f-ceil-vec-1.c
index fc48b15..3ab6455 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-ceil-vec-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-ceil-vec-1.c
@@ -1,10 +1,9 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx512f" } */
/* { dg-require-effective-target avx512f } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#include "avx512f-check.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-ceilf-sfix-vec-1.c b/gcc/testsuite/gcc.target/i386/avx512f-ceilf-sfix-vec-1.c
index c6d53d8..27a4bb9 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-ceilf-sfix-vec-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-ceilf-sfix-vec-1.c
@@ -1,10 +1,9 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx512f" } */
/* { dg-require-effective-target avx512f } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#include "avx512f-check.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-ceilf-vec-1.c b/gcc/testsuite/gcc.target/i386/avx512f-ceilf-vec-1.c
index 4788825..54222da 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-ceilf-vec-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-ceilf-vec-1.c
@@ -1,10 +1,9 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx512f" } */
/* { dg-require-effective-target avx512f } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#include "avx512f-check.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-floor-sfix-vec-1.c b/gcc/testsuite/gcc.target/i386/avx512f-floor-sfix-vec-1.c
index b46ea9f..9eff15f 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-floor-sfix-vec-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-floor-sfix-vec-1.c
@@ -1,10 +1,9 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx512f" } */
/* { dg-require-effective-target avx512f } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#include "avx512f-check.h"
extern double floor (double);
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-floor-vec-1.c b/gcc/testsuite/gcc.target/i386/avx512f-floor-vec-1.c
index b7cbed0..be97099 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-floor-vec-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-floor-vec-1.c
@@ -1,10 +1,9 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx512f" } */
/* { dg-require-effective-target avx512f } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#include "avx512f-check.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-floorf-sfix-vec-1.c b/gcc/testsuite/gcc.target/i386/avx512f-floorf-sfix-vec-1.c
index 6a25f43..7a84fcb 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-floorf-sfix-vec-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-floorf-sfix-vec-1.c
@@ -1,10 +1,9 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx512f" } */
/* { dg-require-effective-target avx512f } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#include "avx512f-check.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-floorf-vec-1.c b/gcc/testsuite/gcc.target/i386/avx512f-floorf-vec-1.c
index 69fc73d..fcc0b27 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-floorf-vec-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-floorf-vec-1.c
@@ -1,10 +1,9 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx512f" } */
/* { dg-require-effective-target avx512f } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#include "avx512f-check.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-rint-sfix-vec-1.c b/gcc/testsuite/gcc.target/i386/avx512f-rint-sfix-vec-1.c
index 8e1745a..d22385c 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-rint-sfix-vec-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-rint-sfix-vec-1.c
@@ -1,10 +1,9 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx512f" } */
/* { dg-require-effective-target avx512f } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#include "avx512f-check.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-rintf-sfix-vec-1.c b/gcc/testsuite/gcc.target/i386/avx512f-rintf-sfix-vec-1.c
index ac3e9a2..6a627ab 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-rintf-sfix-vec-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-rintf-sfix-vec-1.c
@@ -1,10 +1,9 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx512f" } */
/* { dg-require-effective-target avx512f } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#include "avx512f-check.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-round-sfix-vec-1.c b/gcc/testsuite/gcc.target/i386/avx512f-round-sfix-vec-1.c
index 61bea57..4c83e7b 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-round-sfix-vec-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-round-sfix-vec-1.c
@@ -1,10 +1,9 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx512f" } */
/* { dg-require-effective-target avx512f } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#include "avx512f-check.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-roundf-sfix-vec-1.c b/gcc/testsuite/gcc.target/i386/avx512f-roundf-sfix-vec-1.c
index c5ec9e7..1341a5b 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-roundf-sfix-vec-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-roundf-sfix-vec-1.c
@@ -1,10 +1,9 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx512f" } */
/* { dg-require-effective-target avx512f } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#include "avx512f-check.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-trunc-vec-1.c b/gcc/testsuite/gcc.target/i386/avx512f-trunc-vec-1.c
index dfb93d7..b8b5d07 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-trunc-vec-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-trunc-vec-1.c
@@ -1,10 +1,9 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx512f" } */
/* { dg-require-effective-target avx512f } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#include "avx512f-check.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-truncf-vec-1.c b/gcc/testsuite/gcc.target/i386/avx512f-truncf-vec-1.c
index db13e71..7dfd575 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-truncf-vec-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-truncf-vec-1.c
@@ -1,10 +1,9 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -mavx512f" } */
/* { dg-require-effective-target avx512f } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#include "avx512f-check.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-typecast-2.c b/gcc/testsuite/gcc.target/i386/avx512f-typecast-2.c
new file mode 100644
index 0000000..a0483429
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-typecast-2.c
@@ -0,0 +1,71 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx512f" } */
+/* { dg-require-effective-target avx512f } */
+
+#include "avx512f-check.h"
+
+extern int memcmp (const void *, const void *, __SIZE_TYPE__);
+
+void
+avx512f_test (void)
+{
+ union512i_d ad, zero;
+ union512 bd;
+ union512d cd;
+ union256i_d d;
+ union256 e;
+ union256d f;
+ union128i_d g;
+ union128 h;
+ union128d k;
+ int i;
+
+ for (i = 0; i < 16; i++)
+ zero.a[i] = 0;
+
+ for (i = 0; i < 8; i++)
+ {
+ d.a[i] = 109534 + i;
+ e.a[i] = 85034.095f + i;
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ f.a[i] = 41234512451345.0905 + i;
+ g.a[i] = 71469086341 + i;
+ h.a[i] = 45.1264f + i;
+ }
+
+ for (i = 0; i < 2; i++)
+ k.a[i] = 7146908634.576 + i;
+
+ cd.x = _mm512_zextpd128_pd512 (k.x);
+ if (memcmp (cd.a, k.a, 16)
+ || memcmp (&cd.a[2], &zero.a, 48))
+ abort ();
+
+ bd.x = _mm512_zextps128_ps512 (h.x);
+ if (memcmp (bd.a, h.a, 16)
+ || memcmp (&bd.a[4], &zero.a, 48))
+ abort ();
+
+ ad.x = _mm512_zextsi128_si512 (g.x);
+ if (memcmp (ad.a, g.a, 16)
+ || memcmp (&ad.a[4], &zero.a, 48))
+ abort ();
+
+ cd.x = _mm512_zextpd256_pd512 (f.x);
+ if (memcmp (cd.a, f.a, 32)
+ || memcmp (&cd.a[4], &zero.a, 32))
+ abort ();
+
+ bd.x = _mm512_zextps256_ps512 (e.x);
+ if (memcmp (bd.a, e.a, 32)
+ || memcmp (&bd.a[8], &zero.a, 32))
+ abort ();
+
+ ad.x = _mm512_zextsi256_si512 (d.x);
+ if (memcmp (ad.a, d.a, 32)
+ || memcmp (&ad.a[8], &zero.a, 32))
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmpd-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmpd-2.c
index 98b5ed1..8a673d7 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmpd-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmpd-2.c
@@ -9,7 +9,7 @@
#define SIZE (AVX512F_LEN / 64)
#include "avx512f-mask-type.h"
-#include "math.h"
+#include "math_m_pi.h"
#include "float.h"
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmps-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmps-2.c
index e5a917f..815a088 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmps-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmps-2.c
@@ -9,7 +9,7 @@
#define SIZE (AVX512F_LEN / 32)
#include "avx512f-mask-type.h"
-#include "math.h"
+#include "math_m_pi.h"
#include "float.h"
static void
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmsd-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmsd-2.c
index d3cd28c..88df19b 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmsd-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmsd-2.c
@@ -5,7 +5,7 @@
#include "avx512f-check.h"
#include "avx512f-helper.h"
-#include <math.h>
+#include "math_m_pi.h"
#include <float.h>
#include "avx512f-mask-type.h"
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmss-2.c b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmss-2.c
index 7364cc5..65ec045 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmss-2.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vfixupimmss-2.c
@@ -5,7 +5,7 @@
#include "avx512f-check.h"
#include "avx512f-helper.h"
-#include <math.h>
+#include "math_m_pi.h"
#include <float.h>
#include "avx512f-mask-type.h"
diff --git a/gcc/testsuite/gcc.target/i386/avx512vp2intersect-2intersect-1b.c b/gcc/testsuite/gcc.target/i386/avx512vp2intersect-2intersect-1b.c
index dce8705..48a0133 100644
--- a/gcc/testsuite/gcc.target/i386/avx512vp2intersect-2intersect-1b.c
+++ b/gcc/testsuite/gcc.target/i386/avx512vp2intersect-2intersect-1b.c
@@ -2,7 +2,7 @@
/* { dg-options "-O2 -mavx512vp2intersect" } */
/* { dg-require-effective-target avx512vp2intersect } */
-#define AVX512F
+#define AVX512VP2INTERSECT
#include <x86intrin.h>
#include "avx512f-helper.h"
diff --git a/gcc/testsuite/gcc.target/i386/avx512vp2intersect-2intersectvl-1b.c b/gcc/testsuite/gcc.target/i386/avx512vp2intersect-2intersectvl-1b.c
index 3801ff5..137fb5a 100644
--- a/gcc/testsuite/gcc.target/i386/avx512vp2intersect-2intersectvl-1b.c
+++ b/gcc/testsuite/gcc.target/i386/avx512vp2intersect-2intersectvl-1b.c
@@ -2,7 +2,7 @@
/* { dg-options "-O2 -mavx512vp2intersect -mavx512vl" } */
/* { dg-require-effective-target avx512vp2intersect } */
-#define AVX512F
+#define AVX512VP2INTERSECT
#include <x86intrin.h>
#include "avx512f-helper.h"
diff --git a/gcc/testsuite/gcc.target/i386/math_m_pi.h b/gcc/testsuite/gcc.target/i386/math_m_pi.h
new file mode 100644
index 0000000..0757a40
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/math_m_pi.h
@@ -0,0 +1,10 @@
+#include <math.h>
+#ifndef M_PI
+# define M_PI 3.14159265358979323846
+#endif
+#ifndef M_PI_2
+# define M_PI_2 1.57079632679489661923
+#endif
+#ifndef M_PI_4
+# define M_PI_4 0.78539816339744830962
+#endif
diff --git a/gcc/testsuite/gcc.target/i386/minmax-1.c b/gcc/testsuite/gcc.target/i386/minmax-1.c
index b92b8f9..0ec35b1 100644
--- a/gcc/testsuite/gcc.target/i386/minmax-1.c
+++ b/gcc/testsuite/gcc.target/i386/minmax-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -march=opteron" } */
+/* { dg-options "-O2 -march=opteron -mno-stv" } */
/* { dg-final { scan-assembler "test" } } */
/* { dg-final { scan-assembler-not "cmp" } } */
#define max(a,b) (((a) > (b))? (a) : (b))
diff --git a/gcc/testsuite/gcc.target/i386/minmax-2.c b/gcc/testsuite/gcc.target/i386/minmax-2.c
index a5cdf93..af9baea 100644
--- a/gcc/testsuite/gcc.target/i386/minmax-2.c
+++ b/gcc/testsuite/gcc.target/i386/minmax-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -mno-stv" } */
/* { dg-final { scan-assembler "test" } } */
/* { dg-final { scan-assembler-not "cmp" } } */
#define max(a,b) (((a) > (b))? (a) : (b))
diff --git a/gcc/testsuite/gcc.target/i386/minmax-3.c b/gcc/testsuite/gcc.target/i386/minmax-3.c
new file mode 100644
index 0000000..ec7b318
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/minmax-3.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mstv" } */
+
+#define max(a,b) (((a) > (b))? (a) : (b))
+#define min(a,b) (((a) < (b))? (a) : (b))
+
+int ssi[1024];
+unsigned int usi[1024];
+long long sdi[1024];
+unsigned long long udi[1024];
+
+#define CHECK(FN, VARIANT) \
+void \
+FN ## VARIANT (void) \
+{ \
+ for (int i = 1; i < 1024; ++i) \
+ VARIANT[i] = FN(VARIANT[i-1], VARIANT[i]); \
+}
+
+CHECK(max, ssi);
+CHECK(min, ssi);
+CHECK(max, usi);
+CHECK(min, usi);
+CHECK(max, sdi);
+CHECK(min, sdi);
+CHECK(max, udi);
+CHECK(min, udi);
diff --git a/gcc/testsuite/gcc.target/i386/minmax-4.c b/gcc/testsuite/gcc.target/i386/minmax-4.c
new file mode 100644
index 0000000..9d8ed18
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/minmax-4.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mstv -msse4.1" } */
+
+#include "minmax-3.c"
+
+/* { dg-final { scan-assembler-times "pmaxsd" 1 } } */
+/* { dg-final { scan-assembler-times "pmaxud" 1 } } */
+/* { dg-final { scan-assembler-times "pminsd" 1 } } */
+/* { dg-final { scan-assembler-times "pminud" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/minmax-5.c b/gcc/testsuite/gcc.target/i386/minmax-5.c
new file mode 100644
index 0000000..1971dbd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/minmax-5.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mstv -mavx512vl" } */
+
+#include "minmax-3.c"
+
+/* { dg-final { scan-assembler-times "vpmaxsd" 1 } } */
+/* { dg-final { scan-assembler-times "vpmaxud" 1 } } */
+/* { dg-final { scan-assembler-times "vpminsd" 1 } } */
+/* { dg-final { scan-assembler-times "vpminud" 1 } } */
+/* { dg-final { scan-assembler-times "vpmaxsq" 1 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "vpmaxuq" 1 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "vpminsq" 1 { target lp64 } } } */
+/* { dg-final { scan-assembler-times "vpminuq" 1 { target lp64 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/minmax-6.c b/gcc/testsuite/gcc.target/i386/minmax-6.c
new file mode 100644
index 0000000..b3af8c4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/minmax-6.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=haswell" } */
+
+unsigned short
+UMVLine16Y_11 (short unsigned int * Pic, int y, int width)
+{
+ if (y != width)
+ {
+ y = y < 0 ? 0 : y;
+ return Pic[y * width];
+ }
+ return Pic[y];
+}
+
+/* We do not want the RA to spill %esi for it's dual-use but using
+ pmaxsd is OK. */
+/* { dg-final { scan-assembler-not "rsp" { target { ! { ia32 } } } } } */
+/* { dg-final { scan-assembler "pmaxsd" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr73350.c b/gcc/testsuite/gcc.target/i386/pr73350.c
index 62f6cd4..30cb8b1 100644
--- a/gcc/testsuite/gcc.target/i386/pr73350.c
+++ b/gcc/testsuite/gcc.target/i386/pr73350.c
@@ -1,7 +1,7 @@
/* { dg-do run } */
/* { dg-options "-O2 -mavx512f" } */
/* { dg-require-effective-target avx512f } */
-#include <math.h>
+#include "math_m_pi.h"
#define AVX512F
#include "avx512f-helper.h"
diff --git a/gcc/testsuite/gcc.target/i386/pr80969-3.c b/gcc/testsuite/gcc.target/i386/pr80969-3.c
index d902a77..318e06c 100644
--- a/gcc/testsuite/gcc.target/i386/pr80969-3.c
+++ b/gcc/testsuite/gcc.target/i386/pr80969-3.c
@@ -2,11 +2,10 @@
/* { dg-do compile { target { { ! x32 } && { ! avx512f_runtime } } } } */
/* { dg-options "-Ofast -mabi=ms -mavx512f" } */
/* { dg-require-effective-target avx512f } */
+/* { dg-require-effective-target alloca } */
/* Test with alloca (and DRAP). */
-#include <alloca.h>
-
int a[56];
volatile int b = -12345;
volatile const int d = 42;
@@ -19,7 +18,7 @@ void (*volatile const foo_noinfo)(int *, int, int) = foo;
int main (int argc, char *argv[]) {
int c;
- int *e = alloca (d);
+ int *e = __builtin_alloca (d);
foo_noinfo (e, d, 0);
for (; b; b++) {
c = b;
diff --git a/gcc/testsuite/gcc.target/i386/pr85044.c b/gcc/testsuite/gcc.target/i386/pr85044.c
index a25cc7f..02ef91d 100644
--- a/gcc/testsuite/gcc.target/i386/pr85044.c
+++ b/gcc/testsuite/gcc.target/i386/pr85044.c
@@ -1,4 +1,5 @@
/* { dg-do run { target cet } } */
+/* { dg-require-effective-target trampolines } */
/* { dg-options "-O2 -fcf-protection=branch" } */
void callme (void (*callback) (void));
diff --git a/gcc/testsuite/gcc.target/i386/pr85693-1.c b/gcc/testsuite/gcc.target/i386/pr85693-1.c
new file mode 100644
index 0000000..b2bf58d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr85693-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-msse2 -O2 -ftree-vectorize" } */
+
+#define N 8
+
+int abs (int);
+
+unsigned char pix1[N], pix2[N];
+
+int foo (void)
+{
+ int i_sum = 0;
+ int i;
+
+ for (i = 0; i < N; i++)
+ i_sum += abs (pix1[i] - pix2[i]);
+
+ return i_sum;
+}
+
+/* { dg-final { scan-assembler "psadbw" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr85693.c b/gcc/testsuite/gcc.target/i386/pr85693.c
index 214a739..9843ea5 100644
--- a/gcc/testsuite/gcc.target/i386/pr85693.c
+++ b/gcc/testsuite/gcc.target/i386/pr85693.c
@@ -1,4 +1,4 @@
-/* { dg-do compile }
+/* { dg-do compile } */
/* { dg-options "-msse2 -O2 -ftree-vectorize" } */
#define N 1024
diff --git a/gcc/testsuite/gcc.target/i386/pr91154.c b/gcc/testsuite/gcc.target/i386/pr91154.c
new file mode 100644
index 0000000..69f2e21
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91154.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse4.1 -mstv" } */
+
+void foo (int *dc, int *mc, int *tpdd, int *tpmd, int M)
+{
+ int sc;
+ int k;
+ for (k = 1; k <= M; k++)
+ {
+ dc[k] = dc[k-1] + tpdd[k-1];
+ if ((sc = mc[k-1] + tpmd[k-1]) > dc[k]) dc[k] = sc;
+ if (dc[k] < -987654321) dc[k] = -987654321;
+ }
+}
+
+/* We want to convert the loop to SSE since SSE pmaxsd is faster than
+ compare + conditional move. */
+/* { dg-final { scan-assembler-not "cmov" } } */
+/* { dg-final { scan-assembler-times "pmaxsd" 2 } } */
+/* { dg-final { scan-assembler-times "paddd" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr91223.c b/gcc/testsuite/gcc.target/i386/pr91223.c
new file mode 100644
index 0000000..1b9e85b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91223.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-Og -fno-tree-fre" } */
+int a;
+void fn2(short, short);
+
+void fn1(void) {
+ short b[8];
+ b[0] |= a & 3;
+ b[1] = a;
+ fn2(b[0], b[1]);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr91385.c b/gcc/testsuite/gcc.target/i386/pr91385.c
new file mode 100644
index 0000000..f3ff8c8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91385.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -dp" } */
+/* { dg-final { scan-assembler-not "zero_extendsidi" } } */
+
+unsigned long long
+foo (unsigned int a)
+{
+ return -a;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr91408.c b/gcc/testsuite/gcc.target/i386/pr91408.c
new file mode 100644
index 0000000..13acd15
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91408.c
@@ -0,0 +1,29 @@
+/* PR target/91408 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-vectorize -fno-tree-forwprop" } */
+
+long long a;
+unsigned char b;
+short *c;
+int d;
+
+void
+foo (long long *x)
+{
+ unsigned char *e = (char *) x;
+ int f, g = 0;
+ for (d = 0; d < 8; d++)
+ {
+ f = b - e[d];
+ if (f < 0)
+ f = -f;
+ g += f;
+ }
+ c[0] = g;
+}
+
+void
+bar (void)
+{
+ foo (&a);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr91469-1.c b/gcc/testsuite/gcc.target/i386/pr91469-1.c
new file mode 100644
index 0000000..589b72d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91469-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-funroll-loops -O2 -fno-gcse -mavx512vbmi -fno-ivopts -mstv" } */
+
+int a, b, e;
+long long c;
+int d[6];
+
+void fn1() {
+ int i;
+ unsigned f;
+ c = a;
+ f = i;
+ for (; i < b; i++)
+ if (d[i] > f)
+ f = d[i];
+ e = f;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr91469-2.c b/gcc/testsuite/gcc.target/i386/pr91469-2.c
new file mode 100644
index 0000000..4254aaa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr91469-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-Os --param scev-max-expr-size=0 -mavx512vnni -funroll-all-loops" } */
+
+int a, b, c, d;
+int *e;
+void fn1()
+{
+ b = c > 0 ? c : 0;
+ d += e[b];
+ a = d > 0 ? d : 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse2-cvt-vec.c b/gcc/testsuite/gcc.target/i386/sse2-cvt-vec.c
index 8a811a3..67fae51 100644
--- a/gcc/testsuite/gcc.target/i386/sse2-cvt-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse2-cvt-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse2" } */
/* { dg-require-effective-target sse2 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse2-check.h"
@@ -13,7 +12,7 @@
#include CHECK_H
-#include <math.h>
+#include "math_m_pi.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/sse2-mul-1.c b/gcc/testsuite/gcc.target/i386/sse2-mul-1.c
index 9cdc127..af63d24 100644
--- a/gcc/testsuite/gcc.target/i386/sse2-mul-1.c
+++ b/gcc/testsuite/gcc.target/i386/sse2-mul-1.c
@@ -14,11 +14,6 @@
#include <stdlib.h>
-/* mingw runtime don't provide random(). */
-#ifdef __MINGW32__
-#define random rand
-#endif
-
#define N 512
static short a1[N], a2[N], a3[N];
static unsigned short b1[N], b2[N], b3[N];
@@ -160,12 +155,12 @@ TEST (void)
asm volatile ("" : : "r" (&s2) : "memory");
asm volatile ("" : : "r" (&s3) : "memory");
asm volatile ("" : : "r" (&s4) : "memory");
- b2[i] = (int) random ();
- b3[i] = (int) random ();
+ b2[i] = (int) rand ();
+ b3[i] = (int) rand ();
a2[i] = b2[i];
a3[i] = b3[i];
- d2[i] = (((int) random ()) << 16) | b2[i];
- d3[i] = (((int) random ()) << 16) | b3[i];
+ d2[i] = (((int) rand ()) << 16) | b2[i];
+ d3[i] = (((int) rand ()) << 16) | b3[i];
c2[i] = d2[i];
c3[i] = d3[i];
s1 += a2[i] * a3[i];
diff --git a/gcc/testsuite/gcc.target/i386/sse2-pr91201-2.c b/gcc/testsuite/gcc.target/i386/sse2-pr91201-2.c
new file mode 100644
index 0000000..d711ee0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse2-pr91201-2.c
@@ -0,0 +1,21 @@
+/* PR tree-optimization/91201 */
+/* { dg-do compile { target lp64 } } */
+/* { dg-options "-O3 -msse2 -mno-sse3" } */
+/* { dg-final { scan-assembler "\tpsadbw\t" } } */
+
+unsigned char bytes[1024];
+
+unsigned char
+sum (void)
+{
+ unsigned char r = 0;
+ unsigned char *p = (unsigned char *) bytes;
+ int n;
+
+ for (n = 8; n < sizeof (bytes); ++n)
+ {
+ p[n - 8] += p[n];
+ r += p[n];
+ }
+ return r;
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse2-pr91201-3.c b/gcc/testsuite/gcc.target/i386/sse2-pr91201-3.c
new file mode 100644
index 0000000..1fc5834
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse2-pr91201-3.c
@@ -0,0 +1,13 @@
+/* PR tree-optimization/91201 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -mno-sse3 -mtune=generic -masm=att" } */
+/* { dg-final { scan-assembler "\tmovd\t%xmm0, %eax" } } */
+/* { dg-final { scan-assembler-not "\\(%" } } */
+
+typedef unsigned char V __attribute__((vector_size (16)));
+
+unsigned char
+foo (V x)
+{
+ return x[0];
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse2-pr91201-4.c b/gcc/testsuite/gcc.target/i386/sse2-pr91201-4.c
new file mode 100644
index 0000000..48044c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse2-pr91201-4.c
@@ -0,0 +1,13 @@
+/* PR tree-optimization/91201 */
+/* { dg-do compile } */
+/* { dg-options "-Os -msse2 -mno-sse3 -mtune=generic -masm=att" } */
+/* { dg-final { scan-assembler "\tmovd\t%xmm0, %eax" } } */
+/* { dg-final { scan-assembler-not "\\(%" } } */
+
+typedef unsigned char V __attribute__((vector_size (16)));
+
+unsigned char
+foo (V x)
+{
+ return x[0];
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse2-pr91201-5.c b/gcc/testsuite/gcc.target/i386/sse2-pr91201-5.c
new file mode 100644
index 0000000..13c1954
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse2-pr91201-5.c
@@ -0,0 +1,13 @@
+/* PR tree-optimization/91201 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2 -mno-sse3 -mtune=k8 -masm=att" } */
+/* { dg-final { scan-assembler-not "\tmovd\t%xmm0, %eax" } } */
+/* { dg-final { scan-assembler "\tmov(zbl|b)\t\[^\n\r]*\\(%" } } */
+
+typedef unsigned char V __attribute__((vector_size (16)));
+
+unsigned char
+foo (V x)
+{
+ return x[0];
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse2-pr91201-6.c b/gcc/testsuite/gcc.target/i386/sse2-pr91201-6.c
new file mode 100644
index 0000000..2997bfd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse2-pr91201-6.c
@@ -0,0 +1,13 @@
+/* PR tree-optimization/91201 */
+/* { dg-do compile } */
+/* { dg-options "-Os -msse2 -mno-sse3 -mtune=k8 -masm=att" } */
+/* { dg-final { scan-assembler "\tmovd\t%xmm0, %eax" } } */
+/* { dg-final { scan-assembler-not "\\(%" } } */
+
+typedef unsigned char V __attribute__((vector_size (16)));
+
+unsigned char
+foo (V x)
+{
+ return x[0];
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse2-pr91201.c b/gcc/testsuite/gcc.target/i386/sse2-pr91201.c
new file mode 100644
index 0000000..016b187
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse2-pr91201.c
@@ -0,0 +1,18 @@
+/* PR tree-optimization/91201 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -msse2 -mno-sse3" } */
+/* { dg-final { scan-assembler "\tpsadbw\t" } } */
+
+unsigned char bytes[1024];
+
+unsigned char
+sum (void)
+{
+ unsigned char r = 0;
+ unsigned char *p = (unsigned char *) bytes;
+ int n;
+
+ for (n = 0; n < sizeof (bytes); ++n)
+ r += p[n];
+ return r;
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-blendps-2.c b/gcc/testsuite/gcc.target/i386/sse4_1-blendps-2.c
index 8fe71b7..512394e 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-blendps-2.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-blendps-2.c
@@ -8,11 +8,6 @@
#include <string.h>
#include <stdlib.h>
-/* mingw runtime don't provide random(). */
-#ifdef __MINGW32__
-#define random rand
-#endif
-
#define NUM 20
#undef MASK
@@ -64,7 +59,7 @@ sse4_1_test (void)
init_blendps (src1.f, src2.f);
for (i = 0; i < 4; i++)
- src3.f[i] = (int) random ();
+ src3.f[i] = (int) rand ();
/* Check blendps imm8, m128, xmm */
for (i = 0; i < NUM; i++)
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-blendps.c b/gcc/testsuite/gcc.target/i386/sse4_1-blendps.c
index 3f4b335..556094b 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-blendps.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-blendps.c
@@ -16,11 +16,6 @@
#include <string.h>
#include <stdlib.h>
-/* mingw runtime don't provide random(). */
-#ifdef __MINGW32__
-#define random rand
-#endif
-
#define NUM 20
#ifndef MASK
@@ -73,7 +68,7 @@ TEST (void)
init_blendps (src1.f, src2.f);
for (i = 0; i < 4; i++)
- src3.f[i] = (int) random ();
+ src3.f[i] = (int) rand ();
/* Check blendps imm8, m128, xmm */
for (i = 0; i < NUM; i++)
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-ceil-sfix-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-ceil-sfix-vec.c
index bb32c8d..6250906 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-ceil-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-ceil-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern double ceil (double);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-ceil-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-ceil-vec.c
index 4193aaa..2ef43ae 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-ceil-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-ceil-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern double ceil (double);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-ceilf-sfix-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-ceilf-sfix-vec.c
index 971ccb8..c4ccad1 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-ceilf-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-ceilf-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern float ceilf (float);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-ceilf-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-ceilf-vec.c
index e2ebafc..1382d20 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-ceilf-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-ceilf-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern float ceilf (float);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-floor-sfix-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-floor-sfix-vec.c
index 15db225..89ce331 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-floor-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-floor-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern double floor (double);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-floor-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-floor-vec.c
index a33f7d9..32b7002 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-floor-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-floor-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern double floor (double);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-floorf-sfix-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-floorf-sfix-vec.c
index bf05af3..b191236 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-floorf-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-floorf-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-floorf-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-floorf-vec.c
index 13630fb..d2f4a85 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-floorf-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-floorf-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-pr91201.c b/gcc/testsuite/gcc.target/i386/sse4_1-pr91201.c
new file mode 100644
index 0000000..095d18e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-pr91201.c
@@ -0,0 +1,12 @@
+/* PR tree-optimization/91201 */
+/* { dg-do compile } */
+/* { dg-options "-Os -msse4.1 -masm=att" } */
+/* { dg-final { scan-assembler-not "\tmovzb(w|l)" } } */
+
+typedef unsigned char V __attribute__((vector_size (16)));
+
+unsigned short
+foo (V x)
+{
+ return x[0];
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-rint-sfix-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-rint-sfix-vec.c
index 6111933..c82c353 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-rint-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-rint-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern double rint (double);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-rint-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-rint-vec.c
index 88965a5..309f17e 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-rint-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-rint-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern double rint (double);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-rintf-sfix-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-rintf-sfix-vec.c
index 12d3dbe..5188d4b 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-rintf-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-rintf-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern float rintf (float);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-rintf-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-rintf-vec.c
index 362832d..8c31f8d 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-rintf-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-rintf-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern float rintf (float);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-round-sfix-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-round-sfix-vec.c
index c54acee..96b8dca 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-round-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-round-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern double round (double);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-round-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-round-vec.c
index 83aeb64..e3e9328 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-round-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-round-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern double round (double);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-round.h b/gcc/testsuite/gcc.target/i386/sse4_1-round.h
index dfb0b77..adff48b 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-round.h
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-round.h
@@ -1,5 +1,5 @@
#include <smmintrin.h>
-#include <math.h>
+#include "math_m_pi.h"
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundf-sfix-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundf-sfix-vec.c
index cd11071..1416dc9 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundf-sfix-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundf-sfix-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern float roundf (float);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundf-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundf-vec.c
index b55e5df..fc0aead 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundf-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundf-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern float roundf (float);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundpd-1.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundpd-1.c
index 8baee339..37f2028 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundpd-1.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundpd-1.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target sse4 } */
/* { dg-options "-O2 -msse4.1" } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundpd-2.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundpd-2.c
index 86b78ed..7f0475f 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundpd-2.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundpd-2.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target sse4 } */
/* { dg-options "-O2 -msse4.1" } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundpd-3.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundpd-3.c
index 6e6a05c..4a1f810 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundpd-3.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundpd-3.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target sse4 } */
/* { dg-options "-O2 -msse4.1" } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundps-1.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundps-1.c
index fab2278..fa8002d 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundps-1.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundps-1.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target sse4 } */
/* { dg-options "-O2 -msse4.1" } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#include "sse4_1-check.h"
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundps-2.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundps-2.c
index 405c55d..673c786 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundps-2.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundps-2.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target sse4 } */
/* { dg-options "-O2 -msse4.1" } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#include "sse4_1-check.h"
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundps-3.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundps-3.c
index 97485b9..9b52ae5 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundps-3.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundps-3.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target sse4 } */
/* { dg-options "-O2 -msse4.1" } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#include "sse4_1-check.h"
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-1.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-1.c
index e6cec0b..f3ecd0e 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-1.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-1.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target sse4 } */
/* { dg-options "-O2 -msse4.1" } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#include "sse4_1-check.h"
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-2.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-2.c
index 54ca21f..91dfd38 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-2.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-2.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target sse4 } */
/* { dg-options "-O2 -msse4.1" } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#include "sse4_1-check.h"
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-3.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-3.c
index a59d6f8..0a69e06 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-3.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-3.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target sse4 } */
/* { dg-options "-O2 -msse4.1" } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#include "sse4_1-check.h"
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-4.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-4.c
index ff8b09e..d8dcca0 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-4.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundsd-4.c
@@ -1,12 +1,11 @@
/* { dg-do run } */
/* { dg-require-effective-target sse4 } */
/* { dg-options "-O2 -msse4.1" } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#include "sse4_1-check.h"
#include <smmintrin.h>
-#include <math.h>
+#include "math_m_pi.h"
#include <string.h>
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundss-1.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundss-1.c
index 9c20b90a..01940bd 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundss-1.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundss-1.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target sse4 } */
/* { dg-options "-O2 -msse4.1" } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#include "sse4_1-check.h"
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundss-2.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundss-2.c
index 072664e..4c73331 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundss-2.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundss-2.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target sse4 } */
/* { dg-options "-O2 -msse4.1" } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#include "sse4_1-check.h"
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundss-3.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundss-3.c
index 97c69fd..774c193 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundss-3.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundss-3.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-require-effective-target sse4 } */
/* { dg-options "-O2 -msse4.1" } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#include "sse4_1-check.h"
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-roundss-4.c b/gcc/testsuite/gcc.target/i386/sse4_1-roundss-4.c
index 9548890..0a9ab59 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-roundss-4.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-roundss-4.c
@@ -1,12 +1,11 @@
/* { dg-do run } */
/* { dg-require-effective-target sse4 } */
/* { dg-options "-O2 -msse4.1" } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#include "sse4_1-check.h"
#include <smmintrin.h>
-#include <math.h>
+#include "math_m_pi.h"
#include <string.h>
#define NUM 64
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-trunc-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-trunc-vec.c
index 5c27083..4f4786c 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-trunc-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-trunc-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern double trunc (double);
diff --git a/gcc/testsuite/gcc.target/i386/sse4_1-truncf-vec.c b/gcc/testsuite/gcc.target/i386/sse4_1-truncf-vec.c
index e491fee..691ea7b 100644
--- a/gcc/testsuite/gcc.target/i386/sse4_1-truncf-vec.c
+++ b/gcc/testsuite/gcc.target/i386/sse4_1-truncf-vec.c
@@ -1,7 +1,6 @@
/* { dg-do run } */
/* { dg-options "-O2 -ffast-math -ftree-vectorize -msse4.1" } */
/* { dg-require-effective-target sse4 } */
-/* { dg-skip-if "no M_PI" { vxworks_kernel } } */
#ifndef CHECK_H
#define CHECK_H "sse4_1-check.h"
@@ -14,7 +13,7 @@
#include CHECK_H
#define __NO_MATH_INLINES
-#include <math.h>
+#include "math_m_pi.h"
extern float truncf (float);
diff --git a/gcc/testsuite/gcc.target/i386/xop-vshift-1.c b/gcc/testsuite/gcc.target/i386/xop-vshift-1.c
index ee3d299..f3713e8 100644
--- a/gcc/testsuite/gcc.target/i386/xop-vshift-1.c
+++ b/gcc/testsuite/gcc.target/i386/xop-vshift-1.c
@@ -19,11 +19,6 @@
#define TYPE2 long long
#endif
-/* mingw runtime don't provide random(). */
-#ifdef __MINGW32__
-#define random rand
-#endif
-
signed TYPE1 a[N], b[N], g[N];
unsigned TYPE1 c[N], h[N];
signed TYPE2 d[N], e[N], j[N];
@@ -108,10 +103,10 @@ TEST ()
for (i = 0; i < N; i++)
{
asm ("");
- c[i] = (random () << 1) | (random () & 1);
+ c[i] = (rand () << 1) | (rand () & 1);
b[i] = (i * 85) & (sizeof (TYPE1) * __CHAR_BIT__ - 1);
a[i] = c[i];
- d[i] = (random () << 1) | (random () & 1);
+ d[i] = (rand () << 1) | (rand () & 1);
d[i] |= (unsigned long long) c[i] << 32;
e[i] = (i * 85) & (sizeof (TYPE2) * __CHAR_BIT__ - 1);
f[i] = d[i];
diff --git a/gcc/testsuite/gcc.target/msp430/asm-register-names-lower-case.c b/gcc/testsuite/gcc.target/msp430/asm-register-names-lower-case.c
new file mode 100644
index 0000000..98e3929
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/asm-register-names-lower-case.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-expand" } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R4" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R5" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R6" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R7" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R8" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R9" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R10" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R11" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R12" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R13" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R14" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R15" expand } } */
+
+/* PR target/70320
+ Check that a lower case "r" in register names is accepted in
+ an asm statement clobber list. */
+
+void
+foo (void)
+{
+ __asm__ ("" : : : "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12",
+ "r13", "r14", "r15");
+}
diff --git a/gcc/testsuite/gcc.target/msp430/asm-register-names-upper-case.c b/gcc/testsuite/gcc.target/msp430/asm-register-names-upper-case.c
new file mode 100644
index 0000000..bd4edc0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/asm-register-names-upper-case.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-expand" } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R4" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R5" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R6" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R7" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R8" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R9" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R10" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R11" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R12" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R13" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R14" expand } } */
+/* { dg-final { scan-rtl-dump "(?n)clobber.*R15" expand } } */
+
+/* PR target/70320
+ Check that an upper case "r" in register names is accepted in
+ an asm statement clobber list. */
+
+void
+foo (void)
+{
+ __asm__ ("" : : : "R4", "R5", "R6", "R7", "R8", "R9", "R10", "R11", "R12",
+ "R13", "R14", "R15");
+}
diff --git a/gcc/testsuite/gcc.target/msp430/devices-main.c b/gcc/testsuite/gcc.target/msp430/devices-main.c
new file mode 100644
index 0000000..20448f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices-main.c
@@ -0,0 +1,6 @@
+int
+main (void)
+{
+ while (1);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/msp430/devices/README b/gcc/testsuite/gcc.target/msp430/devices/README
new file mode 100644
index 0000000..9134b4c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/README
@@ -0,0 +1,17 @@
+Some tests in this directory are run in a msp430-specific "torture" style,
+where all target specific options (that change code generation) are each used
+on each test source file in turn.
+
+The criteria for this torture style of testing is:
+ - The source file has a .c suffix
+ - The source file is in this "devices" subdirectory of the msp430 tests
+ - Somewhere in the test file name matches the regex:
+ [a-z0-9]+430[a-z0-9_]+(?=\.c).
+
+Some of the options used to run the tests will produce warnings/errors for the
+mcus, so ensure the test has dg-warning and dg-error directives as appropriate.
+
+The "bad-device-*.c" tests expect a corresponding "bad-devices-*.csv", which
+msp430.exp will pass as the argument to -mdevices-csv-loc=. These tests are for
+checking the warnings in msp430-devices.c about a corrupted devices.csv work as
+expected.
diff --git a/gcc/testsuite/gcc.target/msp430/devices/bad-devices-1.c b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-1.c
new file mode 100644
index 0000000..29ef859
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-1.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_00 -mno-warn-mcu" } */
+/* { dg-warning "'CPU_TYPE' column heading is missing from 'devices.csv'" "" { target *-*-* } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/bad-devices-1.csv b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-1.csv
new file mode 100644
index 0000000..282fa7b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-1.csv
@@ -0,0 +1,3 @@
+# Test warning for missing CPU_TYPE heading
+# Device Name,FOO,MPY_TYPE
+msp430_00,0,0
diff --git a/gcc/testsuite/gcc.target/msp430/devices/bad-devices-2.c b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-2.c
new file mode 100644
index 0000000..32e5ceb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-2.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_00 -mno-warn-mcu" } */
+/* { dg-warning "'MPY_TYPE' column heading is missing from 'devices.csv'" "" { target *-*-* } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/bad-devices-2.csv b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-2.csv
new file mode 100644
index 0000000..3bead68
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-2.csv
@@ -0,0 +1,3 @@
+# Test warning for missing MPY_TYPE heading
+# Device Name,CPU_TYPE,FOO
+msp430_00,0,0
diff --git a/gcc/testsuite/gcc.target/msp430/devices/bad-devices-3.c b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-3.c
new file mode 100644
index 0000000..c982c4a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-3.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_00 -mno-warn-mcu" } */
+/* { dg-warning "'CPU_TYPE' and 'MPY_TYPE' column headings are missing from 'devices.csv'" "" { target *-*-* } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/bad-devices-3.csv b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-3.csv
new file mode 100644
index 0000000..63b2030
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-3.csv
@@ -0,0 +1,3 @@
+# Test warning for missing CPU_TYPE and MPY_TYPE headings
+# Device Name,FOO,BAR
+msp430_00,0,0
diff --git a/gcc/testsuite/gcc.target/msp430/devices/bad-devices-4.c b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-4.c
new file mode 100644
index 0000000..89ebe61
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-4.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_00 -mno-warn-mcu" } */
+/* { dg-warning "format of column headings in 'devices.csv' is incorrect" "" { target *-*-* } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/bad-devices-4.csv b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-4.csv
new file mode 100644
index 0000000..4f25f93
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-4.csv
@@ -0,0 +1,3 @@
+# Test incorrectly formatted column headings
+# DeviceName,CPU_TYPE,MPY_TYPE
+msp430_00,0,0
diff --git a/gcc/testsuite/gcc.target/msp430/devices/bad-devices-5.c b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-5.c
new file mode 100644
index 0000000..e33bac0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-5.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_00 -mno-warn-mcu" } */
+/* { dg-warning "invalid 'CPU_TYPE' value of '5' read from 'devices.csv' for 'msp430_00'" "" { target *-*-* } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/bad-devices-5.csv b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-5.csv
new file mode 100644
index 0000000..32b7041
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-5.csv
@@ -0,0 +1,3 @@
+# Test bad CPU_TYPE value
+# Device Name,CPU_TYPE,MPY_TYPE
+msp430_00,5,0
diff --git a/gcc/testsuite/gcc.target/msp430/devices/bad-devices-6.c b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-6.c
new file mode 100644
index 0000000..9dd9ed9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-6.c
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_00 -mno-warn-mcu" } */
+/* { dg-warning "invalid 'MPY_TYPE' value of '3' read from 'devices.csv' for 'msp430_00'" "" { target *-*-* } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/bad-devices-6.csv b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-6.csv
new file mode 100644
index 0000000..0ec7152
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/bad-devices-6.csv
@@ -0,0 +1,3 @@
+# Test bad MPY_TYPE value
+# Device Name,CPU_TYPE,MPY_TYPE
+msp430_00,0,3
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-device-order.c b/gcc/testsuite/gcc.target/msp430/devices/csv-device-order.c
new file mode 100644
index 0000000..1728803
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-device-order.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-skip-if "MCU supports 430 ISA only" { *-*-* } { "-mlarge" "-mcpu=msp430x*" } { "" } } */
+/* { dg-additional-options "-mmcu=msp430f012 -mcpu=msp430 -mhwmult=16bit" } */
+
+/* Test that MCU names in devices.csv are only chosen if the full device name
+ is matched exactly.
+ msp430f0123 (with 430X ISA and f5series hwmult) appears before msp430f012 in
+ devices.csv, but should not be matched.
+ Errors and warnings will be emitted if msp430f0123 is wrongly matched. */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_00.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_00.c
new file mode 100644
index 0000000..8d56873
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_00.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_00" } */
+/* { dg-warning "does not have hardware multiply" "" { target msp430_hwmul_not_none } 0 } */
+/* { dg-warning "supports 430 ISA but" "" { target msp430_430x_selected } 0 } */
+/* { dg-error "'-mlarge' requires a 430X-compatible '-mmcu='" "" { target msp430_mlarge_selected } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_01.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_01.c
new file mode 100644
index 0000000..154511b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_01.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_01" } */
+/* { dg-warning "supports 16-bit hardware multiply" "" { target msp430_hwmul_not_16bit } 0 } */
+/* { dg-warning "supports 430 ISA but" "" { target msp430_430x_selected } 0 } */
+/* { dg-error "'-mlarge' requires a 430X-compatible '-mmcu='" "" { target msp430_mlarge_selected } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_02.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_02.c
new file mode 100644
index 0000000..4c72163
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_02.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_02" } */
+/* { dg-warning "supports 16-bit hardware multiply" "" { target msp430_hwmul_not_16bit } 0 } */
+/* { dg-warning "supports 430 ISA but" "" { target msp430_430x_selected } 0 } */
+/* { dg-error "'-mlarge' requires a 430X-compatible '-mmcu='" "" { target msp430_mlarge_selected } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_04.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_04.c
new file mode 100644
index 0000000..c8ed711
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_04.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_04" } */
+/* { dg-warning "supports 32-bit hardware multiply" "" { target msp430_hwmul_not_32bit } 0 } */
+/* { dg-warning "supports 430 ISA but" "" { target msp430_430x_selected } 0 } */
+/* { dg-error "'-mlarge' requires a 430X-compatible '-mmcu='" "" { target msp430_mlarge_selected } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_08.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_08.c
new file mode 100644
index 0000000..0214e63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_08.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_08" } */
+/* { dg-warning "supports 32-bit .5xx. hardware multiply" "" { target msp430_hwmul_not_f5 } 0 } */
+/* { dg-warning "supports 430 ISA but" "" { target msp430_430x_selected } 0 } */
+/* { dg-error "'-mlarge' requires a 430X-compatible '-mmcu='" "" { target msp430_mlarge_selected } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_10.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_10.c
new file mode 100644
index 0000000..86f89ed
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_10.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_10" } */
+/* { dg-warning "does not have hardware multiply" "" { target msp430_hwmul_not_none } 0 } */
+/* { dg-warning "supports 430X ISA but '-mcpu' option is set to 430" "" { target msp430_430_selected } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_11.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_11.c
new file mode 100644
index 0000000..2923238
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_11.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_11" } */
+/* { dg-warning "supports 430X ISA but '-mcpu' option is set to 430" "" { target msp430_430_selected } 0 } */
+/* { dg-warning "supports 16-bit hardware multiply" "" { target msp430_hwmul_not_16bit } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_12.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_12.c
new file mode 100644
index 0000000..ed59ac8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_12.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_12" } */
+/* { dg-warning "supports 430X ISA but '-mcpu' option is set to 430" "" { target msp430_430_selected } 0 } */
+/* { dg-warning "supports 16-bit hardware multiply" "" { target msp430_hwmul_not_16bit } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_14.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_14.c
new file mode 100644
index 0000000..fb038a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_14.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_14" } */
+/* { dg-warning "supports 430X ISA but '-mcpu' option is set to 430" "" { target msp430_430_selected } 0 } */
+/* { dg-warning "supports 32-bit hardware multiply" "" { target msp430_hwmul_not_32bit } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_18.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_18.c
new file mode 100644
index 0000000..133f984
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_18.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_18" } */
+/* { dg-warning "supports 430X ISA but '-mcpu' option is set to 430" "" { target msp430_430_selected } 0 } */
+/* { dg-warning "supports 32-bit .5xx. hardware multiply" "" { target msp430_hwmul_not_f5 } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_20.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_20.c
new file mode 100644
index 0000000..c7c9425
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_20.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_20" } */
+/* { dg-warning "does not have hardware multiply" "" { target msp430_hwmul_not_none } 0 } */
+/* { dg-warning "supports 430X ISA but '-mcpu' option is set to 430" "" { target msp430_430_selected } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_21.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_21.c
new file mode 100644
index 0000000..8794f89
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_21.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_21" } */
+/* { dg-warning "supports 430X ISA but '-mcpu' option is set to 430" "" { target msp430_430_selected } 0 } */
+/* { dg-warning "supports 16-bit hardware multiply" "" { target msp430_hwmul_not_16bit } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_22.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_22.c
new file mode 100644
index 0000000..47d90f4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_22.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_22" } */
+/* { dg-warning "supports 430X ISA but '-mcpu' option is set to 430" "" { target msp430_430_selected } 0 } */
+/* { dg-warning "supports 16-bit hardware multiply" "" { target msp430_hwmul_not_16bit } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_24.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_24.c
new file mode 100644
index 0000000..0a61630
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_24.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_24" } */
+/* { dg-warning "supports 430X ISA but '-mcpu' option is set to 430" "" { target msp430_430_selected } 0 } */
+/* { dg-warning "supports 32-bit hardware multiply" "" { target msp430_hwmul_not_32bit } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_28.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_28.c
new file mode 100644
index 0000000..1243f75
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430_28.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430_28" } */
+/* { dg-warning "supports 430X ISA but '-mcpu' option is set to 430" "" { target msp430_430_selected } 0 } */
+/* { dg-warning "supports 32-bit .5xx. hardware multiply" "" { target msp430_hwmul_not_f5 } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/csv-msp430fr5969.c b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430fr5969.c
new file mode 100644
index 0000000..6364607
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/csv-msp430fr5969.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-mmcu=msp430fr5969" } */
+/* MSP430FR5969 has msp430x ISA and f5series hwmult in the hard-coded data,
+ check that the different values for this device in devices.csv override it.
+ */
+/* { dg-warning "does not have hardware multiply" "" { target msp430_hwmul_not_none } 0 } */
+/* { dg-warning "supports 430 ISA but" "" { target msp430_430x_selected } 0 } */
+/* { dg-error "'-mlarge' requires a 430X-compatible '-mmcu='" "" { target msp430_mlarge_selected } 0 } */
+
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/devices.csv b/gcc/testsuite/gcc.target/msp430/devices/devices.csv
new file mode 100644
index 0000000..7a13ed9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/devices.csv
@@ -0,0 +1,22 @@
+# Text before "#Device Name" is ignored.
+# We add arbitrary/empty fields in some records after the MPY_TYPE column to get
+# more varied testing.
+# Device Name,CPU_TYPE,MPY_TYPE
+msp430_00,0,0
+msp430_01,0,1,
+msp430_02,0,2,1
+msp430_04,0,4
+msp430_08,0,8,
+msp430_10,1,0,0,
+msp430_11,1,1
+msp430_12,1,2
+msp430_14,1,4,,
+msp430_18,1,8
+msp430_20,2,0
+msp430_21,2,1,4,
+msp430_22,2,2
+msp430_24,2,4
+msp430_28,2,8,100,
+msp430fr5969,0,0
+msp430f0123,2,8
+msp430f012,0,1
diff --git a/gcc/testsuite/gcc.target/msp430/devices/hard-cc430f5123.c b/gcc/testsuite/gcc.target/msp430/devices/hard-cc430f5123.c
new file mode 100644
index 0000000..15a4ae1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/hard-cc430f5123.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mmcu=cc430f5123" } */
+/* { dg-warning "supports 430X ISA but '-mcpu' option is set to 430" "" { target msp430_430_selected } 0 } */
+/* { dg-warning "supports 32-bit .5xx. hardware multiply" "" { target msp430_hwmul_not_f5 } 0 } */
+
+/* revision=2, hwmpy=8 */
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/hard-foo.c b/gcc/testsuite/gcc.target/msp430/devices/hard-foo.c
new file mode 100644
index 0000000..e13acb5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/hard-foo.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-mmcu=msp430foo" } */
+/* { dg-warning "could not locate MCU data file 'devices.csv'" "" { target *-*-* } 0 } */
+/* { dg-warning "Unrecognized MCU name 'msp430foo'.*\n.*Use the" "" { target *-*-* } 0 } */
+
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/hard-msp430afe253.c b/gcc/testsuite/gcc.target/msp430/devices/hard-msp430afe253.c
new file mode 100644
index 0000000..9edf6eb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/hard-msp430afe253.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-mmcu=msp430afe253" } */
+/* { dg-warning "supports 16-bit hardware multiply" "" { target msp430_hwmul_not_16bit } 0 } */
+/* { dg-warning "supports 430 ISA but" "" { target msp430_430x_selected } 0 } */
+/* { dg-error "'-mlarge' requires a 430X-compatible '-mmcu='" "" { target msp430_mlarge_selected } 0 } */
+
+/* revision=0, hwmpy=2 */
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/hard-msp430cg4616.c b/gcc/testsuite/gcc.target/msp430/devices/hard-msp430cg4616.c
new file mode 100644
index 0000000..493d022
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/hard-msp430cg4616.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mmcu=msp430cg4616" } */
+/* { dg-warning "supports 430X ISA but '-mcpu' option is set to 430" "" { target msp430_430_selected } 0 } */
+/* { dg-warning "supports 16-bit hardware multiply" "" { target msp430_hwmul_not_16bit } 0 } */
+
+/* revision=1, hwmpy=1 */
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/hard-msp430f4783.c b/gcc/testsuite/gcc.target/msp430/devices/hard-msp430f4783.c
new file mode 100644
index 0000000..af918c3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/hard-msp430f4783.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-mmcu=msp430f4783" } */
+/* { dg-warning "supports 32-bit hardware multiply" "" { target msp430_hwmul_not_32bit } 0 } */
+/* { dg-warning "supports 430 ISA but" "" { target msp430_430x_selected } 0 } */
+/* { dg-error "'-mlarge' requires a 430X-compatible '-mmcu='" "" { target msp430_mlarge_selected } 0 } */
+
+/* revision=0, hwmpy=4 */
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/devices/hard-rf430frl154h_rom.c b/gcc/testsuite/gcc.target/msp430/devices/hard-rf430frl154h_rom.c
new file mode 100644
index 0000000..ad0c33d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/devices/hard-rf430frl154h_rom.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-mmcu=rf430frl154h_rom" } */
+/* { dg-warning "does not have hardware multiply" "" { target msp430_hwmul_not_none } 0 } */
+/* { dg-warning "supports 430 ISA but" "" { target msp430_430x_selected } 0 } */
+/* { dg-error "'-mlarge' requires a 430X-compatible '-mmcu='" "" { target msp430_mlarge_selected } 0 } */
+
+/* revision=0, hwmpy=0 */
+#include "../devices-main.c"
diff --git a/gcc/testsuite/gcc.target/msp430/msp430.exp b/gcc/testsuite/gcc.target/msp430/msp430.exp
index 50620e9..b97f4dc 100644
--- a/gcc/testsuite/gcc.target/msp430/msp430.exp
+++ b/gcc/testsuite/gcc.target/msp430/msp430.exp
@@ -18,7 +18,99 @@
# Exit immediately if this isn't the right target.
if { ![istarget msp430-*-*] } then {
- return
+ return
+}
+
+# Below are msp430-specific effective target keywords, required for checking
+# device related warnings/errors
+proc check_effective_target_msp430_430_selected { } {
+ return [check-flags [list "" { *-*-* } { "-mcpu=msp430" } { "" } ]]
+}
+
+proc check_effective_target_msp430_430x_selected { } {
+ return [check-flags [list "" { *-*-* } \
+ { "-mcpu=msp430x" "-mcpu=msp430xv2" } { "" } ]]
+}
+
+proc check_effective_target_msp430_mlarge_selected { } {
+ return [check-flags [list "" { *-*-* } { "-mlarge" } { "" } ]]
+}
+
+proc check_effective_target_msp430_hwmul_not_none { } {
+ return [check-flags [list "" { *-*-* } \
+ { "-mhwmult=16bit" "-mhwmult=32bit" "-mhwmult=f5series" } { "" } ]]
+}
+
+proc check_effective_target_msp430_hwmul_not_16bit { } {
+ return [check-flags [list "" { *-*-* } \
+ { "-mhwmult=f5series" "-mhwmult=32bit" } { "" } ]]
+}
+
+proc check_effective_target_msp430_hwmul_not_32bit { } {
+ return [check-flags [list "" { *-*-* } \
+ { "-mhwmult=16bit" "-mhwmult=f5series" } { "" } ]]
+}
+
+proc check_effective_target_msp430_hwmul_not_f5 { } {
+ return [check-flags [list "" { *-*-* } \
+ { "-mhwmult=16bit" "-mhwmult=32bit" } { "" } ]]
+}
+
+# Return a list of msp430-specific options we can run the test with.
+# The mcu name is extracted from the file name, not from the -mmcu option
+# specified in the test file.
+proc msp430_get_opts { test_file } {
+ global board_info
+ # If the mcu name is not recognized, run the test as normal without
+ # additional options.
+ if { ![regexp {[a-z0-9]+430[a-z0-9_]+(?=\.c)} $test_file mcu_name] } {
+ return { "" }
+ }
+ # If the testsuite has been invoked with specific MSP430 options, don't run
+ # in this torture style.
+ set multi_flags [board_info [target_info name] multilib_flags]
+ if { [string match "*mlarge*" $multi_flags]
+ || [string match "*msmall*" $multi_flags]
+ || [string match "*mcpu*" $multi_flags]
+ || [string match "*mmcu*" $multi_flags]
+ || [string match "*mhwmult*" $multi_flags] } {
+ return { "" }
+ }
+ # Test all device related options. The compiler will warn about
+ # incompatibilities, so ensure dg-warning or dg-error directives are set up
+ # in the test sources.
+ return {"" -mhwmult=none -mhwmult=16bit -mhwmult=32bit -mhwmult=f5series \
+ -mcpu=msp430 -mcpu=msp430x -mcpu=msp430xv2 -mlarge}
+}
+
+# Run each test file in 'tests' with every possible value for -mcpu and
+# -mhwmult, and with -mlarge.
+proc msp430_device_permutations_runtest { tests } {
+ # The specific tests being run
+ global runtests
+ global MSP430_DEFAULT_CFLAGS
+ foreach { test_file } $tests {
+ if { ![runtest_file_p $runtests $test_file] } {
+ continue
+ }
+ foreach { mcu_flags } [msp430_get_opts $test_file] {
+ if { [string match "csv-*" [file tail $test_file]] } {
+ # Specify the path to devices.csv for devices/csv-* tests with -I.
+ # Note that the csv-* tests do not have dg-options directives,
+ # they only have dg-additional-options to pass -mmcu. This is
+ # so we can set the path to devices.csv as a "default" flag
+ # with -I, and the path won't show up in the test results
+ # summary. If there were dg-options directives, then these
+ # default flags passed as the 3rd argument to dg-runtest would
+ # not be used.
+ dg-runtest $test_file "$mcu_flags" "-I[file dirname $test_file] $MSP430_DEFAULT_CFLAGS"
+ } elseif { [string match "bad-devices*" [file tail $test_file]] } {
+ dg-runtest $test_file "$mcu_flags" "-mdevices-csv-loc=[file dirname $test_file]/[file tail $test_file]sv $MSP430_DEFAULT_CFLAGS"
+ } else {
+ dg-runtest $test_file "$mcu_flags" "$MSP430_DEFAULT_CFLAGS"
+ }
+ }
+ }
}
# Load support procs.
@@ -42,5 +134,7 @@ dg-init
dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \
"" $MSP430_DEFAULT_CFLAGS
+msp430_device_permutations_runtest [lsort [glob -nocomplain $srcdir/$subdir/devices/*.\[cCS\]]]
+
# All done.
dg-finish
diff --git a/gcc/testsuite/gcc.target/msp430/pr78818-data-region.c b/gcc/testsuite/gcc.target/msp430/pr78818-data-region.c
index 3244c0a..5b0721e 100644
--- a/gcc/testsuite/gcc.target/msp430/pr78818-data-region.c
+++ b/gcc/testsuite/gcc.target/msp430/pr78818-data-region.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-mdata-region=either" } */
+/* { dg-skip-if "" { *-*-* } { "-mcpu=msp430" } { "" } } */
+/* { dg-options "-mlarge -mdata-region=either" } */
/* { dg-final { scan-assembler-not "\\.either\\.data" } } */
/* { dg-final { scan-assembler-not "\\.either\\.bss" } } */
diff --git a/gcc/testsuite/gcc.target/msp430/pr80993.c b/gcc/testsuite/gcc.target/msp430/pr80993.c
index 4da5cf9..6cea2b8 100644
--- a/gcc/testsuite/gcc.target/msp430/pr80993.c
+++ b/gcc/testsuite/gcc.target/msp430/pr80993.c
@@ -1,6 +1,7 @@
/* { dg-do link } */
/* { dg-options "--save-temps -msim -flto -Os" } */
/* { dg-final { scan-file "pr80993.exe.ltrans0.s" no_ref_handler } } */
+/* { dg-final { cleanup-saved-temps } } */
void __attribute__((interrupt)) no_ref_handler (void)
{
diff --git a/gcc/testsuite/gcc.target/msp430/region-attribute-misuse.c b/gcc/testsuite/gcc.target/msp430/region-attribute-misuse.c
new file mode 100644
index 0000000..fe4617b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/region-attribute-misuse.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-mcpu=msp430" "-mlarge" "-mcode-region=*" "-mdata-region=*" } { "" } } */
+/* { dg-final { scan-assembler-not ".section.*bss" } } */
+/* { dg-final { scan-assembler ".section.*upper.data" } } */
+/* { dg-final { scan-assembler ".section.*lower.data" } } */
+/* { dg-final { scan-assembler ".section.*either.data" } } */
+
+int __attribute__((upper)) upper_bss; /* { dg-warning "'upper' attribute ignored. large memory model .'-mlarge'. is required" } */
+int __attribute__((lower)) lower_bss; /* { dg-warning "'lower' attribute ignored. large memory model .'-mlarge'. is required" } */
+int __attribute__((either)) either_bss; /* { dg-warning "'either' attribute ignored. large memory model .'-mlarge'. is required" } */
+
+/* Verify that even without -mlarge, objects can still be placed in
+ upper/lower/either regions manually. */
+int __attribute__((section(".upper.data"))) upper_data = 1;
+int __attribute__((section(".lower.data"))) lower_data = 2;
+int __attribute__((section(".either.data"))) either_data = 3;
diff --git a/gcc/testsuite/gcc.target/msp430/region-misuse-code-data.c b/gcc/testsuite/gcc.target/msp430/region-misuse-code-data.c
new file mode 100644
index 0000000..72a160d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/region-misuse-code-data.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-mlarge" } { "" } } */
+/* { dg-options "-mcode-region=either -mdata-region=none" } */
+/* { dg-error "-mcode-region and -mdata-region require the large memory model .-mlarge." "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.target/msp430/region-misuse-code.c b/gcc/testsuite/gcc.target/msp430/region-misuse-code.c
new file mode 100644
index 0000000..6441b77
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/region-misuse-code.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-mlarge" "-mdata-region=*" } { "" } } */
+/* { dg-options "-mcode-region=lower" } */
+/* { dg-error "-mcode-region requires the large memory model .-mlarge." "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.target/msp430/region-misuse-data.c b/gcc/testsuite/gcc.target/msp430/region-misuse-data.c
new file mode 100644
index 0000000..07523b6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/msp430/region-misuse-data.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "-mlarge" "-mdata-region=*" } { "" } } */
+/* { dg-options "-mdata-region=upper" } */
+/* { dg-error "-mdata-region requires the large memory model .-mlarge." "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.target/powerpc/bmi2-bzhi64-1a.c b/gcc/testsuite/gcc.target/powerpc/bmi2-bzhi64-1a.c
index 149cbc5..89bee61 100644
--- a/gcc/testsuite/gcc.target/powerpc/bmi2-bzhi64-1a.c
+++ b/gcc/testsuite/gcc.target/powerpc/bmi2-bzhi64-1a.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3" } */
+/* { dg-options "-O3 -maltivec -mvsx" } */
/* { dg-require-effective-target lp64 } */
#define NO_WARN_X86_INTRINSICS 1
diff --git a/gcc/testsuite/gcc.target/powerpc/direct-move.h b/gcc/testsuite/gcc.target/powerpc/direct-move.h
index e29f10f..80874ad 100644
--- a/gcc/testsuite/gcc.target/powerpc/direct-move.h
+++ b/gcc/testsuite/gcc.target/powerpc/direct-move.h
@@ -179,7 +179,7 @@ main (void)
for (j = 0; j < 10; j++)
{
for (i = 0; i < sizeof (TYPE); i++)
- u.bytes[i] = (unsigned char) (random () >> 4);
+ u.bytes[i] = (unsigned char) (rand () >> 4);
test_value (u.value);
}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-rotate-1.c b/gcc/testsuite/gcc.target/powerpc/vec-rotate-1.c
new file mode 100644
index 0000000..6fe9627
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-rotate-1.c
@@ -0,0 +1,39 @@
+/* { dg-options "-O3 -maltivec" } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+
+/* Check vectorizer can exploit vector rotation instructions on Power, mainly
+ for the case rotation count is const number.
+
+ Check for instructions vrlb/vrlh/vrlw only available if altivec supported. */
+
+#define N 256
+unsigned int suw[N], ruw[N];
+unsigned short suh[N], ruh[N];
+unsigned char sub[N], rub[N];
+
+void
+testUW ()
+{
+ for (int i = 0; i < 256; ++i)
+ ruw[i] = (suw[i] >> 8) | (suw[i] << (sizeof (suw[0]) * 8 - 8));
+}
+
+void
+testUH ()
+{
+ for (int i = 0; i < 256; ++i)
+ ruh[i] = (unsigned short) (suh[i] >> 9)
+ | (unsigned short) (suh[i] << (sizeof (suh[0]) * 8 - 9));
+}
+
+void
+testUB ()
+{
+ for (int i = 0; i < 256; ++i)
+ rub[i] = (unsigned char) (sub[i] >> 5)
+ | (unsigned char) (sub[i] << (sizeof (sub[0]) * 8 - 5));
+}
+
+/* { dg-final { scan-assembler {\mvrlw\M} } } */
+/* { dg-final { scan-assembler {\mvrlh\M} } } */
+/* { dg-final { scan-assembler {\mvrlb\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-rotate-2.c b/gcc/testsuite/gcc.target/powerpc/vec-rotate-2.c
new file mode 100644
index 0000000..2359895
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-rotate-2.c
@@ -0,0 +1,18 @@
+/* { dg-options "-O3 -mdejagnu-cpu=power8" } */
+
+/* Check vectorizer can exploit vector rotation instructions on Power8, mainly
+ for the case rotation count is const number.
+
+ Check for vrld which is available on Power8 and above. */
+
+#define N 256
+unsigned long long sud[N], rud[N];
+
+void
+testULL ()
+{
+ for (int i = 0; i < 256; ++i)
+ rud[i] = (sud[i] >> 8) | (sud[i] << (sizeof (sud[0]) * 8 - 8));
+}
+
+/* { dg-final { scan-assembler {\mvrld\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-rotate-3.c b/gcc/testsuite/gcc.target/powerpc/vec-rotate-3.c
new file mode 100644
index 0000000..3730562
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-rotate-3.c
@@ -0,0 +1,40 @@
+/* { dg-options "-O3 -maltivec" } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+
+/* Check vectorizer can exploit vector rotation instructions on Power, mainly
+ for the case rotation count isn't const number.
+
+ Check for instructions vrlb/vrlh/vrlw only available if altivec supported. */
+
+#define N 256
+unsigned int suw[N], ruw[N];
+unsigned short suh[N], ruh[N];
+unsigned char sub[N], rub[N];
+extern unsigned char rot_cnt;
+
+void
+testUW ()
+{
+ for (int i = 0; i < 256; ++i)
+ ruw[i] = (suw[i] >> rot_cnt) | (suw[i] << (sizeof (suw[0]) * 8 - rot_cnt));
+}
+
+void
+testUH ()
+{
+ for (int i = 0; i < 256; ++i)
+ ruh[i] = (unsigned short) (suh[i] >> rot_cnt)
+ | (unsigned short) (suh[i] << (sizeof (suh[0]) * 8 - rot_cnt));
+}
+
+void
+testUB ()
+{
+ for (int i = 0; i < 256; ++i)
+ rub[i] = (unsigned char) (sub[i] >> rot_cnt)
+ | (unsigned char) (sub[i] << (sizeof (sub[0]) * 8 - rot_cnt));
+}
+
+/* { dg-final { scan-assembler {\mvrlw\M} } } */
+/* { dg-final { scan-assembler {\mvrlh\M} } } */
+/* { dg-final { scan-assembler {\mvrlb\M} } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-rotate-4.c b/gcc/testsuite/gcc.target/powerpc/vec-rotate-4.c
new file mode 100644
index 0000000..75f08f0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-rotate-4.c
@@ -0,0 +1,19 @@
+/* { dg-options "-O3 -mdejagnu-cpu=power8" } */
+
+/* Check vectorizer can exploit vector rotation instructions on Power8, mainly
+ for the case rotation count isn't const number.
+
+ Check for vrld which is available on Power8 and above. */
+
+#define N 256
+unsigned long long sud[N], rud[N];
+extern unsigned char rot_cnt;
+
+void
+testULL ()
+{
+ for (int i = 0; i < 256; ++i)
+ rud[i] = (sud[i] >> rot_cnt) | (sud[i] << (sizeof (sud[0]) * 8 - rot_cnt));
+}
+
+/* { dg-final { scan-assembler {\mvrld\M} } } */
diff --git a/gcc/testsuite/gcc.target/riscv/attribute-10.c b/gcc/testsuite/gcc.target/riscv/attribute-10.c
new file mode 100644
index 0000000..a874a62
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/attribute-10.c
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=rv32i -march=rv32im_s_sx_unexpectedstring -mabi=ilp32" } */
+int foo()
+{
+}
+/* { dg-error "unexpected ISA string at end:" "" { target { "riscv*-*-*" } } 0 } */
diff --git a/gcc/testsuite/gcc.target/riscv/flattened-struct-abi-1.c b/gcc/testsuite/gcc.target/riscv/flattened-struct-abi-1.c
new file mode 100644
index 0000000..f6a3c51
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/flattened-struct-abi-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc -mabi=ilp32d" } */
+struct s1 { int : 0; float f; int i; int : 0; };
+
+void dummy(float, int);
+
+void f(struct s1 s) { /* { dg-warning "flattened struct" } */
+ dummy(s.f + 1.0, s.i + 1);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/flattened-struct-abi-2.c b/gcc/testsuite/gcc.target/riscv/flattened-struct-abi-2.c
new file mode 100644
index 0000000..760826a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/flattened-struct-abi-2.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-march=rv32gc -mabi=ilp32d" } */
+struct s1 { int : 0; float f; float g; int : 0; };
+
+void dummy(float, float);
+
+void f(struct s1 s) { /* { dg-warning "flattened struct" } */
+ dummy(s.f + 1.0, s.g + 2.0);
+}
diff --git a/gcc/testsuite/gcc.target/riscv/pr91441.c b/gcc/testsuite/gcc.target/riscv/pr91441.c
new file mode 100644
index 0000000..593a297
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/pr91441.c
@@ -0,0 +1,10 @@
+/* PR target/91441 */
+/* { dg-do compile } */
+/* { dg-options "--param asan-stack=1 -fsanitize=kernel-address" } */
+
+int *bar(int *);
+int *f( int a)
+{
+ return bar(&a);
+}
+/* { dg-warning ".'-fsanitize=address' and '-fsanitize=kernel-address' are not supported for this target" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.target/riscv/promote-type-for-libcall.c b/gcc/testsuite/gcc.target/riscv/promote-type-for-libcall.c
new file mode 100644
index 0000000..bdbcbc0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/riscv/promote-type-for-libcall.c
@@ -0,0 +1,37 @@
+/* { dg-do run } */
+/* { dg-options "-O1 -ftree-slp-vectorize -funroll-loops" } */
+
+#include <stdio.h>
+#include <stdlib.h>
+#define N 4
+volatile float f[N];
+int x[N] __attribute__((aligned(8)));
+int main() {
+ int i;
+ x[0] = -1;
+ x[1] = 2;
+ x[2] = -2;
+ x[3] = 2;
+
+ for (i=0;i<N;++i){
+ f[i] = x[i];
+ }
+
+ if (f[0] != -1.0f) {
+ abort();
+ }
+
+ if (f[1] != 2.0f) {
+ abort();
+ }
+
+ if (f[2] != -2.0f) {
+ abort();
+ }
+
+ if (f[3] != 2.0f) {
+ abort();
+ }
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/s390/addsub-signed-overflow-1.c b/gcc/testsuite/gcc.target/s390/addsub-signed-overflow-1.c
new file mode 100644
index 0000000..367dbcb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/addsub-signed-overflow-1.c
@@ -0,0 +1,81 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -mzarch --save-temps" } */
+
+#include <stddef.h>
+#include <limits.h>
+
+int __attribute__((noinline,noclone))
+sadd (int a, int b, int *res)
+{
+ return __builtin_sadd_overflow(a, b, res);
+}
+
+int __attribute__((noinline,noclone))
+ssub (int a, int b, int *res)
+{
+ return __builtin_ssub_overflow(a, b, res);
+}
+
+
+int __attribute__((noinline,noclone))
+saddl (long a, long b, long *res)
+{
+ return __builtin_saddl_overflow(a, b, res);
+}
+
+int __attribute__((noinline,noclone))
+ssubl (long a, long b, long *res)
+{
+ return __builtin_ssubl_overflow(a, b, res);
+}
+
+
+int __attribute__((noinline,noclone))
+saddll (long long a, long long b, long long *res)
+{
+ return __builtin_saddll_overflow(a, b, res);
+}
+
+int __attribute__((noinline,noclone))
+ssubll (long long a, long long b, long long *res)
+{
+ return __builtin_ssubll_overflow(a, b, res);
+}
+
+
+/* With the attribute at least main always uses the same instructions
+ regardless of the -march setting. This is necessary for the
+ scan-assembler-times directive below. */
+int __attribute__ ((target("arch=z10")))
+main ()
+{
+ int ret = 0;
+ int result;
+ long lresult;
+ long long llresult;
+
+ ret += !!sadd (INT_MAX, 1, &result);
+ ret += !!ssub (INT_MIN, 1, &result);
+ ret += !!saddl (LONG_MAX, 1, &lresult);
+ ret += !!ssubl (LONG_MIN, 1, &lresult);
+ ret += !!saddll (LLONG_MAX, 1, &llresult);
+ ret += !!ssubll (LLONG_MIN, 1, &llresult);
+
+ if (ret != 6)
+ __builtin_abort ();
+
+ return 0;
+}
+
+/* Check that no compare or bitop instructions are emitted. */
+/* { dg-final { scan-assembler-not "\tcr" } } */
+/* { dg-final { scan-assembler-not "\txr" } } */
+/* { dg-final { scan-assembler-not "\tnr" } } */
+/* { dg-final { scan-assembler-not "\tcgr" } } */
+/* { dg-final { scan-assembler-not "\txgr" } } */
+/* { dg-final { scan-assembler-not "\tngr" } } */
+/* On 31 bit the long long variants use risbgn to merge the 32 bit
+ regs into a 64 bit reg. */
+/* { dg-final { scan-assembler-not "\trisbg" { target { lp64 } } } } */
+/* Just one for the ret != 6 comparison. */
+/* { dg-final { scan-assembler-times "ci" 1 } } */
diff --git a/gcc/testsuite/gcc.target/s390/addsub-signed-overflow-2.c b/gcc/testsuite/gcc.target/s390/addsub-signed-overflow-2.c
new file mode 100644
index 0000000..230ad4a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/addsub-signed-overflow-2.c
@@ -0,0 +1,80 @@
+/* { dg-do run } */
+/* { dg-options "-O3 -mzarch --save-temps" } */
+
+#include <stddef.h>
+#include <limits.h>
+
+int __attribute__((noinline,noclone))
+sadd (int a, int *res)
+{
+ return __builtin_sadd_overflow(a, -1, res);
+}
+
+int __attribute__((noinline,noclone))
+ssub (int a, int *res)
+{
+ return __builtin_ssub_overflow(a, -1, res);
+}
+
+
+int __attribute__((noinline,noclone))
+saddl (long a, long *res)
+{
+ return __builtin_saddl_overflow(a, -1, res);
+}
+
+int __attribute__((noinline,noclone))
+ssubl (long a, long *res)
+{
+ return __builtin_ssubl_overflow(a, -1, res);
+}
+
+
+int __attribute__((noinline,noclone))
+saddll (long long a, long long *res)
+{
+ return __builtin_saddll_overflow(a, -1, res);
+}
+
+int __attribute__((noinline,noclone))
+ssubll (long long a, long long *res)
+{
+ return __builtin_ssubll_overflow(a, -1, res);
+}
+
+/* With the attribute at least main always uses the same instructions
+ regardless of the -march setting. This is necessary for the
+ scan-assembler-times directive below. */
+int __attribute__ ((target("arch=z10")))
+main ()
+{
+ int ret = 0;
+ int result;
+ long lresult;
+ long long llresult;
+
+ ret += !!sadd (INT_MIN, &result);
+ ret += !!ssub (INT_MIN, &result);
+ ret += !!saddl (LONG_MIN, &lresult);
+ ret += !!ssubl (LONG_MIN, &lresult);
+ ret += !!saddll (LLONG_MIN, &llresult);
+ ret += !!ssubll (LLONG_MIN, &llresult);
+
+ if (ret != 3)
+ __builtin_abort ();
+
+ return 0;
+}
+
+/* Check that no compare or bitop instructions are emitted. */
+/* { dg-final { scan-assembler-not "\tcr" } } */
+/* { dg-final { scan-assembler-not "\txr" } } */
+/* { dg-final { scan-assembler-not "\tnr" } } */
+/* { dg-final { scan-assembler-not "\tcgr" } } */
+/* { dg-final { scan-assembler-not "\txgr" } } */
+/* { dg-final { scan-assembler-not "\tngr" } } */
+/* On 31 bit the long long variants use risbgn to merge the 32 bit
+ regs into a 64 bit reg. */
+/* { dg-final { scan-assembler-not "\trisbg" { target { lp64 } } } } */
+/* Just one for the ret != 3 comparison. */
+/* { dg-final { scan-assembler-times "ci" 1 } } */
diff --git a/gcc/testsuite/gcc.target/s390/mul-signed-overflow-1.c b/gcc/testsuite/gcc.target/s390/mul-signed-overflow-1.c
new file mode 100644
index 0000000..b3db60f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/mul-signed-overflow-1.c
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+/* z14 only because we need msrkc, msc, msgrkc, msgc */
+/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+
+#include <stddef.h>
+#include <limits.h>
+
+int __attribute__((noinline,noclone))
+smul (int a, int b, int *res)
+{
+ return __builtin_smul_overflow(a, b, res);
+}
+
+int __attribute__((noinline,noclone))
+smull (long a, long b, long *res)
+{
+ return __builtin_smull_overflow(a, b, res);
+}
+
+int __attribute__((noinline,noclone))
+smulll (long long a, long long b, long long *res)
+{
+ return __builtin_smulll_overflow(a, b, res);
+}
+
+
+int
+main ()
+{
+ int ret = 0;
+ int result;
+ long lresult;
+ long long llresult;
+
+ ret += !!smul (INT_MAX, 2, &result);
+ ret += !!smull (LONG_MAX, 2, &lresult);
+ ret += !!smulll (LLONG_MAX, 2, &llresult);
+
+ if (ret != 3)
+ __builtin_abort ();
+
+ return 0;
+}
+
+/* Check that no compare or bitop instructions are emitted. */
+/* { dg-final { scan-assembler-not "\tcr" } } */
+/* { dg-final { scan-assembler-not "\txr" } } */
+/* { dg-final { scan-assembler-not "\tnr" } } */
+/* { dg-final { scan-assembler-not "\tcgr" } } */
+/* { dg-final { scan-assembler-not "\txgr" } } */
+/* { dg-final { scan-assembler-not "\tngr" } } */
+/* On 31 bit the long long variants use risbgn to merge the 32 bit
+ regs into a 64 bit reg. */
+/* { dg-final { scan-assembler-not "\trisbg" { target { lp64 } } } } */
+/* Just one for the ret != 3 comparison. */
+/* { dg-final { scan-assembler-times "ci" 1 } } */
diff --git a/gcc/testsuite/gcc.target/s390/mul-signed-overflow-2.c b/gcc/testsuite/gcc.target/s390/mul-signed-overflow-2.c
new file mode 100644
index 0000000..76b3fa6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/mul-signed-overflow-2.c
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+/* z14 only because we need msrkc, msc, msgrkc, msgc */
+/* { dg-options "-O3 -march=z14 -mzarch --save-temps" } */
+
+#include <stddef.h>
+#include <limits.h>
+
+int __attribute__((noinline,noclone))
+smul (int a, int *res)
+{
+ return __builtin_smul_overflow(a, -1, res);
+}
+
+int __attribute__((noinline,noclone))
+smull (long a, long *res)
+{
+ return __builtin_smull_overflow(a, -1, res);
+}
+
+int __attribute__((noinline,noclone))
+smulll (long long a, long long *res)
+{
+ return __builtin_smulll_overflow(a, -1, res);
+}
+
+
+int
+main ()
+{
+ int ret = 0;
+ int result;
+ long lresult;
+ long long llresult;
+
+ ret += !!smul (INT_MIN, &result);
+ ret += !!smull (LONG_MIN, &lresult);
+ ret += !!smulll (LLONG_MIN, &llresult);
+
+ if (ret != 3)
+ __builtin_abort ();
+
+ return 0;
+}
+
+/* Check that no compare or bitop instructions are emitted. */
+/* { dg-final { scan-assembler-not "\tcr" } } */
+/* { dg-final { scan-assembler-not "\txr" } } */
+/* { dg-final { scan-assembler-not "\tnr" } } */
+/* { dg-final { scan-assembler-not "\tcgr" } } */
+/* { dg-final { scan-assembler-not "\txgr" } } */
+/* { dg-final { scan-assembler-not "\tngr" } } */
+/* On 31 bit the long long variants use risbgn to merge the 32 bit
+ regs into a 64 bit reg. */
+/* { dg-final { scan-assembler-not "\trisbg" { target { lp64 } } } } */
+/* Just one for the ret != 3 comparison. */
+/* { dg-final { scan-assembler-times "ci" 1 } } */
diff --git a/gcc/testsuite/gcc.target/sh/pr54236-6.c b/gcc/testsuite/gcc.target/sh/pr54236-6.c
index cc47792..93bfeb3 100644
--- a/gcc/testsuite/gcc.target/sh/pr54236-6.c
+++ b/gcc/testsuite/gcc.target/sh/pr54236-6.c
@@ -9,7 +9,7 @@
*/
/* { dg-do compile } */
-/* { dg-options "-O2" } */
+/* { dg-options "-O2 -fno-tree-forwprop" } */
/* { dg-final { scan-assembler-times {tst #1,r0} 1 } } */
/* { dg-final { scan-assembler-times {subc r} 1 } } */
diff --git a/gcc/testsuite/gcc.target/sparc/setjmp-1.c b/gcc/testsuite/gcc.target/sparc/setjmp-1.c
index d0fecb3..699d7f7 100644
--- a/gcc/testsuite/gcc.target/sparc/setjmp-1.c
+++ b/gcc/testsuite/gcc.target/sparc/setjmp-1.c
@@ -4,9 +4,9 @@
/* { dg-do run { target *-*-solaris2.* *-*-linux* *-*-*bsd* } } */
/* { dg-require-effective-target fpic } */
/* { dg-options "-fPIC" } */
+/* { dg-require-effective-target alloca } */
#include <stdio.h>
-#include <alloca.h>
#include <setjmp.h>
#include <string.h>
#include <stdlib.h>
@@ -26,7 +26,7 @@ int main (void)
{
setjmp (jb);
- char *p = alloca (256);
+ char *p = __builtin_alloca (256);
memset (p, 0, 256);
sprintf (p, "%d\n", foo);
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/gen.cc b/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/gen.cc
index 7015314..818a887 100644
--- a/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/gen.cc
+++ b/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/gen.cc
@@ -291,7 +291,7 @@ void fn::print_def (ostream &out) const
if (get_msabi () && get_alloca ())
{
const char *size_str = m_args.empty () ? "42" : "a";
- out << " void *alloca_mem = alloca (8 + " << size_str << ");" << endl
+ out << " void *alloca_mem = __builtin_alloca (8 + " << size_str << ");" << endl
<< " *(long*)alloca_mem = FLAG_ALLOCA;" << endl;
}
if (get_msabi () && get_varargs ())
diff --git a/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/ms-sysv.c b/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/ms-sysv.c
index 5fdd1e2..abfcee6 100644
--- a/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/ms-sysv.c
+++ b/gcc/testsuite/gcc.target/x86_64/abi/ms-sysv/ms-sysv.c
@@ -49,6 +49,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
/* { dg-do run } */
/* { dg-additional-sources "do-test.S" } */
/* { dg-additional-options "-Wall" } */
+/* { dg-require-effective-target alloca } */
#include <stdio.h>
#include <string.h>
@@ -56,7 +57,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include <signal.h>
#include <unistd.h>
#include <stdint.h>
-#include <alloca.h>
#include <stdarg.h>
#include <assert.h>
#include <errno.h>
diff --git a/gcc/testsuite/gdc.dg/pr90601.d b/gcc/testsuite/gdc.dg/pr90601.d
new file mode 100644
index 0000000..88cdaf8c
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr90601.d
@@ -0,0 +1,22 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90601
+// { dg-do compile }
+
+int postincr(int a)
+{
+ return (a += 1.0)++;
+}
+
+int postdecr(int a)
+{
+ return (a -= 1.0)--;
+}
+
+int preincr(int a)
+{
+ return ++(a += 1.0);
+}
+
+int predecr(int a)
+{
+ return --(a -= 1.0);
+}
diff --git a/gcc/testsuite/gdc.dg/pr91238.d b/gcc/testsuite/gdc.dg/pr91238.d
new file mode 100644
index 0000000..26efb90
--- /dev/null
+++ b/gcc/testsuite/gdc.dg/pr91238.d
@@ -0,0 +1,18 @@
+// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91238
+// { dg-do compile }
+
+alias T = const(char)*;
+
+T name()
+{
+ return "";
+}
+
+void collect(ref T)
+{
+}
+
+void configure(T[T] targets)
+{
+ collect(targets[name]);
+}
diff --git a/gcc/testsuite/gfortran.dg/achar_5.f90 b/gcc/testsuite/gfortran.dg/achar_5.f90
index c4f78c0..498c6e3 100644
--- a/gcc/testsuite/gfortran.dg/achar_5.f90
+++ b/gcc/testsuite/gfortran.dg/achar_5.f90
@@ -37,9 +37,4 @@ program test
print *, char(huge(0_8),kind=4) ! { dg-error "too large for the collating sequence" }
print *, achar(huge(0_8),kind=4) ! { dg-error "too large for the collating sequence" }
- print *, char(z'FFFFFFFF', kind=4)
- print *, achar(z'FFFFFFFF', kind=4)
- print *, char(z'100000000', kind=4) ! { dg-error "too large for the collating sequence" }
- print *, achar(z'100000000', kind=4) ! { dg-error "too large for the collating sequence" }
-
end program test
diff --git a/gcc/testsuite/gfortran.dg/allocated_1.f90 b/gcc/testsuite/gfortran.dg/allocated_1.f90
new file mode 100644
index 0000000..43260c2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/allocated_1.f90
@@ -0,0 +1,24 @@
+! { dg-do run }
+program foo
+
+ implicit none
+
+ integer, allocatable :: x
+ integer, allocatable :: a(:)
+
+ logical a1, a2
+
+ a1 = allocated(scalar=x)
+ if (a1 .neqv. .false.) stop 1
+ a2 = allocated(array=a)
+ if (a2 .neqv. .false.) stop 2
+
+ allocate(x)
+ allocate(a(2))
+
+ a1 = allocated(scalar=x)
+ if (a1 .neqv. .true.) stop 3
+ a2 = allocated(array=a)
+ if (a2 .neqv. .true.) stop 4
+
+end program foo
diff --git a/gcc/testsuite/gfortran.dg/allocated_2.f90 b/gcc/testsuite/gfortran.dg/allocated_2.f90
new file mode 100644
index 0000000..0ea186a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/allocated_2.f90
@@ -0,0 +1,16 @@
+! { dg-do compile }
+program foo
+
+ implicit none
+
+ integer, allocatable :: x
+ integer, allocatable :: a(:)
+
+ logical a1, a2
+
+ a1 = allocated(scalar=a) ! { dg-error "Scalar entity required" }
+ a2 = allocated(array=x) ! { dg-error "Array entity required" }
+ a1 = allocated(scalar=x, array=a) ! { dg-error "Too many arguments" }
+ a1 = allocated(array=a, scalar=x) ! { dg-error "Too many arguments" }
+
+end program foo
diff --git a/gcc/testsuite/gfortran.dg/altreturn_10.f90 b/gcc/testsuite/gfortran.dg/altreturn_10.f90
index 7e5d569..a388c3c 100644
--- a/gcc/testsuite/gfortran.dg/altreturn_10.f90
+++ b/gcc/testsuite/gfortran.dg/altreturn_10.f90
@@ -14,6 +14,6 @@ subroutine sub (x)
end
subroutine sub2
call sub (*99) ! { dg-error "Unexpected alternate return specifier" }
- call sub (99.) ! { dg-warning "Type mismatch in argument" }
+ call sub (99.) ! { dg-error "Type mismatch in argument" }
99 stop
end
diff --git a/gcc/testsuite/gfortran.dg/argument_checking_19.f90 b/gcc/testsuite/gfortran.dg/argument_checking_19.f90
new file mode 100644
index 0000000..4460226
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/argument_checking_19.f90
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! PR 91443 - this was not caught.
+module x
+contains
+ subroutine a
+ call foo(1) ! { dg-error "Type mismatch in argument" }
+ end subroutine a
+end module x
+
+subroutine foo(a)
+ real :: a
+ print *,a
+end subroutine foo
+
+program main
+ use x
+ call a
+end program main
diff --git a/gcc/testsuite/gfortran.dg/arithmetic_overflow_1.f90 b/gcc/testsuite/gfortran.dg/arithmetic_overflow_1.f90
index b19844f..95b15a8 100644
--- a/gcc/testsuite/gfortran.dg/arithmetic_overflow_1.f90
+++ b/gcc/testsuite/gfortran.dg/arithmetic_overflow_1.f90
@@ -3,8 +3,10 @@
!
! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
!
+! In F2008 and F2018, overflow cannot happen, but a BOZ cannot appear
+! in an array constructor.
+!
program bug
implicit none
- integer(1) :: a(2) = (/ Z'FF', Z'FF' /) ! { dg-error "Arithmetic overflow" }
- print*, a
+ integer(1) :: a(2) = (/ Z'FF', Z'FF' /) ! { dg-error "cannot appear in" }
end program bug
diff --git a/gcc/testsuite/gfortran.dg/auto_in_equiv_1.f90 b/gcc/testsuite/gfortran.dg/auto_in_equiv_1.f90
new file mode 100644
index 0000000..61bfd07
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/auto_in_equiv_1.f90
@@ -0,0 +1,36 @@
+! { dg-compile }
+
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+program test
+ call suba(0)
+ call subb(0)
+ call suba(1)
+
+contains
+ subroutine suba(option)
+ integer, intent(in) :: option
+ integer, automatic :: a ! { dg-error "AUTOMATIC at \\(1\\) is a DEC extension" }
+ integer :: b
+ integer :: c
+ equivalence (a, b)
+ if (option.eq.0) then
+ ! initialise a and c
+ a = 9
+ c = 99
+ if (a.ne.b) stop 1
+ if (loc(a).ne.loc(b)) stop 2
+ else
+ ! a should've been overwritten
+ if (a.eq.9) stop 3
+ end if
+ end subroutine suba
+
+ subroutine subb(dummy)
+ integer, intent(in) :: dummy
+ integer, automatic :: x ! { dg-error "AUTOMATIC at \\(1\\) is a DEC extension" }
+ integer :: y
+ x = 77
+ y = 7
+ end subroutine subb
+
+end program test
diff --git a/gcc/testsuite/gfortran.dg/auto_in_equiv_2.f90 b/gcc/testsuite/gfortran.dg/auto_in_equiv_2.f90
new file mode 100644
index 0000000..406e718
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/auto_in_equiv_2.f90
@@ -0,0 +1,38 @@
+! { dg-run }
+! { dg-options "-fdec-static" }
+
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+
+program test
+ call suba(0)
+ call subb(0)
+ call suba(1)
+
+contains
+ subroutine suba(option)
+ integer, intent(in) :: option
+ integer, automatic :: a
+ integer :: b
+ integer :: c
+ equivalence (a, b)
+ if (option.eq.0) then
+ ! initialise a and c
+ a = 9
+ c = 99
+ if (a.ne.b) stop 1
+ if (loc(a).ne.loc(b)) stop 2
+ else
+ ! a should've been overwritten
+ if (a.eq.9) stop 3
+ end if
+ end subroutine suba
+
+ subroutine subb(dummy)
+ integer, intent(in) :: dummy
+ integer, automatic :: x
+ integer :: y
+ x = 77
+ y = 7
+ end subroutine subb
+
+end program test
diff --git a/gcc/testsuite/gfortran.dg/auto_in_equiv_3.f90 b/gcc/testsuite/gfortran.dg/auto_in_equiv_3.f90
new file mode 100644
index 0000000..c67aa8c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/auto_in_equiv_3.f90
@@ -0,0 +1,63 @@
+! { dg-run }
+! { dg-options "-fdec-static -fno-automatic" }
+
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+
+! Storage is NOT on the static unless explicitly specified using the
+! DEC extension "automatic". The address of the first local variable
+! is used to determine that storage for the automatic local variable
+! is different to that of a local variable with no attributes. The
+! contents of the local variable in suba should be overwritten by the
+! call to subb.
+!
+program test
+ integer :: dummy
+ integer, parameter :: address = kind(loc(dummy))
+ integer(address) :: ad1
+ integer(address) :: ad2
+ integer(address) :: ad3
+ logical :: ok
+
+ call suba(0, ad1)
+ call subb(0, ad2)
+ call suba(1, ad1)
+ call subc(0, ad3)
+ ok = (ad1.eq.ad3).and.(ad1.ne.ad2)
+ if (.not.ok) stop 4
+
+contains
+ subroutine suba(option, addr)
+ integer, intent(in) :: option
+ integer(address), intent(out) :: addr
+ integer, automatic :: a
+ integer :: b
+ equivalence (a, b)
+ addr = loc(a)
+ if (option.eq.0) then
+ ! initialise a and c
+ a = 9
+ if (a.ne.b) stop 1
+ if (loc(a).ne.loc(b)) stop 2
+ else
+ ! a should've been overwritten
+ if (a.eq.9) stop 3
+ end if
+ end subroutine suba
+
+ subroutine subb(dummy, addr)
+ integer, intent(in) :: dummy
+ integer(address), intent(out) :: addr
+ integer :: x
+ addr = loc(x)
+ x = 77
+ end subroutine subb
+
+ subroutine subc(dummy, addr)
+ integer, intent(in) :: dummy
+ integer(address), intent(out) :: addr
+ integer, automatic :: y
+ addr = loc(y)
+ y = 77
+ end subroutine subc
+
+end program test
diff --git a/gcc/testsuite/gfortran.dg/boz_1.f90 b/gcc/testsuite/gfortran.dg/boz_1.f90
index 56aab76..5f9abb3 100644
--- a/gcc/testsuite/gfortran.dg/boz_1.f90
+++ b/gcc/testsuite/gfortran.dg/boz_1.f90
@@ -1,25 +1,25 @@
! { dg-do run }
-! { dg-options "-std=gnu" }
+! { dg-options "-std=gnu -fallow-invalid-boz" }
! Test the boz handling
program boz
implicit none
- integer(1), parameter :: b1 = b'00000001'
- integer(2), parameter :: b2 = b'0101010110101010'
- integer(4), parameter :: b4 = b'01110000111100001111000011110000'
+ integer(1), parameter :: b1 = b'00000001' ! { dg-warning "BOZ literal constant" }
+ integer(2), parameter :: b2 = b'0101010110101010' ! { dg-warning "BOZ literal constant" }
+ integer(4), parameter :: b4 = b'01110000111100001111000011110000' ! { dg-warning "BOZ literal constant" }
integer(8), parameter :: &
- & b8 = b'0111000011110000111100001111000011110000111100001111000011110000'
+ & b8 = b'0111000011110000111100001111000011110000111100001111000011110000' ! { dg-warning "BOZ literal constant" }
- integer(1), parameter :: o1 = o'12'
- integer(2), parameter :: o2 = o'4321'
- integer(4), parameter :: o4 = o'43210765'
- integer(8), parameter :: o8 = o'1234567076543210'
+ integer(1), parameter :: o1 = o'12' ! { dg-warning "BOZ literal constant" }
+ integer(2), parameter :: o2 = o'4321' ! { dg-warning "BOZ literal constant" }
+ integer(4), parameter :: o4 = o'43210765' ! { dg-warning "BOZ literal constant" }
+ integer(8), parameter :: o8 = o'1234567076543210' ! { dg-warning "BOZ literal constant" }
- integer(1), parameter :: z1 = z'a'
- integer(2), parameter :: z2 = z'ab'
- integer(4), parameter :: z4 = z'dead'
- integer(8), parameter :: z8 = z'deadbeef'
+ integer(1), parameter :: z1 = z'a' ! { dg-warning "BOZ literal constant" }
+ integer(2), parameter :: z2 = z'ab' ! { dg-warning "BOZ literal constant" }
+ integer(4), parameter :: z4 = z'dead' ! { dg-warning "BOZ literal constant" }
+ integer(8), parameter :: z8 = z'deadbeef' ! { dg-warning "BOZ literal constant" }
if (z1 /= 10_1) STOP 1
if (z2 /= 171_2) STOP 2
diff --git a/gcc/testsuite/gfortran.dg/boz_11.f90 b/gcc/testsuite/gfortran.dg/boz_11.f90
index 751dc23..c9bae41 100644
--- a/gcc/testsuite/gfortran.dg/boz_11.f90
+++ b/gcc/testsuite/gfortran.dg/boz_11.f90
@@ -12,16 +12,5 @@ program test0
if (cmplx(b'01000000001010010101001111111101',x,4) /= r) STOP 1
if (cmplx(x,b'01000000001010010101001111111101',4) /= z) STOP 2
- if (complex(b'01000000001010010101001111111101',0) /= r) STOP 3
- if (complex(0,b'01000000001010010101001111111101') /= z) STOP 4
-
- !if (cmplx(b'00000000000000000000000000000000&
- ! &01000000001010010101001111111101',x,8) /= rd) STOP 5
- !if (cmplx(x,b'00000000000000000000000000000000&
- ! &01000000001010010101001111111101',8) /= zd) STOP 6
- !if (dcmplx(b'00000000000000000000000000000000&
- ! &01000000001010010101001111111101',x) /= rd) STOP 7
- !if (dcmplx(x,b'00000000000000000000000000000000&
- ! &01000000001010010101001111111101') /= zd) STOP 8
end program test0
diff --git a/gcc/testsuite/gfortran.dg/boz_12.f90 b/gcc/testsuite/gfortran.dg/boz_12.f90
index 4c5c750..60a8952 100644
--- a/gcc/testsuite/gfortran.dg/boz_12.f90
+++ b/gcc/testsuite/gfortran.dg/boz_12.f90
@@ -4,11 +4,8 @@ program test
implicit none
real x4
double precision x8
-
x4 = 1.7
x8 = 1.7
- write(*,*) complex(x4,z'1FFFFFFFF') ! { dg-error "too" }
- write(*,*) cmplx(x8,z'1FFFFFFFFFFFFFFFF') ! { dg-error "too" }
- write(*,*) complex(x8,z'1FFFFFFFFFFFFFFFF') ! { dg-error "too" }
- write(*,*) dcmplx(x8,z'1FFFFFFFFFFFFFFFF') ! { dg-error "too" }
+ write(*,*) cmplx(x8,z'1FFFFFFFFFFFFFFFF')
+ write(*,*) dcmplx(x8,z'1FFFFFFFFFFFFFFFF')
end program test
diff --git a/gcc/testsuite/gfortran.dg/boz_3.f90 b/gcc/testsuite/gfortran.dg/boz_3.f90
index 2bfef00..b3766cc 100644
--- a/gcc/testsuite/gfortran.dg/boz_3.f90
+++ b/gcc/testsuite/gfortran.dg/boz_3.f90
@@ -1,5 +1,6 @@
! { dg-do run }
-! { dg-options "-std=gnu" }
+! { dg-options "-std=gnu -fallow-invalid-boz" }
+!
! Test that the BOZ constant on the RHS, which are of different KIND than
! the LHS, are correctly converted.
!
@@ -7,18 +8,20 @@ program boz
implicit none
- integer(1), parameter :: b1 = b'000000000001111'
- integer(2), parameter :: b2 = b'00000000000000000111000011110000'
+ integer(1), parameter :: &
+ & b1 = b'000000000001111' ! { dg-warning "BOZ literal constant at" }
+ integer(2), parameter :: &
+ & b2 = b'00000000000000000111000011110000' ! { dg-warning "BOZ literal constant at" }
integer(4), parameter :: &
- & b4 = b'0000000000000000000000000000000001110000111100001111000011110000'
+ & b4 = b'0000000000000000000000000000000001110000111100001111000011110000' ! { dg-warning "BOZ literal constant at" }
- integer(1), parameter :: o1 = o'0012'
- integer(2), parameter :: o2 = o'0004321'
- integer(4), parameter :: o4 = o'0000000043210765'
+ integer(1), parameter :: o1 = o'0012' ! { dg-warning "BOZ literal constant at" }
+ integer(2), parameter :: o2 = o'0004321' ! { dg-warning "BOZ literal constant at" }
+ integer(4), parameter :: o4 = o'0000000043210765' ! { dg-warning "BOZ literal constant at" }
- integer(1), parameter :: z1 = z'0a'
- integer(2), parameter :: z2 = z'00ab'
- integer(4), parameter :: z4 = z'0000dead'
+ integer(1), parameter :: z1 = z'0a' ! { dg-warning "BOZ literal constant at" }
+ integer(2), parameter :: z2 = z'00ab' ! { dg-warning "BOZ literal constant at" }
+ integer(4), parameter :: z4 = z'0000dead' ! { dg-warning "BOZ literal constant at" }
if (b1 /= 15_1) STOP 1
if (b2 /= 28912_2) STOP 2
diff --git a/gcc/testsuite/gfortran.dg/boz_4.f90 b/gcc/testsuite/gfortran.dg/boz_4.f90
index d016df2..fbde453 100644
--- a/gcc/testsuite/gfortran.dg/boz_4.f90
+++ b/gcc/testsuite/gfortran.dg/boz_4.f90
@@ -1,29 +1,16 @@
! { dg-do compile }
-! Test that the conversion of a BOZ constant that is too large for the
-! integer variable is caught by the compiler.
+! { dg-options "-fallow-invalid-boz" }
+!
program boz
-
implicit none
-
- integer(1), parameter :: &
- & b1 = b'0101010110101010' ! { dg-error "overflow converting" }
- integer(2), parameter :: &
- & b2 = b'01110000111100001111000011110000' ! { dg-error "overflow converting" }
+ integer(1), parameter :: b1 = b'0101010110101010' ! { dg-warning "BOZ literal constant" }
+ integer(2), parameter :: b2 = b'01110000111100001111000011110000' ! { dg-warning "BOZ literal constant" }
integer(4), parameter :: &
- & b4 = b'0111000011110000111100001111000011110000111100001111000011110000' ! { dg-error "overflow converting" }
-
- integer(1), parameter :: &
- & o1 = o'1234567076543210' ! { dg-error "overflow converting" }
- integer(2), parameter :: &
- & o2 = o'1234567076543210' ! { dg-error "overflow converting" }
- integer(4), parameter :: &
- & o4 = o'1234567076543210' ! { dg-error "overflow converting" }
-
- integer(1), parameter :: &
- & z1 = z'deadbeef' ! { dg-error "overflow converting" }
- integer(2), parameter :: &
- & z2 = z'deadbeef' ! { dg-error "overflow converting" }
- integer(4), parameter :: &
- & z4 = z'deadbeeffeed' ! { dg-error "overflow converting" }
-
+ & b4 = b'0111000011110000111100001111000011110000111100001111000011110000' ! { dg-warning "BOZ literal constant" }
+ integer(1), parameter :: o1 = o'1234567076543210' ! { dg-warning "BOZ literal constant" }
+ integer(2), parameter :: o2 = o'1234567076543210' ! { dg-warning "BOZ literal constant" }
+ integer(4), parameter :: o4 = o'1234567076543210' ! { dg-warning "BOZ literal constant" }
+ integer(1), parameter :: z1 = z'deadbeef' ! { dg-warning "BOZ literal constant" }
+ integer(2), parameter :: z2 = z'deadbeef' ! { dg-warning "BOZ literal constant" }
+ integer(4), parameter :: z4 = z'deadbeeffeed' ! { dg-warning "BOZ literal constant" }
end program boz
diff --git a/gcc/testsuite/gfortran.dg/boz_5.f90 b/gcc/testsuite/gfortran.dg/boz_5.f90
index 3b1994b..f4176b9 100644
--- a/gcc/testsuite/gfortran.dg/boz_5.f90
+++ b/gcc/testsuite/gfortran.dg/boz_5.f90
@@ -1,4 +1,4 @@
! { dg-do compile }
integer, dimension (2) :: i
- i = (/Z'abcde', Z'abcde/) ! { dg-error "Illegal character" }
+ i = (/Z'abcde', Z'abcde/) ! { dg-error "cannot appear in" }
end
diff --git a/gcc/testsuite/gfortran.dg/boz_6.f90 b/gcc/testsuite/gfortran.dg/boz_6.f90
index 379a44f..57a8beb 100644
--- a/gcc/testsuite/gfortran.dg/boz_6.f90
+++ b/gcc/testsuite/gfortran.dg/boz_6.f90
@@ -1,13 +1,13 @@
! { dg-do run }
-! { dg-options "-std=gnu" }
+! { dg-options "-std=gnu -fallow-invalid-boz" }
! PR 24917
program test
integer ib, io, iz, ix
integer jb, jo, jz, jx
- data ib, jb /b'111', '111'b/
- data io, jo /o'234', '234'o/
- data iz, jz /z'abc', 'abc'z/
- data ix, jx /x'abc', 'abc'x/
+ data ib, jb /b'111', '111'b/ ! { dg-warning "nonstandard" }
+ data io, jo /o'234', '234'o/ ! { dg-warning "nonstandard" }
+ data iz, jz /z'abc', 'abc'z/ ! { dg-warning "nonstandard" }
+ data ix, jx /x'abc', 'abc'x/ ! { dg-warning "nonstandard" }
if (ib /= jb) STOP 1
if (io /= jo) STOP 2
if (iz /= jz) STOP 3
diff --git a/gcc/testsuite/gfortran.dg/boz_7.f90 b/gcc/testsuite/gfortran.dg/boz_7.f90
index 348f561..45fa7a7 100644
--- a/gcc/testsuite/gfortran.dg/boz_7.f90
+++ b/gcc/testsuite/gfortran.dg/boz_7.f90
@@ -7,6 +7,6 @@
!
integer :: k, m
integer :: j = z'000abc' ! { dg-error "BOZ used outside a DATA statement" }
-data k/x'0003'/ ! { dg-error "uses non-standard syntax" }
-data m/'0003'z/ ! { dg-error "uses non-standard postfix syntax" }
+data k/x'0003'/ ! { dg-error "nonstandard syntax" }
+data m/'0003'z/ ! { dg-error "nonstandard postfix" }
end
diff --git a/gcc/testsuite/gfortran.dg/boz_8.f90 b/gcc/testsuite/gfortran.dg/boz_8.f90
index effce2d..b1d966f 100644
--- a/gcc/testsuite/gfortran.dg/boz_8.f90
+++ b/gcc/testsuite/gfortran.dg/boz_8.f90
@@ -10,8 +10,9 @@
!
real :: r
integer :: i
-data i/z'111'/, r/z'4455'/ ! { dg-error "BOZ literal at .1. used to initialize non-integer variable 'r'" }
-r = z'FFFF' ! { dg-error "outside a DATA statement" }
-i = z'4455' ! { dg-error "outside a DATA statement" }
-r = real(z'FFFFFFFFF') ! { dg-error "is too large" }
+data i/z'111'/
+data r/z'4455'/ ! { dg-error "BOZ literal constant" }
+r = z'FFFF' ! { dg-error "BOZ literal constant" }
+i = z'4455' ! { dg-error "BOZ literal constant" }
+r = real(z'FFFFFFFFF')
end
diff --git a/gcc/testsuite/gfortran.dg/boz_bge.f90 b/gcc/testsuite/gfortran.dg/boz_bge.f90
new file mode 100644
index 0000000..46891e3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/boz_bge.f90
@@ -0,0 +1,22 @@
+! { dg-do run }
+program foo
+
+ integer :: k = 4242
+
+ if (bge(z'1234', z'5678') .neqv. .false.) stop 1
+ if (bgt(z'1234', z'5678') .neqv. .false.) stop 2
+ if (ble(z'1234', z'5678') .eqv. .false.) stop 3
+ if (blt(z'1234', z'5678') .eqv. .false.) stop 4
+
+ if (bge(z'1234', k) .eqv. .false.) stop 5
+ if (bgt(z'1234', k) .eqv. .false.) stop 6
+ if (ble(z'1234', k) .neqv. .false.) stop 7
+ if (blt(z'1234', k) .neqv. .false.) stop 8
+
+ if (bge(k, z'5678') .neqv. .false.) stop 9
+ if (bgt(k, z'5678') .neqv. .false.) stop 10
+ if (ble(k, z'5678') .eqv. .false.) stop 11
+ if (blt(k, z'5678') .eqv. .false.) stop 12
+
+end program foo
+
diff --git a/gcc/testsuite/gfortran.dg/boz_complex_1.f90 b/gcc/testsuite/gfortran.dg/boz_complex_1.f90
new file mode 100644
index 0000000..e05246a
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/boz_complex_1.f90
@@ -0,0 +1,17 @@
+! { dg-do compile }
+program foo
+
+ implicit none
+
+ complex(4) z
+
+ z = complex(z'4444', z'4444') ! { dg-error "cannot both be BOZ" }
+ if (real(z,4) /= 17476.0 .or. aimag(z) /= 42.0) stop 2
+
+ z = complex(z'4444', 42) ! { dg-error "cannot appear in the" }
+ if (real(z,4) /= 17476.0 .or. aimag(z) /= 42.0) stop 2
+
+ z = complex(z'44444400', 42.) ! { dg-error "cannot appear in the" }
+ if (real(z,4) /= 785.062500 .or. aimag(z) /= 42.0) stop 3
+
+end program foo
diff --git a/gcc/testsuite/gfortran.dg/boz_complex_2.f90 b/gcc/testsuite/gfortran.dg/boz_complex_2.f90
new file mode 100644
index 0000000..345027b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/boz_complex_2.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! { dg-options "-fallow-invalid-boz" }
+program foo
+
+ implicit none
+
+ complex(4) z
+
+ z = complex(z'4444', 42) ! { dg-warning "cannot appear in the" }
+ if (real(z,4) /= 17476.0 .or. aimag(z) /= 42.0) stop 2
+
+ z = complex(z'44444400', 42.) ! { dg-warning "cannot appear in the" }
+ if (real(z,4) /= 785.062500 .or. aimag(z) /= 42.0) stop 3
+
+end program foo
diff --git a/gcc/testsuite/gfortran.dg/boz_complex_3.f90 b/gcc/testsuite/gfortran.dg/boz_complex_3.f90
new file mode 100644
index 0000000..4318a7f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/boz_complex_3.f90
@@ -0,0 +1,15 @@
+! { dg-do run }
+! { dg-options "-fallow-invalid-boz -w" }
+program foo
+
+ implicit none
+
+ complex(4) z
+
+ z = complex(z'4444', 42)
+ if (real(z,4) /= 17476.0 .or. aimag(z) /= 42.0) stop 2
+
+ z = complex(z'44444400', 42.)
+ if (real(z,4) /= 785.062500 .or. aimag(z) /= 42.0) stop 3
+
+end program foo
diff --git a/gcc/testsuite/gfortran.dg/boz_dble.f90 b/gcc/testsuite/gfortran.dg/boz_dble.f90
new file mode 100644
index 0000000..c155243
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/boz_dble.f90
@@ -0,0 +1,6 @@
+! { dg-do run }
+program foo
+ double precision x
+ x = dble(z"400921FB54411744");
+ if (x /= 3.1415926535_8) stop 1
+end
diff --git a/gcc/testsuite/gfortran.dg/boz_dshift_1.f90 b/gcc/testsuite/gfortran.dg/boz_dshift_1.f90
new file mode 100644
index 0000000..ba10315
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/boz_dshift_1.f90
@@ -0,0 +1,10 @@
+! { dg-do compile }
+program foo
+ integer k, n
+ k = dshiftl(z'1234',z'2345',1) ! { dg-error "cannot both be BOZ" }
+ n = dshiftr(z'1234',z'2345',1) ! { dg-error "cannot both be BOZ" }
+ if (k .eq. n) stop 1
+ k = dshiftl(z'1234',3.1415,1) ! { dg-error "must be INTEGER" }
+ n = dshiftr(2.7362,z'2345',1) ! { dg-error "must be INTEGER" }
+ if (k .eq. n) stop 2
+end program foo
diff --git a/gcc/testsuite/gfortran.dg/boz_dshift_2.f90 b/gcc/testsuite/gfortran.dg/boz_dshift_2.f90
new file mode 100644
index 0000000..c2fbd1b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/boz_dshift_2.f90
@@ -0,0 +1,12 @@
+! { dg-do run }
+program foo
+ integer k, n
+ k = dshiftl(z'1234',42,1)
+ n = dshiftr(z'1234',42,1)
+ if (k /= 9320) stop 1
+ if (n /= 21) stop 2
+ k = dshiftl(42,b'01010101', 1)
+ n = dshiftr(22,o'12345', 1)
+ if (k /= 84) stop 1
+ if (n /= 2674) stop 2
+end program foo
diff --git a/gcc/testsuite/gfortran.dg/boz_float_1.f90 b/gcc/testsuite/gfortran.dg/boz_float_1.f90
new file mode 100644
index 0000000..e444b09
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/boz_float_1.f90
@@ -0,0 +1,4 @@
+! { dg-do compile }
+program foo
+ print *, float(z'1234') ! { dg-error "cannot appear in" }
+end program foo
diff --git a/gcc/testsuite/gfortran.dg/boz_float_2.f90 b/gcc/testsuite/gfortran.dg/boz_float_2.f90
new file mode 100644
index 0000000..638dae2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/boz_float_2.f90
@@ -0,0 +1,5 @@
+! { dg-do compile }
+! { dg-options "-fallow-invalid-boz" }
+program foo
+ print *, float(z'1234') ! { dg-warning "cannot appear in" }
+end program foo
diff --git a/gcc/testsuite/gfortran.dg/boz_float_3.f90 b/gcc/testsuite/gfortran.dg/boz_float_3.f90
new file mode 100644
index 0000000..7262495
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/boz_float_3.f90
@@ -0,0 +1,7 @@
+! { dg-do run }
+! { dg-options "-fallow-invalid-boz -w" }
+program foo
+ integer i
+ i = float(z'1234')
+ if (i /= 4660.0) stop 1
+end program foo
diff --git a/gcc/testsuite/gfortran.dg/boz_iand_1.f90 b/gcc/testsuite/gfortran.dg/boz_iand_1.f90
new file mode 100644
index 0000000..45d8c39
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/boz_iand_1.f90
@@ -0,0 +1,10 @@
+! { dg-do compile }
+program foo
+ print *, iand(z'1234', z'3456') ! { dg-error "cannot both be" }
+ print *, and(z'1234', z'3456') ! { dg-error "cannot both be" }
+ print *, ieor(z'1234', z'3456') ! { dg-error "cannot both be" }
+ print *, xor(z'1234', z'3456') ! { dg-error "cannot both be" }
+ print *, ior(z'1234', z'3456') ! { dg-error "cannot both be" }
+ print *, or(z'1234', z'3456') ! { dg-error "cannot both be" }
+end program foo
+
diff --git a/gcc/testsuite/gfortran.dg/boz_iand_2.f90 b/gcc/testsuite/gfortran.dg/boz_iand_2.f90
new file mode 100644
index 0000000..e656ac0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/boz_iand_2.f90
@@ -0,0 +1,17 @@
+! { dg-do run }
+program foo
+ integer :: k = 42
+ n = iand(k, z'3456'); if (n /= 2) stop 1
+ n = iand(z'1234', k); if (n /= 32) stop 2
+ n = and(k, z'3456'); if (n /= 2) stop 3
+ n = and(z'1234', k); if (n /= 32) stop 4
+ n = ieor(k, z'3456'); if (n /= 13436) stop 5
+ n = ieor(z'1234', k); if (n /= 4638) stop 6
+ n = xor(k, z'3456'); if (n /= 13436) stop 7
+ n = xor(z'1234', k); if (n /= 4638) stop 8
+ n = ior(k, z'3456'); if (n /= 13438) stop 9
+ n = ior(z'1234', k); if (n /= 4670) stop 10
+ n = or(k, z'3456'); if (n /= 13438) stop 11
+ n = or(z'1234', k); if (n /= 4670) stop 12
+end program foo
+
diff --git a/gcc/testsuite/gfortran.dg/boz_int.f90 b/gcc/testsuite/gfortran.dg/boz_int.f90
new file mode 100644
index 0000000..79302cd
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/boz_int.f90
@@ -0,0 +1,13 @@
+! { dg-do run }
+program foo
+ implicit none
+ integer(1) i1
+ integer(2) i2
+ integer(4) i4, j4
+ integer(8) i8
+ i1 = int(z'12', 1); if (i1 /= 18) stop 1
+ i2 = int(z'1234', 2); if (i2 /= 4660) stop 2
+ i4 = int(z'1234', 4); if (i4 /= 4660) stop 3
+ j4 = int(z'1234'); if (i4 /= 4660) stop 4
+ i8 = int(z'1233456',8); if (i8 /= 19084374_8) stop 5
+end program
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_6.f90 b/gcc/testsuite/gfortran.dg/dec_structure_6.f90
index 91a4df9..c4cb7e3 100644
--- a/gcc/testsuite/gfortran.dg/dec_structure_6.f90
+++ b/gcc/testsuite/gfortran.dg/dec_structure_6.f90
@@ -1,5 +1,5 @@
! { dg-do run }
-! { dg-options "-fdec-structure" }
+! { dg-options "-fdec-structure -fallow-invalid-boz" }
!
! Test old-style CLIST initializers in STRUCTURE.
!
@@ -21,7 +21,7 @@ structure /s8/
integer o(as) /as*9/ ! ok, parameter array spec
integer p(2,2) /1,2,3,4/! ok
real q(3) /1_2,3.5,2.4E-12_8/ ! ok, with some implicit conversions
- integer :: canary = z'3D3D3D3D'
+ integer :: canary = z'3D3D3D3D' ! { dg-warning "BOZ literal constant" }
end structure
record /s8/ r8
@@ -41,6 +41,6 @@ if ( r8.o(1) /= 9 .or. r8.o(2) /= 9 .or. r8.o(3) /= 9 ) call aborts ("r8.o")
if ( r8.p(1,1) /= 1 .or. r8.p(2,1) /= 2 .or. r8.p(1,2) /= 3 &
.or. r8.p(2,2) /= 4) &
call aborts ("r8.p")
-if ( r8.canary /= z'3D3D3D3D' ) call aborts ("r8.canary")
+if ( r8.canary /= int(z'3D3D3D3D') ) call aborts ("r8.canary")
end
diff --git a/gcc/testsuite/gfortran.dg/dec_union_1.f90 b/gcc/testsuite/gfortran.dg/dec_union_1.f90
index 074782c..689628c 100644
--- a/gcc/testsuite/gfortran.dg/dec_union_1.f90
+++ b/gcc/testsuite/gfortran.dg/dec_union_1.f90
@@ -28,8 +28,8 @@ subroutine sub ()
end union
end structure
record /s6/ r6
- r6.ibuf(1) = z'badbeef'
- r6.ibuf(2) = z'badbeef'
+ r6.ibuf(1) = int(z'badbeef')
+ r6.ibuf(2) = int(z'badbeef')
end subroutine
! Repeat definition from subroutine sub with different size parameter.
@@ -55,7 +55,7 @@ integer :: r6_canary = 0
! Copied type declaration - this should not cause problems
i = 1
do while (i < siz)
- r6.ibuf(i) = z'badbeef'
+ r6.ibuf(i) = int(z'badbeef')
i = i + 1
end do
diff --git a/gcc/testsuite/gfortran.dg/dec_union_11.f90 b/gcc/testsuite/gfortran.dg/dec_union_11.f90
index 3ff4b49..41e23b2 100644
--- a/gcc/testsuite/gfortran.dg/dec_union_11.f90
+++ b/gcc/testsuite/gfortran.dg/dec_union_11.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
-! { dg-options "-g -fdec-structure" }
+! { dg-options "-g -fdec-structure -std=legacy" }
!
! Test a regression where typespecs of unions containing character buffers of
! different lengths where copied, resulting in a bad gimple tree state.
diff --git a/gcc/testsuite/gfortran.dg/dec_union_2.f90 b/gcc/testsuite/gfortran.dg/dec_union_2.f90
index 99db431..4e23955 100644
--- a/gcc/testsuite/gfortran.dg/dec_union_2.f90
+++ b/gcc/testsuite/gfortran.dg/dec_union_2.f90
@@ -31,6 +31,7 @@ structure /s1/
end map
end union
end structure
+
structure /s2/
union ! U2
map ! M4
@@ -51,9 +52,9 @@ r1.b = 1.33e7
if ( r1.a .eq. 0 ) call aborts ("basic union 1")
! Endian-agnostic runtime check
-r2.long = z'12345678'
-if (.not. ( (r2.w1 .eq. z'1234' .and. r2.w2 .eq. z'5678') &
- .or. (r2.w1 .eq. z'5678' .and. r2.w2 .eq. z'1234')) ) then
+r2.long = int(z'12345678')
+if (.not. ( (r2.w1 .eq. int(z'1234',2) .and. r2.w2 .eq. int(z'5678',2)) &
+ .or. (r2.w1 .eq. int(z'5678',2) .and. r2.w2 .eq. int(z'1234',2))) ) then
call aborts ("basic union 2")
endif
diff --git a/gcc/testsuite/gfortran.dg/dec_union_5.f90 b/gcc/testsuite/gfortran.dg/dec_union_5.f90
index f3cca5d..712b9a4 100644
--- a/gcc/testsuite/gfortran.dg/dec_union_5.f90
+++ b/gcc/testsuite/gfortran.dg/dec_union_5.f90
@@ -25,11 +25,11 @@ end structure
record /s5/ r5
! Unions with arrays
-r5.a(1) = z'41'
-r5.a(2) = z'42'
-r5.a(3) = z'43'
-r5.a(4) = z'44'
-r5.a(5) = z'45'
+r5.a(1) = int(z'41',1)
+r5.a(2) = int(z'42',1)
+r5.a(3) = int(z'43',1)
+r5.a(4) =int( z'44',1)
+r5.a(5) = int(z'45',1)
if ( r5.s(1) .ne. 'A' &
.or. r5.s(2) .ne. 'B' &
.or. r5.s(3) .ne. 'C' &
diff --git a/gcc/testsuite/gfortran.dg/deferred_character_34.f90 b/gcc/testsuite/gfortran.dg/deferred_character_34.f90
new file mode 100644
index 0000000..2040841
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/deferred_character_34.f90
@@ -0,0 +1,10 @@
+! { dg-do run }
+! PR fortran/90561
+! This used to ICE.
+! Original test case by Gerhard Steinmetz.
+program p
+ character(:), allocatable :: z(:)
+ z = [character(2):: 'ab', 'xy']
+ z = z(2)
+ if (any(z /= 'xy')) stop 1
+end
diff --git a/gcc/testsuite/gfortran.dg/dependency_54.f90 b/gcc/testsuite/gfortran.dg/dependency_54.f90
new file mode 100644
index 0000000..f738ed8
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dependency_54.f90
@@ -0,0 +1,24 @@
+! { dg-do run }
+! { dg-additional-options "-fdump-tree-original -ffrontend-optimize" }
+! PR 65819 - this used to cause a temporary in matmul inlining.
+! Check that these are absent by looking for the names of the
+! temporary variables.
+program main
+ implicit none
+ real, dimension(3,3,3) :: f
+ real, dimension(3,3) :: res
+ real, dimension(2,3,3) :: backup
+ integer :: three
+ integer :: i
+
+ data f(1,:,:) /9*-42./
+ data f(2:3,:,:) /2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61/
+ data res /652, 772, 984, 2010, 2406, 3082, 3402, 4086, 5242/
+ three = 3
+ backup = f(2:3,:,:)
+ f(1, 1:three, :) = matmul(f(2,1:3,2:3), f(3,2:3,:))
+ if (any (res /= f(1,:,:))) stop 1
+ if (any (f(2:3,:,:) /= backup)) stop 2
+end program main
+! { dg-final { scan-tree-dump-not "mma" "original" } }
+! { dg-final { scan-tree-dump-not "mmb" "original" } }
diff --git a/gcc/testsuite/gfortran.dg/do_subscript_3.f90 b/gcc/testsuite/gfortran.dg/do_subscript_3.f90
new file mode 100644
index 0000000..2f62f58
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/do_subscript_3.f90
@@ -0,0 +1,22 @@
+! { dg-do compile }
+! PR fortran/91424
+! Check that only one warning is issued inside blocks, and that
+! warnings are also issued for contained subroutines.
+
+program main
+ real :: a(5)
+ block
+ integer :: j
+ do j=0, 5 ! { dg-warning "out of bounds" }
+ a(j) = 2. ! { dg-warning "out of bounds" }
+ end do
+ end block
+ call x
+contains
+ subroutine x
+ integer :: i
+ do i=1,6 ! { dg-warning "out of bounds" }
+ a(i) = 2. ! { dg-warning "out of bounds" }
+ end do
+ end subroutine x
+end program main
diff --git a/gcc/testsuite/gfortran.dg/do_subscript_4.f90 b/gcc/testsuite/gfortran.dg/do_subscript_4.f90
new file mode 100644
index 0000000..c773fe7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/do_subscript_4.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! PR 91424 - this used to warn although the DO loop is zero trip.
+program main
+ implicit none
+ integer :: i
+ real :: a(2)
+ do i=1,3,-1
+ a(i) = 2.
+ end do
+ print *,a
+end program main
diff --git a/gcc/testsuite/gfortran.dg/do_subscript_5.f90 b/gcc/testsuite/gfortran.dg/do_subscript_5.f90
new file mode 100644
index 0000000..54a4f1b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/do_subscript_5.f90
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-additional-options "-Wdo-subscript" }
+! PR 90563 - this used to be rejected, wrongly
+! Original test case by Tobias Neumann
+program test
+ implicit none
+ integer, parameter :: swap(4) = [2,1,3,4]
+ real :: p(20)
+ integer :: j
+
+ p = 0.0
+
+ ! The following warnings are actually bogus, but we are not yet
+ ! clever enough to suppress them.
+ do j=1,6 ! { dg-warning "out of bounds" }
+ if (j<5) then
+ p(j) = p(swap(j)) ! { dg-warning "out of bounds" }
+ endif
+ enddo
+end program
diff --git a/gcc/testsuite/gfortran.dg/dshift_3.f90 b/gcc/testsuite/gfortran.dg/dshift_3.f90
index 1f214c7..2ed2840 100644
--- a/gcc/testsuite/gfortran.dg/dshift_3.f90
+++ b/gcc/testsuite/gfortran.dg/dshift_3.f90
@@ -17,7 +17,6 @@ subroutine foo(i, j, k)
print *, dshiftl(i, k, 10) ! { dg-error "must be the same type and kind" }
print *, dshiftl(k, j, 10) ! { dg-error "must be the same type and kind" }
print *, dshiftl(i, j, k)
- print *, dshiftl(i, j, z'd')
print *, dshiftr(i, j, 134) ! { dg-error "must be less than or equal" }
print *, dshiftr(z'FFF', j, 134) ! { dg-error "must be less than or equal" }
@@ -29,6 +28,5 @@ subroutine foo(i, j, k)
print *, dshiftr(i, k, 10) ! { dg-error "must be the same type and kind" }
print *, dshiftr(k, j, 10) ! { dg-error "must be the same type and kind" }
print *, dshiftr(i, j, k)
- print *, dshiftr(i, j, z'd')
end subroutine foo
diff --git a/gcc/testsuite/gfortran.dg/equiv_10.f90 b/gcc/testsuite/gfortran.dg/equiv_10.f90
new file mode 100644
index 0000000..2d6d5c3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/equiv_10.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! PR fortran/90986
+module mymod
+ type :: mytyp
+ integer :: i
+ end type mytyp
+contains
+ subroutine mysub
+ implicit none
+ type(mytyp) :: a
+ integer :: equivalencei,equivalencej
+ equivalencei = a%i
+ equivalencej = a%j ! { dg-error "is not a member of the" }
+ end subroutine mysub
+end module mymod
diff --git a/gcc/testsuite/gfortran.dg/gnu_logical_1.F b/gcc/testsuite/gfortran.dg/gnu_logical_1.F
index 19e368c..e69de29 100644
--- a/gcc/testsuite/gfortran.dg/gnu_logical_1.F
+++ b/gcc/testsuite/gfortran.dg/gnu_logical_1.F
@@ -1,91 +0,0 @@
-! Testcases for the AND, OR and XOR functions (GNU intrinsics).
-! { dg-do run }
-! { dg-options "-ffixed-line-length-none" }
- integer(kind=1) i1, j1
- integer(kind=2) i2, j2
- integer i4, j4
- integer(kind=8) i8, j8
- logical(kind=1) l1, k1
- logical(kind=2) l2, k2
- logical l4, k4
- logical(kind=8) l8, k8
-
-#define TEST_INTEGER(u,ukind,v,vkind) \
- ukind = u;\
- vkind = v;\
- if (iand(u,v) /= and(ukind, vkind)) STOP 1;\
- if (iand(u,v) /= and(vkind, ukind)) STOP 1;\
- if (ieor(u,v) /= xor(ukind, vkind)) STOP 1;\
- if (ieor(u,v) /= xor(vkind, ukind)) STOP 1;\
- if (ior(u,v) /= or(ukind, vkind)) STOP 1;\
- if (ior(u,v) /= or(vkind, ukind)) STOP 1
-
- TEST_INTEGER(19,i1,6,j1)
- TEST_INTEGER(19,i1,6,j2)
- TEST_INTEGER(19,i1,6,j4)
- TEST_INTEGER(19,i1,6,j8)
-
- TEST_INTEGER(19,i2,6,j1)
- TEST_INTEGER(19,i2,6,j2)
- TEST_INTEGER(19,i2,6,j4)
- TEST_INTEGER(19,i2,6,j8)
-
- TEST_INTEGER(19,i4,6,j1)
- TEST_INTEGER(19,i4,6,j2)
- TEST_INTEGER(19,i4,6,j4)
- TEST_INTEGER(19,i4,6,j8)
-
- TEST_INTEGER(19,i8,6,j1)
- TEST_INTEGER(19,i8,6,j2)
- TEST_INTEGER(19,i8,6,j4)
- TEST_INTEGER(19,i8,6,j8)
-
-
-
-#define TEST_LOGICAL(u,ukind,v,vkind) \
- ukind = u;\
- vkind = v;\
- if ((u .and. v) .neqv. and(ukind, vkind)) STOP 1;\
- if ((u .and. v) .neqv. and(vkind, ukind)) STOP 1;\
- if (((u .and. .not. v) .or. (.not. u .and. v)) .neqv. xor(ukind, vkind)) STOP 1;\
- if (((u .and. .not. v) .or. (.not. u .and. v)) .neqv. xor(vkind, ukind)) STOP 1;\
- if ((u .or. v) .neqv. or(ukind, vkind)) STOP 1;\
- if ((u .or. v) .neqv. or(vkind, ukind)) STOP 2
-
- TEST_LOGICAL(.true.,l1,.false.,k1)
- TEST_LOGICAL(.true.,l1,.true.,k1)
- TEST_LOGICAL(.true.,l1,.false.,k2)
- TEST_LOGICAL(.true.,l1,.true.,k2)
- TEST_LOGICAL(.true.,l1,.false.,k4)
- TEST_LOGICAL(.true.,l1,.true.,k4)
- TEST_LOGICAL(.true.,l1,.false.,k8)
- TEST_LOGICAL(.true.,l1,.true.,k8)
-
- TEST_LOGICAL(.true.,l2,.false.,k1)
- TEST_LOGICAL(.true.,l2,.true.,k1)
- TEST_LOGICAL(.true.,l2,.false.,k2)
- TEST_LOGICAL(.true.,l2,.true.,k2)
- TEST_LOGICAL(.true.,l2,.false.,k4)
- TEST_LOGICAL(.true.,l2,.true.,k4)
- TEST_LOGICAL(.true.,l2,.false.,k8)
- TEST_LOGICAL(.true.,l2,.true.,k8)
-
- TEST_LOGICAL(.true.,l4,.false.,k1)
- TEST_LOGICAL(.true.,l4,.true.,k1)
- TEST_LOGICAL(.true.,l4,.false.,k2)
- TEST_LOGICAL(.true.,l4,.true.,k2)
- TEST_LOGICAL(.true.,l4,.false.,k4)
- TEST_LOGICAL(.true.,l4,.true.,k4)
- TEST_LOGICAL(.true.,l4,.false.,k8)
- TEST_LOGICAL(.true.,l4,.true.,k8)
-
- TEST_LOGICAL(.true.,l8,.false.,k1)
- TEST_LOGICAL(.true.,l8,.true.,k1)
- TEST_LOGICAL(.true.,l8,.false.,k2)
- TEST_LOGICAL(.true.,l8,.true.,k2)
- TEST_LOGICAL(.true.,l8,.false.,k4)
- TEST_LOGICAL(.true.,l8,.true.,k4)
- TEST_LOGICAL(.true.,l8,.false.,k8)
- TEST_LOGICAL(.true.,l8,.true.,k8)
-
- end
diff --git a/gcc/testsuite/gfortran.dg/gnu_logical_2.f90 b/gcc/testsuite/gfortran.dg/gnu_logical_2.f90
index 4ff70fa..a7b31b4 100644
--- a/gcc/testsuite/gfortran.dg/gnu_logical_2.f90
+++ b/gcc/testsuite/gfortran.dg/gnu_logical_2.f90
@@ -7,23 +7,23 @@
print *, and(i,i)
print *, and(l,l)
- print *, and(i,r) ! { dg-error "must be INTEGER or LOGICAL" }
- print *, and(c,l) ! { dg-error "must be INTEGER or LOGICAL" }
- print *, and(i,l) ! { dg-error "must have the same type" }
- print *, and(l,i) ! { dg-error "must have the same type" }
+ print *, and(i,r) ! { dg-error "must be the same type" }
+ print *, and(c,l) ! { dg-error "must be the same type" }
+ print *, and(i,l) ! { dg-error "must be the same type" }
+ print *, and(l,i) ! { dg-error "must be the same type" }
print *, or(i,i)
print *, or(l,l)
- print *, or(i,r) ! { dg-error "must be INTEGER or LOGICAL" }
- print *, or(c,l) ! { dg-error "must be INTEGER or LOGICAL" }
- print *, or(i,l) ! { dg-error "must have the same type" }
- print *, or(l,i) ! { dg-error "must have the same type" }
+ print *, or(i,r) ! { dg-error "must be the same type" }
+ print *, or(c,l) ! { dg-error "must be the same type" }
+ print *, or(i,l) ! { dg-error "must be the same type" }
+ print *, or(l,i) ! { dg-error "must be the same type" }
print *, xor(i,i)
print *, xor(l,l)
- print *, xor(i,r) ! { dg-error "must be INTEGER or LOGICAL" }
- print *, xor(c,l) ! { dg-error "must be INTEGER or LOGICAL" }
- print *, xor(i,l) ! { dg-error "must have the same type" }
- print *, xor(l,i) ! { dg-error "must have the same type" }
+ print *, xor(i,r) ! { dg-error "must be the same type" }
+ print *, xor(c,l) ! { dg-error "must be the same type" }
+ print *, xor(i,l) ! { dg-error "must be the same type" }
+ print *, xor(l,i) ! { dg-error "must be the same type" }
end
diff --git a/gcc/testsuite/gfortran.dg/hollerith8.f90 b/gcc/testsuite/gfortran.dg/hollerith8.f90
index b9f25d0..384904d 100644
--- a/gcc/testsuite/gfortran.dg/hollerith8.f90
+++ b/gcc/testsuite/gfortran.dg/hollerith8.f90
@@ -1,9 +1,9 @@
! { dg-do run }
-! { dg-options "-std=gnu" }
+! { dg-options "-std=legacy" }
! PR43217 Output of Hollerith constants which are not a multiple of 4 bytes
! Test case prepared from OP by Jerry DeLisle <jvdelisle@gcc.gnu.org>
program hello2
- call wrtout (9hHELLO YOU, 9)
+ call wrtout (9hHELLO YOU, 9) ! { dg-warning "Rank mismatch" }
stop
end
@@ -22,5 +22,3 @@ subroutine wrtout (iarray, nchrs)
& outstr.ne."48454C4C 4F20594F 55202020") STOP 1
return
end
-! { dg-warning "Hollerith constant" "" { target *-*-* } 6 }
-! { dg-warning "Rank mismatch" "" { target *-*-* } 6 }
diff --git a/gcc/testsuite/gfortran.dg/ibits.f90 b/gcc/testsuite/gfortran.dg/ibits.f90
index 780c8e6..c817c48 100644
--- a/gcc/testsuite/gfortran.dg/ibits.f90
+++ b/gcc/testsuite/gfortran.dg/ibits.f90
@@ -1,8 +1,10 @@
! { dg-do run }
+! { dg-options "-fallow-invalid-boz" }
! Test that the mask is properly converted to the kind type of j in ibits.
program ibits_test
implicit none
- integer(8), parameter :: n = z'00000000FFFFFFFF' ! { dg-warning "BOZ literal at .1. outside a DATA statement" }
+ integer(8), parameter :: &
+ & n = z'00000000FFFFFFFF' ! { dg-warning "BOZ literal constant" }
integer(8) i,j,k,m
j = 1
do i=1,70
diff --git a/gcc/testsuite/gfortran.dg/illegal_boz_arg_1.f90 b/gcc/testsuite/gfortran.dg/illegal_boz_arg_1.f90
new file mode 100644
index 0000000..8a79a52
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/illegal_boz_arg_1.f90
@@ -0,0 +1,9 @@
+! { dg-do compile }
+program foo
+ implicit none
+ integer :: i = 42
+ print *, storage_size(z'1234') ! { dg-error "cannot be an actual" }
+ print *, transfer(z'1234', i) ! { dg-error "cannot be an actual" }
+ print *, transfer(i, z'1234') ! { dg-error "cannot be an actual" }
+ print *, transfer(i, i, z'1234') ! { dg-error "must be INTEGER" }
+end program foo
diff --git a/gcc/testsuite/gfortran.dg/inquire_recl_f2018.f90 b/gcc/testsuite/gfortran.dg/inquire_recl_f2018.f90
index b744e92..dfb4092 100644
--- a/gcc/testsuite/gfortran.dg/inquire_recl_f2018.f90
+++ b/gcc/testsuite/gfortran.dg/inquire_recl_f2018.f90
@@ -39,4 +39,11 @@ program inqrecl
if (r /= -2) then
STOP 5
end if
+
+ ! Also inquire by filename for a non-opened unit is considered
+ ! unconnected similar to the first test.
+ inquire(file='unconnectedfile.txt', recl=r)
+ if (r /= -1) then
+ stop 6
+ end if
end program inqrecl
diff --git a/gcc/testsuite/gfortran.dg/int_conv_1.f90 b/gcc/testsuite/gfortran.dg/int_conv_1.f90
index a3e8783..daf0dfd 100644
--- a/gcc/testsuite/gfortran.dg/int_conv_1.f90
+++ b/gcc/testsuite/gfortran.dg/int_conv_1.f90
@@ -1,36 +1,25 @@
! { dg-do run }
! { dg-options "-std=gnu" }
- integer(kind=2) :: i2, j2, k2, l2, m2, n2, o2
- integer(kind=4) :: i4, j4
- integer(kind=8) :: i8, j8
+ integer(kind=2) :: i2, k2, l2
+ integer(kind=8) :: i8
real :: x
complex :: z
i2 = huge(i2) / 3
i8 = int8(i2)
- i4 = long(i2)
- j2 = short(i2)
k2 = int2(i2)
l2 = int2(i8)
- m2 = short(i8)
- n2 = int2(i4)
- o2 = short(i4)
- if (i8 /= i2 .or. i4 /= i2 .or. j2 /= i2 .or. k2 /= i2 &
- .or. l2 /= i2 .or. m2 /= i2 .or. n2 /= i2 .or. o2 /= i2) STOP 1
+ if (i8 /= i2 .or. k2 /= i2 .or. l2 /= i2 ) STOP 1
x = i2
i8 = int8(x)
- i4 = long(x)
- j2 = short(x)
k2 = int2(x)
- if (i8 /= i2 .or. i4 /= i2 .or. j2 /= i2 .or. k2 /= i2) STOP 2
+ if (i8 /= i2 .or. k2 /= i2) STOP 2
z = i2 + (0.,-42.)
i8 = int8(z)
- i4 = long(z)
- j2 = short(z)
k2 = int2(z)
- if (i8 /= i2 .or. i4 /= i2 .or. j2 /= i2 .or. k2 /= i2) STOP 3
+ if (i8 /= i2 .or. k2 /= i2) STOP 3
end
diff --git a/gcc/testsuite/gfortran.dg/integer_exponentiation_2.f90 b/gcc/testsuite/gfortran.dg/integer_exponentiation_2.f90
index 41f4cbf..ec018ff 100644
--- a/gcc/testsuite/gfortran.dg/integer_exponentiation_2.f90
+++ b/gcc/testsuite/gfortran.dg/integer_exponentiation_2.f90
@@ -139,16 +139,16 @@ subroutine foo(a)
call gee_i(i**(-huge(0_4)))
call gee_i(i**(-huge(0_4)-1_4))
- call gee_i(i**0_8) ! { dg-warning "Type mismatch in argument" }
- call gee_i(i**1_8) ! { dg-warning "Type mismatch in argument" }
- call gee_i(i**2_8) ! { dg-warning "Type mismatch in argument" }
- call gee_i(i**3_8) ! { dg-warning "Type mismatch in argument" }
- call gee_i(i**(-1_8)) ! { dg-warning "Type mismatch in argument" }
- call gee_i(i**(-2_8)) ! { dg-warning "Type mismatch in argument" }
- call gee_i(i**(-3_8)) ! { dg-warning "Type mismatch in argument" }
- call gee_i(i**huge(0_8)) ! { dg-warning "Type mismatch in argument" }
- call gee_i(i**(-huge(0_8))) ! { dg-warning "Type mismatch in argument" }
- call gee_i(i**(-huge(0_8)-1_8)) ! { dg-warning "Type mismatch in argument" }
+ call gee_i8(i**0_8)
+ call gee_i8(i**1_8)
+ call gee_i8(i**2_8)
+ call gee_i8(i**3_8)
+ call gee_i8(i**(-1_8))
+ call gee_i8(i**(-2_8))
+ call gee_i8(i**(-3_8))
+ call gee_i8(i**huge(0_8))
+ call gee_i8(i**(-huge(0_8)))
+ call gee_i8(i**(-huge(0_8)-1_8))
! Real
call gee_r(a**0_1)
@@ -245,6 +245,10 @@ subroutine gee_i(i)
integer :: i
end subroutine gee_i
+subroutine gee_i8(i)
+ integer(kind=8) :: i
+end subroutine gee_i8
+
subroutine gee_r(r)
real :: r
end subroutine gee_r
diff --git a/gcc/testsuite/gfortran.dg/ishft_1.f90 b/gcc/testsuite/gfortran.dg/ishft_1.f90
index 82fdb02..ffac323 100644
--- a/gcc/testsuite/gfortran.dg/ishft_1.f90
+++ b/gcc/testsuite/gfortran.dg/ishft_1.f90
@@ -25,7 +25,6 @@ if (ishft (1_8, 0) /= 1) STOP 19
if (ishft (1_8, 1) /= 2) STOP 20
if (ishft (3_8, 1) /= 6) STOP 21
if (ishft (-1_8, 1) /= -2) STOP 22
-if (ishft (-1_8, -60) /= z'F') STOP 23
if (ishftc (1_1, 0) /= 1) STOP 24
if (ishftc (1_1, 1) /= 2) STOP 25
diff --git a/gcc/testsuite/gfortran.dg/merge_bits_3.f90 b/gcc/testsuite/gfortran.dg/merge_bits_3.f90
new file mode 100644
index 0000000..8193b32
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/merge_bits_3.f90
@@ -0,0 +1,5 @@
+! { dg-do compile }
+program foo
+ integer m
+ m = merge_bits(b'010101', b"101010", 42) ! { dg-error "cannot both be" }
+end program foo
diff --git a/gcc/testsuite/gfortran.dg/merge_bits_4.f90 b/gcc/testsuite/gfortran.dg/merge_bits_4.f90
new file mode 100644
index 0000000..5622ecb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/merge_bits_4.f90
@@ -0,0 +1,7 @@
+! { dg-do run }
+program foo
+ integer m, n, k
+ m = merge_bits(b'010101', 1234, 42); if (m /= 1232) stop 1
+ n = merge_bits(1234, z'3456', 42); if (n /= 13398) stop 2
+ k = merge_bits(1234, 3456, o'12334'); if (k /= 3536) stop 3
+end program foo
diff --git a/gcc/testsuite/gfortran.dg/nan_4.f90 b/gcc/testsuite/gfortran.dg/nan_4.f90
index 46aba3e..b4c1f71 100644
--- a/gcc/testsuite/gfortran.dg/nan_4.f90
+++ b/gcc/testsuite/gfortran.dg/nan_4.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
-! { dg-options "-std=gnu" }
+! { dg-options "-std=gnu -fallow-invalid-boz" }
! { dg-add-options ieee }
! { dg-skip-if "NaN not supported" { spu-*-* } }
!
@@ -9,8 +9,8 @@
!
program test
implicit none
- real(4), parameter :: r0 = z'FFFFFFFF' ! { dg-error "Arithmetic NaN" }
+ real(4), parameter :: r0 = z'FFFFFFFF' ! { dg-warning "BOZ literal constant" }
real(4) r
- data r/z'FFFFFFFF'/ ! { dg-error "Arithmetic NaN" }
- r = z'FFFFFFFF' ! { dg-error "Arithmetic NaN" }
+ data r/z'FFFFFFFF'/ ! { dg-warning "BOZ literal constant" }
+ r = z'FFFFFFFF' ! { dg-warning "BOZ literal constant" }
end program test
diff --git a/gcc/testsuite/gfortran.dg/no_range_check_3.f90 b/gcc/testsuite/gfortran.dg/no_range_check_3.f90
index ffab312..4653ff0 100644
--- a/gcc/testsuite/gfortran.dg/no_range_check_3.f90
+++ b/gcc/testsuite/gfortran.dg/no_range_check_3.f90
@@ -1,6 +1,6 @@
! { dg-do run }
-! { dg-options "-fno-range-check" }
program test
+ integer(2) :: j, k
integer :: i
i = int(z'FFFFFFFF',kind(i))
if (i /= -1) STOP 1
@@ -9,4 +9,8 @@ program test
if (popcnt(int(z'0F00F00080000001',8)) /= 10) STOP 3
if (popcnt(int(z'800F0001',4)) /= 6) STOP 4
+ j = -1234_2
+ k = int(z'FB2E',kind(j))
+ if (k /= j) STOP 5
+ if (int(z'FB2E',kind(j)) /= j) STOP 6
end program test
diff --git a/gcc/testsuite/gfortran.dg/pr16433.f b/gcc/testsuite/gfortran.dg/pr16433.f
index cb3dcec..925eb52 100644
--- a/gcc/testsuite/gfortran.dg/pr16433.f
+++ b/gcc/testsuite/gfortran.dg/pr16433.f
@@ -1,6 +1,6 @@
! { dg-do compile }
real x
double precision dx
- data x/x'2ffde'/ ! { dg-warning "Hexadecimal constant | used to initialize non-integer" }
- dx = x ! { dg-bogus "exadecimal constant" "Hex constant where there is none" }
+ data x/x'2ffde'/ ! { dg-error "Hexadecimal constant" }
+ dx = x
end
diff --git a/gcc/testsuite/gfortran.dg/pr41011.f b/gcc/testsuite/gfortran.dg/pr41011.f
index 83e85fb..5a32185 100644
--- a/gcc/testsuite/gfortran.dg/pr41011.f
+++ b/gcc/testsuite/gfortran.dg/pr41011.f
@@ -1,5 +1,5 @@
! { dg-do compile }
-! { dg-options "-O3" }
+! { dg-options "-O3 -std=legacy" }
CALL UVSET(NX,NY,NZ,HVAR,ZET,NP,DZ,DKM,UM,VM,UG,VG,TM,DCDX, ! { dg-warning "Rank mismatch" }
*ITY,ISH,NSMT,F)
CALL DCTDX(NX,NY,NX1,NFILT,C(MLAG),DCDX(MLAG),HELP,HELPA,
diff --git a/gcc/testsuite/gfortran.dg/pr44491.f90 b/gcc/testsuite/gfortran.dg/pr44491.f90
index 406bb26..3bd31c4 100644
--- a/gcc/testsuite/gfortran.dg/pr44491.f90
+++ b/gcc/testsuite/gfortran.dg/pr44491.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
! { dg-options "-std=gnu" }
! PR fortran/44491
- character*2 escape /z'1B'/ ! { dg-error "Incompatible types in DATA" }
+ character*2 escape /z'1B'/ ! { dg-error "cannot appear in" }
end
diff --git a/gcc/testsuite/gfortran.dg/pr58027.f90 b/gcc/testsuite/gfortran.dg/pr58027.f90
index bef893c..7398c6c 100644
--- a/gcc/testsuite/gfortran.dg/pr58027.f90
+++ b/gcc/testsuite/gfortran.dg/pr58027.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
! PR fortran/58027
-integer, parameter :: i(1)=(/z'ff800000'/) ! { dg-error "overflow converting" }
+integer, parameter :: i(1)=(/z'ff800000'/) ! { dg-error "cannot appear in" }
print *, isclass
end
diff --git a/gcc/testsuite/gfortran.dg/pr70754.f90 b/gcc/testsuite/gfortran.dg/pr70754.f90
index d7e790c..593acf9 100644
--- a/gcc/testsuite/gfortran.dg/pr70754.f90
+++ b/gcc/testsuite/gfortran.dg/pr70754.f90
@@ -18,12 +18,13 @@ contains
integer (ii4), dimension(40,40) :: c
integer i, j
- do i=1,20
- b(i,j) = 123 * a(i,j) + 34 * a(i,j+1) &
- + 34 * a(i,j-1) + a(i+1,j+1) &
- + a(i+1,j-1) + a(i-1,j+1) &
- + a(i-1,j-1)
- c(i,j) = 123
+ j = 10
+ do i=11,30
+ b(i,j) = 123 * a(i,j) + 34 * a(i,j+1) &
+ + 34 * a(i,j-1) + a(i+1,j+1) &
+ + a(i+1,j-1) + a(i-1,j+1) &
+ + a(i-1,j-1)
+ c(i,j) = 123
end do
where ((xyz(:,:,2) /= 0) .and. (c /= 0))
diff --git a/gcc/testsuite/gfortran.dg/pr71649.f90 b/gcc/testsuite/gfortran.dg/pr71649.f90
index f20b768..c01389a 100644
--- a/gcc/testsuite/gfortran.dg/pr71649.f90
+++ b/gcc/testsuite/gfortran.dg/pr71649.f90
@@ -1,13 +1,13 @@
! { dg-do compile }
! PR71649 Internal Compiler Error
-SUBROUTINE Compiler_Options ( Options, Version, WriteOpt )
- USE ISO_FORTRAN_ENV, ONLY : Compiler_Version, Compiler_Options ! { dg-error "already declared" }
+SUBROUTINE Compiler_Options ( Options, Version, WriteOpt ) ! { dg-error "\(1\)" }
+ USE ISO_FORTRAN_ENV, ONLY : Compiler_Version, Compiler_Options ! { dg-error "conflicts with the" }
IMPLICIT NONE
CHARACTER (LEN=*), INTENT(OUT) :: Options
CHARACTER (LEN=*), INTENT(OUT) :: Version
LOGICAL, INTENT(IN), OPTIONAL :: WriteOpt
- Version = Compiler_Version()
- Options = Compiler_Options() ! { dg-error "Unexpected use of subroutine name" }
+ Version = Compiler_Version() ! { dg-error "has no IMPLICIT type" }
+ Options = Compiler_Options() ! { dg-error "Unexpected use of subroutine name" }
RETURN
END SUBROUTINE Compiler_Options
diff --git a/gcc/testsuite/gfortran.dg/pr78719_1.f90 b/gcc/testsuite/gfortran.dg/pr78719_1.f90
new file mode 100644
index 0000000..f5a99c2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr78719_1.f90
@@ -0,0 +1,29 @@
+! { dg-do run }
+! PR fortran/78719
+! Code contributed by Gerhard Steinmetz
+program p
+
+ type t
+ integer :: n
+ end type
+
+ abstract interface
+ subroutine h
+ end
+ end interface
+
+ procedure(h), pointer :: s
+
+ s => f
+ call s
+ s => g
+ call s
+
+ contains
+
+ subroutine f
+ end
+
+ subroutine g
+ end
+end program p
diff --git a/gcc/testsuite/gfortran.dg/pr78719_2.f90 b/gcc/testsuite/gfortran.dg/pr78719_2.f90
new file mode 100644
index 0000000..59abebe
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr78719_2.f90
@@ -0,0 +1,32 @@
+! { dg-do compile }
+! PR fortran/78719
+! Code contributed by Gerhard Steinmetz
+program p
+
+ type t
+ integer :: n
+ end type
+
+ real :: g
+
+ abstract interface
+ subroutine h
+ end
+ end interface
+
+ procedure(h), pointer :: s
+
+ s => f
+ call s
+ s => g ! { dg-error "Invalid procedure pointer" }
+ call s
+
+ contains
+
+ subroutine f
+ end
+
+ subroutine g ! { dg-error "has an explicit interface" }
+ end
+
+end program p ! { dg-error "Syntax error" }
diff --git a/gcc/testsuite/gfortran.dg/pr78719_3.f90 b/gcc/testsuite/gfortran.dg/pr78719_3.f90
new file mode 100644
index 0000000..8e7f6ac
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr78719_3.f90
@@ -0,0 +1,32 @@
+! { dg-do compile }
+! PR fortran/78719
+! Code contributed by Gerhard Steinmetz
+program p
+
+ type t
+ integer :: n
+ end type
+
+ class(t) :: g ! { dg-error "must be dummy, allocatable or pointer" }
+
+ abstract interface
+ subroutine h
+ end
+ end interface
+
+ procedure(h), pointer :: s
+
+ s => f
+ call s
+ s => g ! { dg-error "Invalid procedure pointer" }
+ call s
+
+ contains
+
+ subroutine f
+ end
+
+ subroutine g ! { dg-error "has an explicit interface" }
+ end
+
+end program p ! { dg-error "Syntax error" }
diff --git a/gcc/testsuite/gfortran.dg/pr78739.f90 b/gcc/testsuite/gfortran.dg/pr78739.f90
new file mode 100644
index 0000000..4b36b76
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr78739.f90
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! { dg-options "-w" }
+! PR fortran/78739
+! Code contributed Gerhard Steinmetz
+function f(n)
+ f() = n ! { dg-error "conflicts with function name" }
+end
+
+function g()
+ g(x) = x ! { dg-error "conflicts with function name" }
+end
+
+function a() ! This should cause an error, but cannot be easily detected!
+ a() = x
+end
diff --git a/gcc/testsuite/gfortran.dg/pr81509_2.f90 b/gcc/testsuite/gfortran.dg/pr81509_2.f90
index 919cb4e..a0618cc 100644
--- a/gcc/testsuite/gfortran.dg/pr81509_2.f90
+++ b/gcc/testsuite/gfortran.dg/pr81509_2.f90
@@ -12,7 +12,7 @@ k = and(i, z'1234')
k = ieor(z'ade',i)
k = ior(i,z'1111')
k = ior(i,k) ! { dg-error "different kind type parameters" }
-k = and(i,k)
-k = and(a,z'1234') ! { dg-error "must have the same type" }
+k = and(i,k) ! { dg-error "must be the same type" }
+k = and(a,z'1234') ! { dg-error "must be the same type" }
end program foo
diff --git a/gcc/testsuite/gfortran.dg/pr87991.f90 b/gcc/testsuite/gfortran.dg/pr87991.f90
new file mode 100644
index 0000000..435871e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr87991.f90
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! { dg-options "-w" }
+! PR fortran/87991
+program p
+ type t
+ character(:), pointer :: c
+ end type
+ type(t) :: x
+ allocate (character(3) :: x%c)
+ data x%c /'abc'/ ! { dg-error "has the pointer attribute" }
+end
diff --git a/gcc/testsuite/gfortran.dg/pr87993.f90 b/gcc/testsuite/gfortran.dg/pr87993.f90
new file mode 100644
index 0000000..96d353d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr87993.f90
@@ -0,0 +1,8 @@
+! { dg-do run }
+! Code contributed by Gerhard Steinmetz <gscfq at t-online dot de>
+program p
+ integer, parameter :: a(2) = 1
+ integer, parameter :: b = a%kind
+ if (any(a /= 1)) stop 1
+ if (b /= kind(a)) stop 2
+end
diff --git a/gcc/testsuite/gfortran.dg/pr88072.f90 b/gcc/testsuite/gfortran.dg/pr88072.f90
new file mode 100644
index 0000000..5bc6af4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr88072.f90
@@ -0,0 +1,30 @@
+! { dg-do compile }
+! PR fortran/88072
+! Original code contributed by Andrew Wood <andrew at fluidgravity dot co.uk>
+module m1
+
+ implicit none
+
+ type, abstract, public :: t1
+ integer, dimension(:), allocatable :: i
+ contains
+ procedure(f1), deferred :: f
+ end type t1
+
+ type, extends(t1), public :: t2 ! { dg-error "must be ABSTRACT because" }
+ contains
+ procedure :: f => f2 ! { dg-error "mismatch for the overriding" }
+ end type t2
+
+ abstract interface
+ function f1(this) ! { dg-error "must be dummy, allocatable or" }
+ import
+ class(t1) :: this
+ class(t1) :: f1
+ end function f1
+ end interface
+ contains
+ type(t2) function f2(this)
+ class(t2) :: this
+ end function f2
+end module m1
diff --git a/gcc/testsuite/gfortran.dg/pr89647.f90 b/gcc/testsuite/gfortran.dg/pr89647.f90
new file mode 100644
index 0000000..1d4dc2d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr89647.f90
@@ -0,0 +1,33 @@
+! { dg-do compile }
+! Code contributed by Ian Harvey <ian_harvey at bigpond dot com>
+ MODULE m1
+ IMPLICIT NONE
+ PUBLIC :: False
+ PUBLIC :: True
+ CONTAINS
+ FUNCTION False() RESULT(b)
+ LOGICAL :: b
+ b = .FALSE.
+ END FUNCTION False
+
+ FUNCTION True() RESULT(b)
+ LOGICAL :: b
+ b = .TRUE.
+ END FUNCTION True
+ END MODULE m1
+
+ MODULE m2
+ USE m1
+ IMPLICIT NONE
+ TYPE, ABSTRACT :: t_parent
+ CONTAINS
+ PROCEDURE(False), DEFERRED, NOPASS :: Binding
+ END TYPE t_parent
+ CONTAINS
+ SUBROUTINE s
+ TYPE, EXTENDS(t_parent) :: t_extension
+ CONTAINS
+ PROCEDURE, NOPASS :: Binding => True
+ END TYPE t_extension
+ END SUBROUTINE s
+ END MODULE m2
diff --git a/gcc/testsuite/gfortran.dg/pr90985.f90 b/gcc/testsuite/gfortran.dg/pr90985.f90
new file mode 100644
index 0000000..48f5023
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr90985.f90
@@ -0,0 +1,14 @@
+! { dg-do compile }
+module mymod
+ type :: mytyp
+ integer :: i
+ end type mytyp
+contains
+ subroutine mysub
+ implicit none
+ type(mytyp) :: a
+ integer :: datai,dataj
+ datai = a%i
+ dataj = a%j ! { dg-error "is not a member of the" }
+ end subroutine mysub
+end module mymod
diff --git a/gcc/testsuite/gfortran.dg/pr91296.f90 b/gcc/testsuite/gfortran.dg/pr91296.f90
new file mode 100644
index 0000000..5f7bb0e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr91296.f90
@@ -0,0 +1,27 @@
+! { dg-do compile }
+! { dg-options "-Waliasing" }
+! PR fortran/91296
+! Code contributed by Chinoune Mehdi <chinoune dot medhi at hotmail dot com>
+module m
+ implicit none
+ integer, parameter :: sp = selected_real_kind(6)
+
+contains
+ pure subroutine s(a,b,c)
+ real(sp), intent(in) :: a, b
+ real(sp), intent(out) :: c
+ c = a + b
+ end subroutine s
+end module m
+
+program test
+ use m
+ implicit none
+ real(sp) :: a
+ complex(sp) :: c
+
+ c = (1._sp,1._sp)
+ call s(c%re,c%im,a) ! *** This use to cause an ICE. ***
+ print*,a
+
+end program test
diff --git a/gcc/testsuite/gfortran.dg/pr91359_1.f b/gcc/testsuite/gfortran.dg/pr91359_1.f
new file mode 100644
index 0000000..5a49640
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr91359_1.f
@@ -0,0 +1,16 @@
+! { dg-do run }
+! PR fortran/91359
+! Orginal code contributed by Brian T. Carcich <briantcarcich at gmail dot com>
+!
+ logical function zero()
+ goto 2
+1 return
+2 zero = .false.
+ if (.not.zero) goto 1
+ return
+ end
+
+ program test_zero
+ logical zero
+ if (zero()) stop 1
+ end
diff --git a/gcc/testsuite/gfortran.dg/pr91359_2.f b/gcc/testsuite/gfortran.dg/pr91359_2.f
new file mode 100644
index 0000000..88a9293
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr91359_2.f
@@ -0,0 +1,16 @@
+! { dg-do run }
+! PR fortran/91359
+! Orginal code contributed by Brian T. Carcich <briantcarcich at gmail dot com>
+!
+ logical function zero() result(a)
+ goto 2
+1 return
+2 a = .false.
+ if (.not.a) goto 1
+ return
+ end
+
+ program test_zero
+ logical zero
+ if (zero()) stop 1
+ end
diff --git a/gcc/testsuite/gfortran.dg/pr91372.f90 b/gcc/testsuite/gfortran.dg/pr91372.f90
new file mode 100644
index 0000000..b948314
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr91372.f90
@@ -0,0 +1,9 @@
+! { dg-do compile }
+! PR fortran/91372
+module module_sf_lake
+ implicit none
+ integer, parameter :: r8 = selected_real_kind(12)
+ integer, private :: i
+ real(r8) :: sand(2) ! percent sand
+ data(sand(i), i=1,2)/92.,80./
+end module module_sf_lake
diff --git a/gcc/testsuite/gfortran.dg/pr91471.f90 b/gcc/testsuite/gfortran.dg/pr91471.f90
new file mode 100644
index 0000000..fa79844
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr91471.f90
@@ -0,0 +1,14 @@
+! { dg-do compile }
+! PR fortran/91471
+! Code contributed by Sameeran Joshi <SameeranJayant dot Joshi at amd dot com>
+!
+! This invalid code (x(1) is referenced, but never set) caused an ICE due
+! to hitting a gfc_internal_error() in primary.c (gfc_variable_attr). The
+! fix is to remove that gfc_internal_error().
+!
+program dynamic
+ implicit none
+ integer, dimension(:), allocatable :: x
+ allocate(x(1))
+ stop x(1)
+end program dynamic
diff --git a/gcc/testsuite/gfortran.dg/pr91485.f90 b/gcc/testsuite/gfortran.dg/pr91485.f90
new file mode 100644
index 0000000..a6d0687
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr91485.f90
@@ -0,0 +1,24 @@
+! { dg-do compile }
+module foo
+ implicit none
+ interface operator(.x.)
+ module procedure product
+ end interface operator(.x.)
+ contains
+ function product(x, y)
+ real, intent(in) :: x, y
+ real :: product
+ product = x * y
+ end function product
+end module foo
+
+module gfcbug155
+ implicit none
+ contains
+ subroutine print_prod (x, y)
+ use foo, only : operator(.x.)
+ implicit none
+ real :: x, y
+ print *, x .x. y
+ end subroutine print_prod
+end module gfcbug155
diff --git a/gcc/testsuite/gfortran.dg/random_seed_1.f90 b/gcc/testsuite/gfortran.dg/random_seed_1.f90
index 39c81ce..a97e530 100644
--- a/gcc/testsuite/gfortran.dg/random_seed_1.f90
+++ b/gcc/testsuite/gfortran.dg/random_seed_1.f90
@@ -10,11 +10,12 @@
PROGRAM random_seed_1
IMPLICIT NONE
- INTEGER, PARAMETER :: nbytes = 128
+ ! Should match sizeof(master_state) in
+ ! libgfortran/intrinsics/random.c
+ INTEGER, PARAMETER :: nbytes = 32
- ! +1 due to the special 'p' value in xorshift1024*
! '+1' to avoid out-of-bounds warnings
- INTEGER, PARAMETER :: n = nbytes / KIND(n) + 2
+ INTEGER, PARAMETER :: n = nbytes / KIND(n) + 1
INTEGER, DIMENSION(n) :: seed
! Get seed, array too small
diff --git a/gcc/testsuite/gfortran.dg/unf_io_convert_1.f90 b/gcc/testsuite/gfortran.dg/unf_io_convert_1.f90
index 1baa7f5..61d982d 100644
--- a/gcc/testsuite/gfortran.dg/unf_io_convert_1.f90
+++ b/gcc/testsuite/gfortran.dg/unf_io_convert_1.f90
@@ -18,9 +18,9 @@ program main
integer i
character(4) str
- m(1) = Z'11223344' ! { dg-warning "BOZ literal at .1. outside a DATA statement" }
- m(2) = Z'55667788' ! { dg-warning "BOZ literal at .1. outside a DATA statement" }
- n = Z'77AABBCC' ! { dg-warning "BOZ literal at .1. outside a DATA statement" }
+ m(1) = int(Z'11223344')
+ m(2) = int(Z'55667788')
+ n = int(Z'77AABBCC')
str = 'asdf'
do i = 1,size
r(i) = i
@@ -46,7 +46,7 @@ program main
read(9) str
!
! check results
- if (m(1).ne.Z'11223344') then
+ if (m(1).ne.int(Z'11223344')) then
if (debug) then
print '(A,Z8)','m(1) incorrect. m(1) = ',m(1)
else
@@ -54,7 +54,7 @@ program main
endif
endif
- if (m(2).ne.Z'55667788') then
+ if (m(2).ne.int(Z'55667788')) then
if (debug) then
print '(A,Z8)','m(2) incorrect. m(2) = ',m(2)
else
@@ -62,7 +62,7 @@ program main
endif
endif
- if (n.ne.Z'77AABBCC') then
+ if (n.ne.int(Z'77AABBCC')) then
if (debug) then
print '(A,Z8)','n incorrect. n = ',n
else
diff --git a/gcc/testsuite/gfortran.dg/unf_io_convert_2.f90 b/gcc/testsuite/gfortran.dg/unf_io_convert_2.f90
index e9092cb..cc5ab4d 100644
--- a/gcc/testsuite/gfortran.dg/unf_io_convert_2.f90
+++ b/gcc/testsuite/gfortran.dg/unf_io_convert_2.f90
@@ -15,26 +15,28 @@ program main
close(10,status="delete")
open (10, form="unformatted",convert="big_endian") ! { dg-warning "Extension: CONVERT" }
- i = (/ Z'11223344', Z'55667700' /)
+ i = (/ int(Z'11223344'), int(Z'55667700') /)
write (10) i
rewind (10)
read (10) b
- if (any(b /= (/ Z'11', Z'22', Z'33', Z'44', Z'55', Z'66', Z'77', Z'00' /))) &
+ if (any(b /= (/ int(Z'11',1), int(Z'22',1), int(Z'33',1), int(Z'44',1), &
+ & int(Z'55',1), int(Z'66',1), int(Z'77',1), int(Z'00',1) /))) &
STOP 2
backspace 10
read (10) j
- if (j /= Z'1122334455667700') STOP 3
+ if (j /= int(Z'1122334455667700',8)) STOP 3
close (10, status="delete")
open (10, form="unformatted", convert="little_endian") ! { dg-warning "Extension: CONVERT" }
write (10) i
rewind (10)
read (10) b
- if (any(b /= (/ Z'44', Z'33', Z'22', Z'11', Z'00', Z'77', Z'66', Z'55' /))) &
+ if (any(b /= (/ int(Z'44',1), int(Z'33',1), int(Z'22',1), int(Z'11',1), &
+ & int(Z'00',1), int(Z'77',1), int(Z'66',1), int(Z'55',1) /))) &
STOP 4
backspace 10
read (10) j
- if (j /= Z'5566770011223344') STOP 5
+ if (j /= int(Z'5566770011223344',8)) STOP 5
close (10, status="delete")
end program main
diff --git a/gcc/testsuite/gfortran.dg/unlimited_polymorphic_28.f90 b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_28.f90
index b474a24..a9f6727 100644
--- a/gcc/testsuite/gfortran.dg/unlimited_polymorphic_28.f90
+++ b/gcc/testsuite/gfortran.dg/unlimited_polymorphic_28.f90
@@ -21,7 +21,7 @@ implicit none
type,abstract,extends(c_base) :: c_derived
contains
- procedure :: f_base => f_derived ! { dg-error "Type mismatch in function result \\(CLASS\\(\\*\\)/CLASS\\(c_base\\)\\)" }
+ procedure :: f_base => f_derived ! { dg-error "Type mismatch in function result" }
end type c_derived
contains
diff --git a/gcc/testsuite/gfortran.dg/use_15.f90 b/gcc/testsuite/gfortran.dg/use_15.f90
index bd5920a..eb5aa87 100644
--- a/gcc/testsuite/gfortran.dg/use_15.f90
+++ b/gcc/testsuite/gfortran.dg/use_15.f90
@@ -28,8 +28,8 @@ subroutine my_sub2 (a)
end subroutine
-subroutine my_sub3 (a)
- use test_mod2, my_sub3 => my_sub2 ! { dg-error "is also the name of the current program unit" }
+subroutine my_sub3 (a) ! { dg-error "\(1\)" }
+ use test_mod2, my_sub3 => my_sub2 ! { dg-error "conflicts with the rename" }
real a
print *, a
end subroutine
diff --git a/gcc/testsuite/gfortran.dg/use_rename_8.f90 b/gcc/testsuite/gfortran.dg/use_rename_8.f90
index ad3ab39..b8b49d7 100644
--- a/gcc/testsuite/gfortran.dg/use_rename_8.f90
+++ b/gcc/testsuite/gfortran.dg/use_rename_8.f90
@@ -19,8 +19,8 @@ SUBROUTINE T
USE MOO, ONLY: X => B
END SUBROUTINE T
-SUBROUTINE C
- USE MOO, ONLY: C ! { dg-error "is also the name of the current program unit" }
+SUBROUTINE C ! { dg-error "\(1\)" }
+ USE MOO, ONLY: C ! { dg-error "conflicts with the" }
END SUBROUTINE C
SUBROUTINE D
@@ -36,15 +36,15 @@ SUBROUTINE F
USE MOO, ONLY: X => F
END SUBROUTINE F
-SUBROUTINE X
- USE MOO, ONLY: X => G ! { dg-error "is also the name of the current program unit" }
+SUBROUTINE X ! { dg-error "\(1\)" }
+ USE MOO, ONLY: X => G ! { dg-error "conflicts with the rename" }
END SUBROUTINE X
-SUBROUTINE Y
- USE MOO, ONLY: Y => H ! { dg-error "is also the name of the current program unit" }
+SUBROUTINE Y ! { dg-error "\(1\)" }
+ USE MOO, ONLY: Y => H ! { dg-error "conflicts with the rename" }
END SUBROUTINE Y
-SUBROUTINE Z
- USE MOO, ONLY: Z => I, Z => I ! { dg-error "is also the name of the current program unit" }
+SUBROUTINE Z ! { dg-error "\(1\)" }
+ USE MOO, ONLY: Z => I, Z => I ! { dg-error "conflicts with the rename" }
END SUBROUTINE Z
diff --git a/gcc/testsuite/gfortran.dg/whole_file_1.f90 b/gcc/testsuite/gfortran.dg/whole_file_1.f90
index bceb250..c865395 100644
--- a/gcc/testsuite/gfortran.dg/whole_file_1.f90
+++ b/gcc/testsuite/gfortran.dg/whole_file_1.f90
@@ -19,7 +19,7 @@ subroutine b
integer :: u1
end type
type (u) :: q
- call a(q) ! { dg-warning "Type mismatch" }
+ call a(q) ! { dg-error "Type mismatch" }
print *, q%u1
end subroutine
@@ -36,7 +36,7 @@ subroutine d
integer :: u1
end type
type (u) :: q
- call c(q) ! { dg-warning "Type mismatch" }
+ call c(q) ! { dg-error "Type mismatch" }
print *, q%u1
end subroutine
diff --git a/gcc/testsuite/gfortran.dg/whole_file_2.f90 b/gcc/testsuite/gfortran.dg/whole_file_2.f90
index 60163f4..0d44574 100644
--- a/gcc/testsuite/gfortran.dg/whole_file_2.f90
+++ b/gcc/testsuite/gfortran.dg/whole_file_2.f90
@@ -14,8 +14,8 @@ end function
program gg
real :: h
character (5) :: chr = 'hello'
-h = a(); ! { dg-warning "Missing actual argument" }
-call test ([chr]) ! { dg-warning "Rank mismatch" }
+h = a(); ! { dg-error "Missing actual argument" }
+call test ([chr]) ! { dg-error "Rank mismatch" }
end program gg
subroutine test (a)
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_fraction_exponent.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_fraction_exponent.f90
index ed7e2f1..ce7f0fb 100644
--- a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_fraction_exponent.f90
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_fraction_exponent.f90
@@ -13,25 +13,25 @@ program test_exponent_fraction
x = 0.
call test_4(x)
- i = o'00000000001'
+ i = int(o'00000000001')
call test_4(x)
- i = o'00010000000'
+ i = int(o'00010000000')
call test_4(x)
- i = o'17700000000'
+ i = int(o'17700000000')
call test_4(x)
- i = o'00004000001'
+ i = int(o'00004000001')
call test_4(x)
- i = o'17737777777'
+ i = int(o'17737777777')
call test_4(x)
- i = o'10000000000'
+ i = int(o'10000000000')
call test_4(x)
- i = o'0000010000'
+ i = int(o'0000010000')
call test_4(x)
y = 0.5
@@ -40,7 +40,7 @@ program test_exponent_fraction
y = 0.
call test_8(y)
- j = o'00000000001'
+ j = int(o'00000000001',8)
call test_8(y)
y = 0.2938735877D-38
@@ -49,7 +49,7 @@ program test_exponent_fraction
y = -1.469369D-39
call test_8(y)
- y = z'7fe00000'
+ y = real(z'7fe00000',8)
call test_8(y)
y = -5.739719D+42
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mvbits.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mvbits.f90
index c423d4f..13ff85e 100644
--- a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mvbits.f90
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_mvbits.f90
@@ -10,7 +10,7 @@ CALL mvbits(from, 2, 16, to, 1)
if (to /= result) STOP 1
to8 = 0_8
-from8 = b'1011'*2_8**32
+from8 = int(b'1011',8)*2_8**32
call mvbits (from8, 33, 3, to8, 2)
-if (to8 /= b'10100') STOP 1
+if (to8 /= int(b'10100',8)) STOP 1
end
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.f90
index ec2bc18..222da0a 100644
--- a/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.f90
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/intrinsic_nearest.f90
@@ -11,13 +11,13 @@ program test_nearest
s = 3.0
call test_n (s, r)
- i = z'00800000'
+ i = int(z'00800000')
call test_n (s, r)
- i = z'007fffff'
+ i = int(z'007fffff')
call test_n (s, r)
- i = z'00800100'
+ i = int(z'00800100')
call test_n (s, r)
s = 0
@@ -25,9 +25,8 @@ program test_nearest
y = nearest(s, -r)
if (.not. (x .gt. s .and. y .lt. s )) STOP 1
-! ??? This is pretty sketchy, but passes on most targets.
- infi = z'7f800000'
- maxi = z'7f7fffff'
+ infi = int(z'7f800000')
+ maxi = int(z'7f7fffff')
call test_up(max, inf)
call test_up(-inf, -max)
diff --git a/gcc/testsuite/gfortran.fortran-torture/execute/seq_io.f90 b/gcc/testsuite/gfortran.fortran-torture/execute/seq_io.f90
index dadab92..54f2aa7 100644
--- a/gcc/testsuite/gfortran.fortran-torture/execute/seq_io.f90
+++ b/gcc/testsuite/gfortran.fortran-torture/execute/seq_io.f90
@@ -16,9 +16,9 @@
integer n
real*4 r(size)
integer i
- m(1) = Z'11111111'
- m(2) = Z'22222222'
- n = Z'33333333'
+ m(1) = int(Z'11111111')
+ m(2) = int(Z'22222222')
+ n = int(Z'33333333')
do i = 1,size
r(i) = i
end do
@@ -39,7 +39,7 @@
read(9)r
!
! check results
- if (m(1).ne.Z'11111111') then
+ if (m(1).ne. int(Z'11111111')) then
if (debug) then
print '(A,Z8)','m(1) incorrect. m(1) = ',m(1)
else
@@ -47,7 +47,7 @@
endif
endif
- if (m(2).ne.Z'22222222') then
+ if (m(2).ne. int(Z'22222222')) then
if (debug) then
print '(A,Z8)','m(2) incorrect. m(2) = ',m(2)
else
@@ -55,7 +55,7 @@
endif
endif
- if (n.ne.Z'33333333') then
+ if (n.ne. int(Z'33333333')) then
if (debug) then
print '(A,Z8)','n incorrect. n = ',n
else
diff --git a/gcc/testsuite/gnat.dg/aggr26.adb b/gcc/testsuite/gnat.dg/aggr26.adb
new file mode 100644
index 0000000..0466473
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aggr26.adb
@@ -0,0 +1,10 @@
+-- { dg-do compile }
+
+procedure Aggr26 is
+
+ type Row is array (Positive) of Integer;
+ H : array (Positive) of Row := (others => (others => 0)); -- { dg-warning "\"Storage_Error\" will be raised at run time" }
+
+begin
+ null;
+end Aggr26;
diff --git a/gcc/testsuite/gnat.dg/aggr27.adb b/gcc/testsuite/gnat.dg/aggr27.adb
new file mode 100644
index 0000000..43b6206
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/aggr27.adb
@@ -0,0 +1,26 @@
+-- { dg-do run }
+-- { dg-options "-gnatws -gnata" }
+
+with GNAT.Random_Numbers;
+
+procedure Aggr27 is
+
+ Gen: GNAT.Random_Numbers.Generator;
+
+ function Random return Long_Long_Integer is
+ Rand : Integer := GNAT.Random_Numbers.Random(Gen);
+ begin
+ return Long_Long_Integer(Rand);
+ end Random;
+
+ type Values is range 1 .. 4;
+
+ Seq_LLI : array (Values) of Long_Long_Integer := (others => Random);
+ Seq_I : array (Values) of Integer := (others => Integer(Random));
+
+begin
+ -- Verify that there is at least two different entries in each.
+
+ pragma Assert (For some E of Seq_LLI => E /= Seq_LLI (Values'First));
+ pragma Assert (For some E of Seq_I => E /= Seq_I (Values'First));
+end Aggr27;
diff --git a/gcc/testsuite/gnat.dg/alignment15.adb b/gcc/testsuite/gnat.dg/alignment15.adb
new file mode 100644
index 0000000..e58243d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/alignment15.adb
@@ -0,0 +1,17 @@
+-- { dg-compile }
+
+procedure Alignment15 is
+ type T0 is record
+ X : Integer;
+ end record;
+ for T0'Alignment use 0;
+
+ type T00 is record
+ X : Integer;
+ end record with Alignment => 0;
+
+ Dummy0 : T0;
+ Dummy00 : T00;
+begin
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/allocator2.adb b/gcc/testsuite/gnat.dg/allocator2.adb
new file mode 100644
index 0000000..495efd3
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/allocator2.adb
@@ -0,0 +1,6 @@
+-- { dg-do compile }
+-- { dg-options "-gnatd.F" }
+
+package body Allocator2 is
+ procedure Dummy is null;
+end Allocator2;
diff --git a/gcc/testsuite/gnat.dg/allocator2.ads b/gcc/testsuite/gnat.dg/allocator2.ads
new file mode 100644
index 0000000..7c4c228
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/allocator2.ads
@@ -0,0 +1,15 @@
+pragma SPARK_Mode;
+package Allocator2 is
+ type Nat_Array is array (Positive range <>) of Natural with
+ Default_Component_Value => 0;
+ type Nat_Stack (Max : Natural) is record
+ Content : Nat_Array (1 .. Max);
+ end record;
+ type Stack_Acc is access Nat_Stack;
+ type My_Rec is private;
+private
+ type My_Rec is record
+ My_Stack : Stack_Acc := new Nat_Stack (Max => 10);
+ end record;
+ procedure Dummy;
+end Allocator2;
diff --git a/gcc/testsuite/gnat.dg/anon3.adb b/gcc/testsuite/gnat.dg/anon3.adb
new file mode 100644
index 0000000..8628633
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/anon3.adb
@@ -0,0 +1,6 @@
+-- { dg-do compile }
+-- { dg-options "-gnatwa" }
+
+package body Anon3 is
+ procedure Dummy is null;
+end Anon3;
diff --git a/gcc/testsuite/gnat.dg/anon3.ads b/gcc/testsuite/gnat.dg/anon3.ads
new file mode 100644
index 0000000..39978c2
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/anon3.ads
@@ -0,0 +1,4 @@
+package Anon3 is
+ X : access Integer := new Integer;
+ procedure Dummy;
+end Anon3;
diff --git a/gcc/testsuite/gnat.dg/array37.adb b/gcc/testsuite/gnat.dg/array37.adb
new file mode 100644
index 0000000..f1ee385
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/array37.adb
@@ -0,0 +1,19 @@
+-- { dg-do run }
+-- { dg-options "-O" }
+
+procedure Array37 is
+
+ type Arr is array (Integer range -1 .. 1) of Integer;
+
+ A : Arr := (-100, 0, 100);
+
+ function Ident (I : Integer) return Integer IS
+ begin
+ return I;
+ end;
+
+begin
+ if Ident (A (1)) <= Ident (A (0)) then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/assert2.adb b/gcc/testsuite/gnat.dg/assert2.adb
new file mode 100644
index 0000000..1328004
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/assert2.adb
@@ -0,0 +1,5 @@
+-- { dg-do compile }
+
+package body Assert2 is
+ procedure Dummy is null;
+end Assert2;
diff --git a/gcc/testsuite/gnat.dg/assert2.ads b/gcc/testsuite/gnat.dg/assert2.ads
new file mode 100644
index 0000000..adf9b921
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/assert2.ads
@@ -0,0 +1,15 @@
+package Assert2
+ with SPARK_Mode
+is
+ type Living is new Integer;
+ function Is_Martian (Unused : Living) return Boolean is (False);
+
+ function Is_Green (Unused : Living) return Boolean is (True);
+
+ pragma Assert
+ (for all M in Living => (if Is_Martian (M) then Is_Green (M)));
+ pragma Assert
+ (for all M in Living => (if Is_Martian (M) then not Is_Green (M)));
+
+ procedure Dummy;
+end Assert2;
diff --git a/gcc/testsuite/gnat.dg/case_optimization3.adb b/gcc/testsuite/gnat.dg/case_optimization3.adb
new file mode 100644
index 0000000..6887f32
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/case_optimization3.adb
@@ -0,0 +1,25 @@
+-- { dg-do compile }
+
+package body Case_Optimization3 is
+
+ procedure Proc (Val : T_RANGE) is
+ begin
+ case Val is
+ when 0 =>
+ raise Program_Error;
+ when 1 =>
+ null;
+ when 2 =>
+ null;
+ when 3 =>
+ null;
+ when 4 =>
+ null;
+ when others =>
+ null;
+ end case;
+ end;
+
+end Case_Optimization3;
+
+-- { dg-final { scan-assembler-not "__ucmpdi2" } }
diff --git a/gcc/testsuite/gnat.dg/case_optimization3.ads b/gcc/testsuite/gnat.dg/case_optimization3.ads
new file mode 100644
index 0000000..3e3c769
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/case_optimization3.ads
@@ -0,0 +1,10 @@
+package Case_Optimization3 is
+
+ type T_UINT32 is range 0 .. (2 ** 32) - 1;
+ for T_UINT32'Size use 32;
+
+ subtype T_RANGE is T_UINT32 range 0 .. 7;
+
+ procedure Proc (Val : T_RANGE);
+
+end Case_Optimization3;
diff --git a/gcc/testsuite/gnat.dg/casesi.adb b/gcc/testsuite/gnat.dg/casesi.adb
new file mode 100644
index 0000000..3884898
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/casesi.adb
@@ -0,0 +1,28 @@
+with Ada.Assertions;
+package body Casesi is
+
+ function Process (X : Natural) return String is
+ begin
+ case X is
+ when 0 => raise Ada.Assertions.Assertion_Error;
+ when 1 => raise Ada.Assertions.Assertion_Error;
+ when 2 => return (1 .. 4 => 'T');
+ when 3 => return (2 .. 8 => 'T');
+ when 4 => return "hello";
+ when others => return (1 .. 0 => <>);
+ end case;
+ end;
+
+ procedure Try (X : Natural) is
+ begin
+ declare
+ Code : String := Process (X);
+ begin
+ if X < 2 then
+ raise Program_Error;
+ end if;
+ end;
+ exception
+ when Ada.Assertions.Assertion_Error => null;
+ end;
+end;
diff --git a/gcc/testsuite/gnat.dg/casesi.ads b/gcc/testsuite/gnat.dg/casesi.ads
new file mode 100644
index 0000000..665fa11
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/casesi.ads
@@ -0,0 +1,4 @@
+
+package Casesi is
+ procedure Try (X : Natural);
+end;
diff --git a/gcc/testsuite/gnat.dg/discr56.adb b/gcc/testsuite/gnat.dg/discr56.adb
new file mode 100644
index 0000000..dc0ca7f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/discr56.adb
@@ -0,0 +1,5 @@
+-- { dg-do compile }
+
+package body Discr56 is
+ procedure Dummy is null;
+end Discr56;
diff --git a/gcc/testsuite/gnat.dg/discr56.ads b/gcc/testsuite/gnat.dg/discr56.ads
new file mode 100644
index 0000000..443f1bd
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/discr56.ads
@@ -0,0 +1,9 @@
+with Discr56_Pkg2;
+
+package Discr56 is
+
+ Obj : Discr56_Pkg2.Buffer (1);
+
+ procedure Dummy;
+
+end Discr56;
diff --git a/gcc/testsuite/gnat.dg/discr56_pkg1.adb b/gcc/testsuite/gnat.dg/discr56_pkg1.adb
new file mode 100644
index 0000000..67c329a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/discr56_pkg1.adb
@@ -0,0 +1,6 @@
+package body Discr56_Pkg1 is
+
+ protected body Buffer is
+ end Buffer;
+
+end Discr56_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/discr56_pkg1.ads b/gcc/testsuite/gnat.dg/discr56_pkg1.ads
new file mode 100644
index 0000000..3852632
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/discr56_pkg1.ads
@@ -0,0 +1,14 @@
+package Discr56_Pkg1 is
+
+ type Buffer (Size : Positive) is limited private;
+
+private
+
+ type Arr is array (Natural range <>) of Integer;
+
+ protected type Buffer (Size : Positive) is
+ private
+ Store : Arr (0..Size);
+ end Buffer;
+
+end Discr56_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/discr56_pkg2.ads b/gcc/testsuite/gnat.dg/discr56_pkg2.ads
new file mode 100644
index 0000000..dc94908
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/discr56_pkg2.ads
@@ -0,0 +1,11 @@
+with Discr56_Pkg1;
+
+package Discr56_Pkg2 is
+
+ type Buffer (Size : Positive) is limited private;
+
+private
+
+ type Buffer (Size : Positive) is new Discr56_Pkg1.Buffer (Size);
+
+end Discr56_Pkg2;
diff --git a/gcc/testsuite/gnat.dg/discr57.adb b/gcc/testsuite/gnat.dg/discr57.adb
new file mode 100644
index 0000000..cb5cecc
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/discr57.adb
@@ -0,0 +1,17 @@
+-- { dg-do compile }
+
+procedure Discr57 is
+
+ type T1(Scalar : Boolean) is abstract tagged null record;
+
+ subtype S1 is T1 (Scalar => False);
+
+ type T2(Lower_Bound : Natural) is new
+ S1 with null record;
+
+ Obj : constant T2 :=
+ (Lower_Bound => 123);
+
+begin
+ null;
+end Discr57;
diff --git a/gcc/testsuite/gnat.dg/elab8.adb b/gcc/testsuite/gnat.dg/elab8.adb
new file mode 100644
index 0000000..a54ba9d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/elab8.adb
@@ -0,0 +1,12 @@
+-- { dg-do compile }
+-- { dg-options "-gnatN" }
+
+with Elab8_Gen;
+
+procedure Elab8 is
+
+ package My_G is new Elab8_Gen (Integer);
+
+begin
+ My_G.Compare (0, 1);
+end;
diff --git a/gcc/testsuite/gnat.dg/elab8_gen.adb b/gcc/testsuite/gnat.dg/elab8_gen.adb
new file mode 100644
index 0000000..fbb09b9
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/elab8_gen.adb
@@ -0,0 +1,12 @@
+with Elab8_Pkg;
+
+package body Elab8_Gen is
+
+ procedure Compare (Arg1, Arg2 : T) is
+ begin
+ if Arg1 = Arg2 then
+ raise Program_Error;
+ end if;
+ end;
+
+end Elab8_Gen;
diff --git a/gcc/testsuite/gnat.dg/elab8_gen.ads b/gcc/testsuite/gnat.dg/elab8_gen.ads
new file mode 100644
index 0000000..8125407
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/elab8_gen.ads
@@ -0,0 +1,8 @@
+generic
+ type T is private;
+package Elab8_Gen is
+
+ procedure Compare (Arg1, Arg2 : T);
+ pragma Inline (Compare);
+
+end Elab8_Gen;
diff --git a/gcc/testsuite/gnat.dg/elab8_pkg.adb b/gcc/testsuite/gnat.dg/elab8_pkg.adb
new file mode 100644
index 0000000..451d4e4
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/elab8_pkg.adb
@@ -0,0 +1,5 @@
+package body Elab8_Pkg is
+
+ procedure Dummy is null;
+
+end Elab8_Pkg;
diff --git a/gcc/testsuite/gnat.dg/elab8_pkg.ads b/gcc/testsuite/gnat.dg/elab8_pkg.ads
new file mode 100644
index 0000000..8bf4603
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/elab8_pkg.ads
@@ -0,0 +1,5 @@
+package Elab8_Pkg with SPARK_Mode is
+
+ pragma Elaborate_Body;
+
+end Elab8_Pkg;
diff --git a/gcc/testsuite/gnat.dg/equal10.adb b/gcc/testsuite/gnat.dg/equal10.adb
new file mode 100644
index 0000000..9b61e5e
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal10.adb
@@ -0,0 +1,5 @@
+-- { dg-do compile }
+
+package body Equal10 is
+ procedure Dummy is null;
+end Equal10;
diff --git a/gcc/testsuite/gnat.dg/equal10.ads b/gcc/testsuite/gnat.dg/equal10.ads
new file mode 100644
index 0000000..28e1a21
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal10.ads
@@ -0,0 +1,7 @@
+package Equal10 is
+ type R is record X : Integer; end record;
+ Rr : R;
+ function "=" (Y : R; Z : Integer) return Boolean is
+ (Y.X = Z);
+ procedure Dummy;
+end Equal10;
diff --git a/gcc/testsuite/gnat.dg/equal11.adb b/gcc/testsuite/gnat.dg/equal11.adb
new file mode 100644
index 0000000..83cff18
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal11.adb
@@ -0,0 +1,37 @@
+-- { dg-do run }
+
+with Equal11_Record;
+
+procedure Equal11 is
+
+ use Equal11_Record;
+
+ R : My_Record_Type;
+ L : My_Record_Type_List_Pck.List;
+begin
+ -- Single record
+ R.F := 42;
+ R.Put;
+ if Put_Result /= 42 then
+ raise Program_Error;
+ end if;
+
+ -- List of records
+ L.Append ((F => 3));
+ L.Append ((F => 2));
+ L.Append ((F => 1));
+
+ declare
+ Expected : constant array (Positive range <>) of Integer :=
+ (3, 2, 1);
+ I : Positive := 1;
+ begin
+ for LR of L loop
+ LR.Put;
+ if Put_Result /= Expected (I) then
+ raise Program_Error;
+ end if;
+ I := I + 1;
+ end loop;
+ end;
+end Equal11;
diff --git a/gcc/testsuite/gnat.dg/equal11_interface.ads b/gcc/testsuite/gnat.dg/equal11_interface.ads
new file mode 100644
index 0000000..abc4415
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal11_interface.ads
@@ -0,0 +1,7 @@
+package Equal11_Interface is
+
+ type My_Interface_Type is interface;
+
+ procedure Put (R : in My_Interface_Type) is abstract;
+
+end Equal11_Interface;
diff --git a/gcc/testsuite/gnat.dg/equal11_record.adb b/gcc/testsuite/gnat.dg/equal11_record.adb
new file mode 100644
index 0000000..5528162
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal11_record.adb
@@ -0,0 +1,10 @@
+with Ada.Text_IO;
+
+package body Equal11_Record is
+
+ procedure Put (R : in My_Record_Type) is
+ begin
+ Put_Result := R.F;
+ end Put;
+
+end Equal11_Record;
diff --git a/gcc/testsuite/gnat.dg/equal11_record.ads b/gcc/testsuite/gnat.dg/equal11_record.ads
new file mode 100644
index 0000000..09a1822
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/equal11_record.ads
@@ -0,0 +1,21 @@
+with Ada.Containers.Doubly_Linked_Lists;
+with Equal11_Interface;
+
+package Equal11_Record is
+
+ use Equal11_Interface;
+
+ type My_Record_Type is new My_Interface_Type with
+ record
+ F : Integer;
+ end record;
+
+ overriding
+ procedure Put (R : in My_Record_Type);
+
+ Put_Result : Integer;
+
+ package My_Record_Type_List_Pck is
+ new Ada.Containers.Doubly_Linked_Lists (Element_Type => My_Record_Type);
+
+end Equal11_Record;
diff --git a/gcc/testsuite/gnat.dg/expr_func9.adb b/gcc/testsuite/gnat.dg/expr_func9.adb
new file mode 100644
index 0000000..4bfa21d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/expr_func9.adb
@@ -0,0 +1,24 @@
+-- { dg-do compile }
+-- { dg-options "-gnatws" }
+
+procedure Expr_Func9 is
+
+ type Root is interface;
+
+ type Child1 is new Root with null record;
+
+ type Child2 is new Root with record
+ I2 : Integer;
+ end record;
+
+ function Create (I : Integer) return Child2 is (I2 => I);
+
+ I : Root'Class :=
+ (if False
+ then Child1'(null record)
+ else
+ Create (1));
+
+begin
+ null;
+end Expr_Func9;
diff --git a/gcc/testsuite/gnat.dg/float_value1.adb b/gcc/testsuite/gnat.dg/float_value1.adb
index 8e36767..df7761e 100644
--- a/gcc/testsuite/gnat.dg/float_value1.adb
+++ b/gcc/testsuite/gnat.dg/float_value1.adb
@@ -1,4 +1,4 @@
--- { dg-do run }
+-- { dg-do run { target i?86-*-* x86_64-*-* } }
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
diff --git a/gcc/testsuite/gnat.dg/generic_inst10.adb b/gcc/testsuite/gnat.dg/generic_inst10.adb
new file mode 100644
index 0000000..75bb65a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst10.adb
@@ -0,0 +1,26 @@
+-- { dg-do compile }
+
+with Generic_Inst10_Pkg; use Generic_Inst10_Pkg;
+
+procedure Generic_Inst10 is
+
+ function Image (S : XString) return String is (S.To_String);
+
+ generic
+ type Left_Type (<>) is private;
+ type Right_Type (<>) is private;
+ with function Image (L : Left_Type) return String is <>;
+ with function Image (L : Right_Type) return String is <>;
+ procedure G (Left : Left_Type; Right : Right_Type);
+
+ procedure G (Left : Left_Type; Right : Right_Type) is
+ A : String := Image (Left) & Image (Right);
+ begin
+ null;
+ end;
+
+ procedure My_G is new G (XString, XString);
+
+begin
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/generic_inst10_pkg.ads b/gcc/testsuite/gnat.dg/generic_inst10_pkg.ads
new file mode 100644
index 0000000..d9009ac
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst10_pkg.ads
@@ -0,0 +1,11 @@
+package Generic_Inst10_Pkg is
+
+ type XString is tagged private;
+
+ function To_String (S : XString) return String;
+
+private
+
+ type XString is tagged null record;
+
+end Generic_Inst10_Pkg;
diff --git a/gcc/testsuite/gnat.dg/generic_inst11.adb b/gcc/testsuite/gnat.dg/generic_inst11.adb
new file mode 100644
index 0000000..75c19a5
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst11.adb
@@ -0,0 +1,9 @@
+-- { dg-do compile }
+-- { dg-options "-O -gnatn" }
+
+with Generic_Inst11_Pkg;
+
+procedure Generic_Inst11 is
+begin
+ Generic_Inst11_Pkg.Proc;
+end;
diff --git a/gcc/testsuite/gnat.dg/generic_inst11_pkg.adb b/gcc/testsuite/gnat.dg/generic_inst11_pkg.adb
new file mode 100644
index 0000000..b90f8bb
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst11_pkg.adb
@@ -0,0 +1,21 @@
+with System;
+
+package body Generic_Inst11_Pkg is
+
+ Data : Integer;
+
+ generic
+ Reg_Address : System.Address;
+ procedure Inner_G with Inline;
+
+ procedure Inner_G is
+ Reg : Integer with Address => Reg_Address;
+ begin
+ null;
+ end;
+
+ procedure My_Inner_G is new Inner_G (Data'Address);
+
+ procedure Proc renames My_Inner_G;
+
+end Generic_Inst11_Pkg;
diff --git a/gcc/testsuite/gnat.dg/generic_inst11_pkg.ads b/gcc/testsuite/gnat.dg/generic_inst11_pkg.ads
new file mode 100644
index 0000000..07ee9f6
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst11_pkg.ads
@@ -0,0 +1,5 @@
+package Generic_Inst11_Pkg is
+
+ procedure Proc with Inline;
+
+end Generic_Inst11_Pkg;
diff --git a/gcc/testsuite/gnat.dg/generic_inst12.adb b/gcc/testsuite/gnat.dg/generic_inst12.adb
new file mode 100644
index 0000000..4f99749
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst12.adb
@@ -0,0 +1,12 @@
+-- { dg-do run }
+-- { dg-options "-O -gnatn" }
+with Generic_Inst12_Pkg2;
+
+procedure Generic_Inst12 is
+
+ procedure My_Inner_G is new Generic_Inst12_Pkg2.Inner_G;
+
+begin
+ My_Inner_G (1);
+ Generic_Inst12_Pkg2.Proc (1);
+end;
diff --git a/gcc/testsuite/gnat.dg/generic_inst12_pkg1.adb b/gcc/testsuite/gnat.dg/generic_inst12_pkg1.adb
new file mode 100644
index 0000000..e4eced5
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst12_pkg1.adb
@@ -0,0 +1,13 @@
+package body Generic_Inst12_Pkg1 is
+
+ procedure Inner_G (Val : T) is
+ begin
+ null;
+ end;
+
+ procedure Proc (Val : T) is
+ begin
+ null;
+ end;
+
+end Generic_Inst12_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/generic_inst12_pkg1.ads b/gcc/testsuite/gnat.dg/generic_inst12_pkg1.ads
new file mode 100644
index 0000000..27de7cb
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst12_pkg1.ads
@@ -0,0 +1,11 @@
+generic
+ type T is private;
+package Generic_Inst12_Pkg1 is
+
+ generic
+ procedure Inner_G (Val : T);
+
+ procedure Proc (Val : T);
+ pragma Inline (Proc);
+
+end Generic_Inst12_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/generic_inst12_pkg2.ads b/gcc/testsuite/gnat.dg/generic_inst12_pkg2.ads
new file mode 100644
index 0000000..60519ad
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst12_pkg2.ads
@@ -0,0 +1,3 @@
+with Generic_Inst12_Pkg1;
+
+package Generic_Inst12_Pkg2 is new Generic_Inst12_Pkg1 (Integer);
diff --git a/gcc/testsuite/gnat.dg/generic_inst7.adb b/gcc/testsuite/gnat.dg/generic_inst7.adb
new file mode 100644
index 0000000..d56e479
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst7.adb
@@ -0,0 +1,11 @@
+-- { dg-do compile }
+
+with Generic_Inst7_Pkg;
+
+procedure Generic_Inst7 is
+
+ package Inst is new Generic_Inst7_Pkg;
+
+begin
+ null;
+end Generic_Inst7;
diff --git a/gcc/testsuite/gnat.dg/generic_inst7_pkg.adb b/gcc/testsuite/gnat.dg/generic_inst7_pkg.adb
new file mode 100644
index 0000000..261ffea
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst7_pkg.adb
@@ -0,0 +1,12 @@
+package body Generic_Inst7_Pkg is
+
+ use type Generic_Inst7_Types.Index;
+
+ procedure Process (List : in out Generic_Inst7_Types.List) is
+ begin
+ for I in Generic_Inst7_Types.Index range 1 .. List.Arr'length loop
+ null;
+ end loop;
+ end Process;
+
+end Generic_Inst7_Pkg;
diff --git a/gcc/testsuite/gnat.dg/generic_inst7_pkg.ads b/gcc/testsuite/gnat.dg/generic_inst7_pkg.ads
new file mode 100644
index 0000000..7bc4abc
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst7_pkg.ads
@@ -0,0 +1,8 @@
+with Generic_Inst7_Types;
+
+generic
+package Generic_Inst7_Pkg is
+
+ procedure Process (List : in out Generic_Inst7_Types.List);
+
+end Generic_Inst7_Pkg;
diff --git a/gcc/testsuite/gnat.dg/generic_inst7_types.ads b/gcc/testsuite/gnat.dg/generic_inst7_types.ads
new file mode 100644
index 0000000..34d782d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst7_types.ads
@@ -0,0 +1,15 @@
+package Generic_Inst7_Types is
+
+ type Index is new Integer range 0 .. 10;
+
+ type Element is record
+ I : Integer;
+ end record;
+
+ type Element_Array is array (Index range <>) of Element;
+
+ type List (Size : Index := 1) is record
+ Arr : Element_Array (1 .. Size);
+ end record;
+
+end Generic_Inst7_Types;
diff --git a/gcc/testsuite/gnat.dg/generic_inst8.adb b/gcc/testsuite/gnat.dg/generic_inst8.adb
new file mode 100644
index 0000000..5536f0b
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst8.adb
@@ -0,0 +1,8 @@
+-- { dg-do compile }
+-- { dg-options "-gnatn" }
+
+package body Generic_Inst8 is
+
+ package My_G is new Generic_Inst8_G (0);
+
+end Generic_Inst8;
diff --git a/gcc/testsuite/gnat.dg/generic_inst8.ads b/gcc/testsuite/gnat.dg/generic_inst8.ads
new file mode 100644
index 0000000..d6491e3
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst8.ads
@@ -0,0 +1,7 @@
+with Generic_Inst8_G;
+
+package Generic_Inst8 is
+
+ pragma Elaborate_Body;
+
+end Generic_Inst8;
diff --git a/gcc/testsuite/gnat.dg/generic_inst8_g.adb b/gcc/testsuite/gnat.dg/generic_inst8_g.adb
new file mode 100644
index 0000000..dab7b62
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst8_g.adb
@@ -0,0 +1,12 @@
+package body Generic_Inst8_G is
+
+ package body First is
+
+ function Get (Data : T) return T is
+ begin
+ return Data;
+ end;
+
+ end First;
+
+end Generic_Inst8_G;
diff --git a/gcc/testsuite/gnat.dg/generic_inst8_g.ads b/gcc/testsuite/gnat.dg/generic_inst8_g.ads
new file mode 100644
index 0000000..087a9e6
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst8_g.ads
@@ -0,0 +1,17 @@
+generic
+ N : Natural;
+package Generic_Inst8_G is
+
+ generic
+ type T is private;
+ package First is
+ function Get (Data : T) return T with Inline;
+ end First;
+
+ generic
+ type T is private;
+ package Second is
+ package My_First is new First (T);
+ end Second;
+
+end Generic_Inst8_G;
diff --git a/gcc/testsuite/gnat.dg/generic_inst9.adb b/gcc/testsuite/gnat.dg/generic_inst9.adb
new file mode 100644
index 0000000..1a5bbaf
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst9.adb
@@ -0,0 +1,5 @@
+-- { dg-do compile }
+
+package body Generic_Inst9 is
+ procedure Dummy is null;
+end Generic_Inst9;
diff --git a/gcc/testsuite/gnat.dg/generic_inst9.ads b/gcc/testsuite/gnat.dg/generic_inst9.ads
new file mode 100644
index 0000000..ace5566
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst9.ads
@@ -0,0 +1,11 @@
+with Generic_Inst9_Pkg2;
+with Generic_Inst9_Pkg1; use Generic_Inst9_Pkg1;
+
+package Generic_Inst9 is
+
+ package Partition is new Generic_Inst9_Pkg2
+ (Item_T => Generic_Inst9_Pkg1.R, Bound_T => Generic_Inst9_Pkg1.R);
+
+ procedure Dummy;
+
+end Generic_Inst9;
diff --git a/gcc/testsuite/gnat.dg/generic_inst9_pkg1-operator.ads b/gcc/testsuite/gnat.dg/generic_inst9_pkg1-operator.ads
new file mode 100644
index 0000000..f6bb43f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst9_pkg1-operator.ads
@@ -0,0 +1,10 @@
+generic
+ type T is private;
+ with function Compare
+ (Left, Right: T) return Generic_Inst9_Pkg1.T is <>;
+package Generic_Inst9_Pkg1.Operator is
+ function Compare (Left, Right: Integer) return Generic_Inst9_Pkg1.T is
+ (Equal);
+ function "<" (Left, Right: T) return Boolean is
+ (Compare (Left, Right) = Smaller);
+end Generic_Inst9_Pkg1.Operator;
diff --git a/gcc/testsuite/gnat.dg/generic_inst9_pkg1.ads b/gcc/testsuite/gnat.dg/generic_inst9_pkg1.ads
new file mode 100644
index 0000000..50b62f1
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst9_pkg1.ads
@@ -0,0 +1,12 @@
+
+package Generic_Inst9_Pkg1 is
+
+ type T is (None, Smaller, Equal, Larger);
+
+ type R is record
+ Val : Integer;
+ end record;
+
+ function Compare (Left, Right : R) return T;
+
+end;
diff --git a/gcc/testsuite/gnat.dg/generic_inst9_pkg2.adb b/gcc/testsuite/gnat.dg/generic_inst9_pkg2.adb
new file mode 100644
index 0000000..d008888
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst9_pkg2.adb
@@ -0,0 +1,9 @@
+with Generic_Inst9_Pkg1.Operator;
+
+package body Generic_Inst9_Pkg2 is
+
+ package My_Operator is new Generic_Inst9_Pkg1.Operator (Bound_T);
+
+ procedure Dummy is begin null; end;
+
+end Generic_Inst9_Pkg2;
diff --git a/gcc/testsuite/gnat.dg/generic_inst9_pkg2.ads b/gcc/testsuite/gnat.dg/generic_inst9_pkg2.ads
new file mode 100644
index 0000000..4bd3dcc
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/generic_inst9_pkg2.ads
@@ -0,0 +1,17 @@
+with Generic_Inst9_Pkg1;
+
+generic
+
+ type Item_T is private;
+ with function Compare
+ (Left, Right: Item_T) return Generic_Inst9_Pkg1.T is <>;
+
+ type Bound_T is private;
+ with function Compare
+ (Left, Right : Bound_T) return Generic_Inst9_Pkg1.T is <>;
+
+package Generic_Inst9_Pkg2 is
+
+ procedure Dummy;
+
+end Generic_Inst9_Pkg2;
diff --git a/gcc/testsuite/gnat.dg/inline18.adb b/gcc/testsuite/gnat.dg/inline18.adb
new file mode 100644
index 0000000..29b3d45
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline18.adb
@@ -0,0 +1,6 @@
+-- { dg-do compile }
+-- { dg-options "-O -gnatn" }
+
+package body Inline18 is
+ procedure Dummy is null;
+end Inline18;
diff --git a/gcc/testsuite/gnat.dg/inline18.ads b/gcc/testsuite/gnat.dg/inline18.ads
new file mode 100644
index 0000000..435ee7f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline18.ads
@@ -0,0 +1,6 @@
+with Inline18_Pkg1; use Inline18_Pkg1;
+
+package Inline18 is
+ I : Integer := My_G.Next (0);
+ procedure Dummy;
+end Inline18;
diff --git a/gcc/testsuite/gnat.dg/inline18_gen1-inner_g.ads b/gcc/testsuite/gnat.dg/inline18_gen1-inner_g.ads
new file mode 100644
index 0000000..2c6544d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline18_gen1-inner_g.ads
@@ -0,0 +1,8 @@
+generic
+package Inline18_Gen1.Inner_G is
+
+ type T is new Inline18_Gen1.T;
+
+ Val : T;
+
+end Inline18_Gen1.Inner_G;
diff --git a/gcc/testsuite/gnat.dg/inline18_gen1.adb b/gcc/testsuite/gnat.dg/inline18_gen1.adb
new file mode 100644
index 0000000..3352624
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline18_gen1.adb
@@ -0,0 +1,9 @@
+package body Inline18_Gen1 is
+
+ function Complete return T is
+ Dummy : T;
+ begin
+ return Dummy;
+ end;
+
+end Inline18_Gen1;
diff --git a/gcc/testsuite/gnat.dg/inline18_gen1.ads b/gcc/testsuite/gnat.dg/inline18_gen1.ads
new file mode 100644
index 0000000..54e5693
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline18_gen1.ads
@@ -0,0 +1,14 @@
+generic
+
+ type Bound_T is private;
+
+package Inline18_Gen1 is
+
+ type T is private;
+ function Complete return T with Inline_Always;
+
+private
+
+ type T is array (0 .. 1) of Bound_T;
+
+end Inline18_Gen1;
diff --git a/gcc/testsuite/gnat.dg/inline18_gen2.adb b/gcc/testsuite/gnat.dg/inline18_gen2.adb
new file mode 100644
index 0000000..fe09fd0
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline18_gen2.adb
@@ -0,0 +1,10 @@
+package body Inline18_Gen2 is
+
+ function Func (I : Interval_T) return T is
+ pragma Unreferenced (I);
+ Dummy : T;
+ begin
+ return Dummy;
+ end;
+
+end Inline18_Gen2;
diff --git a/gcc/testsuite/gnat.dg/inline18_gen2.ads b/gcc/testsuite/gnat.dg/inline18_gen2.ads
new file mode 100644
index 0000000..ca6302b
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline18_gen2.ads
@@ -0,0 +1,11 @@
+generic
+
+ type Interval_T is private;
+
+package Inline18_Gen2 is
+
+ type T is new Integer;
+
+ function Func (I : Interval_T) return T;
+
+end Inline18_Gen2;
diff --git a/gcc/testsuite/gnat.dg/inline18_gen3.adb b/gcc/testsuite/gnat.dg/inline18_gen3.adb
new file mode 100644
index 0000000..4f786c2
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline18_gen3.adb
@@ -0,0 +1,12 @@
+package body Inline18_Gen3 is
+
+ package body Inner_G is
+
+ function Next (Position : Index_T) return Index_T is
+ begin
+ return Position;
+ end;
+
+ end Inner_G;
+
+end Inline18_Gen3;
diff --git a/gcc/testsuite/gnat.dg/inline18_gen3.ads b/gcc/testsuite/gnat.dg/inline18_gen3.ads
new file mode 100644
index 0000000..798df5f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline18_gen3.ads
@@ -0,0 +1,13 @@
+generic
+
+ type Index_T is range <>;
+
+package Inline18_Gen3 is
+
+ generic
+ package Inner_G is
+ function Next (Position : Index_T) return Index_T;
+ pragma Inline (Next);
+ end Inner_G;
+
+end Inline18_Gen3;
diff --git a/gcc/testsuite/gnat.dg/inline18_pkg1.adb b/gcc/testsuite/gnat.dg/inline18_pkg1.adb
new file mode 100644
index 0000000..f266f09
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline18_pkg1.adb
@@ -0,0 +1,8 @@
+package body Inline18_Pkg1 is
+
+ procedure Proc (R : in out Rec) is
+ begin
+ R.Comp := My_G2.Func (Inline18_Pkg2.Child.General.Val);
+ end;
+
+end Inline18_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/inline18_pkg1.ads b/gcc/testsuite/gnat.dg/inline18_pkg1.ads
new file mode 100644
index 0000000..a0c184c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline18_pkg1.ads
@@ -0,0 +1,19 @@
+with Inline18_Pkg2.Child;
+with Inline18_Gen2;
+with Inline18_Gen3;
+
+package Inline18_Pkg1 is
+
+ package My_G2 is new Inline18_Gen2 (Inline18_Pkg2.Child.General.T);
+
+ package My_G3 is new Inline18_Gen3 (Integer);
+
+ type Rec is record
+ Comp : My_G2.T;
+ end record;
+
+ procedure Proc (R : in out Rec);
+
+ package My_G is new My_G3.Inner_G;
+
+end Inline18_Pkg1;
diff --git a/gcc/testsuite/gnat.dg/inline18_pkg2-child.ads b/gcc/testsuite/gnat.dg/inline18_pkg2-child.ads
new file mode 100644
index 0000000..21f1ba1
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline18_pkg2-child.ads
@@ -0,0 +1,9 @@
+with Inline18_Gen1.Inner_G;
+
+package Inline18_Pkg2.Child is
+
+ package Base is new Inline18_Gen1 (Integer);
+
+ package General is new Base.Inner_G;
+
+end Inline18_Pkg2.Child;
diff --git a/gcc/testsuite/gnat.dg/inline18_pkg2.ads b/gcc/testsuite/gnat.dg/inline18_pkg2.ads
new file mode 100644
index 0000000..ae48bfc
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline18_pkg2.ads
@@ -0,0 +1,2 @@
+package Inline18_Pkg2 is
+end Inline18_Pkg2;
diff --git a/gcc/testsuite/gnat.dg/inline19.adb b/gcc/testsuite/gnat.dg/inline19.adb
new file mode 100644
index 0000000..01be738
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline19.adb
@@ -0,0 +1,17 @@
+-- { dg-do compile }
+-- { dg-options "-O2" }
+
+package body Inline19 is
+
+ S : String := "Hello";
+
+ protected body P is
+ function F return String is
+ begin
+ return Result : constant String := S do
+ null;
+ end return;
+ end F;
+ end P;
+
+end Inline19;
diff --git a/gcc/testsuite/gnat.dg/inline19.ads b/gcc/testsuite/gnat.dg/inline19.ads
new file mode 100644
index 0000000..7a2d35c
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/inline19.ads
@@ -0,0 +1,8 @@
+package Inline19 is
+
+ protected P is
+ function F return String;
+ pragma Inline (F);
+ end P;
+
+end Inline19;
diff --git a/gcc/testsuite/gnat.dg/no_caching.adb b/gcc/testsuite/gnat.dg/no_caching.adb
new file mode 100644
index 0000000..446dbd6
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/no_caching.adb
@@ -0,0 +1,29 @@
+-- { dg-do compile }
+
+package body No_Caching with SPARK_Mode is
+ Status : Boolean;
+
+ procedure Handle (V : Mult_Bit_Boolean) is
+ Ret_Val : Mult_Bit_Boolean := V with Volatile, No_Caching;
+ begin
+ if (Ret_Val = NV_TRUE) then
+ Do_Something;
+ elsif (Ret_Val = NV_FALSE) then
+ Do_Something_Else;
+ else
+ null;
+ -- Fault inject detected. Take punitive action
+ end if;
+ end Handle;
+
+ procedure Do_Something is
+ begin
+ Status := True;
+ end Do_Something;
+
+ procedure Do_Something_Else is
+ begin
+ Status := False;
+ end Do_Something_Else;
+
+end No_Caching;
diff --git a/gcc/testsuite/gnat.dg/no_caching.ads b/gcc/testsuite/gnat.dg/no_caching.ads
new file mode 100644
index 0000000..24a9cd3
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/no_caching.ads
@@ -0,0 +1,8 @@
+package No_Caching with SPARK_Mode is
+ type Mult_Bit_Boolean is (NV_FALSE, NV_TRUE);
+ for Mult_Bit_Boolean use (NV_FALSE => 16#55_AA#,
+ NV_TRUE => 16#AA_55#);
+ procedure Handle (V : Mult_Bit_Boolean);
+ procedure Do_Something;
+ procedure Do_Something_Else;
+end No_Caching;
diff --git a/gcc/testsuite/gnat.dg/null_check.adb b/gcc/testsuite/gnat.dg/null_check.adb
new file mode 100644
index 0000000..c335c06
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/null_check.adb
@@ -0,0 +1,19 @@
+-- { dg-do run }
+
+procedure Null_Check with SPARK_Mode is
+ type Int_Ptr is access Integer;
+ subtype Not_Null_Int_Ptr is not null Int_Ptr;
+
+ procedure Set_To_Null (X : out Int_Ptr) with Global => null is
+ begin
+ X := null;
+ end Set_To_Null;
+
+ X : Not_Null_Int_Ptr := new Integer'(12);
+begin
+ Set_To_Null (X);
+ raise Program_Error;
+exception
+ when Constraint_Error =>
+ null;
+end Null_Check;
diff --git a/gcc/testsuite/gnat.dg/openacc1.adb b/gcc/testsuite/gnat.dg/openacc1.adb
new file mode 100644
index 0000000..ce27a5f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/openacc1.adb
@@ -0,0 +1,12 @@
+-- { dg-do compile }
+
+procedure OpenAcc1 is
+ type Integer_Array is array (1 .. 32) of Integer;
+ Data : Integer_Array;
+begin
+ for i in Data'Range loop
+ pragma Acc_Parallel;
+ pragma Acc_Loop(Worker);
+ Data (i) := i;
+ end loop;
+end;
diff --git a/gcc/testsuite/gnat.dg/opt81.adb b/gcc/testsuite/gnat.dg/opt81.adb
new file mode 100644
index 0000000..057d846
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt81.adb
@@ -0,0 +1,20 @@
+-- { dg-do compile }
+-- { dg-options "-O -gnatws" }
+
+with Unchecked_Conversion;
+
+package body Opt81 is
+
+ procedure Copy (From, To : Rec) is
+ Len : constant Natural := From.A.all'Length;
+ subtype Fixed_String is String (1 .. Len);
+ type Fixed_String_Access is access Fixed_String;
+ function To_Fixed is new
+ Unchecked_Conversion (Source => String_Access,
+ Target => Fixed_String_Access);
+ S : Fixed_String_Access := To_Fixed (To.A);
+ begin
+ S (1 .. Len) := From.A.all;
+ end;
+
+end Opt81;
diff --git a/gcc/testsuite/gnat.dg/opt81.ads b/gcc/testsuite/gnat.dg/opt81.ads
new file mode 100644
index 0000000..743dcc2
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt81.ads
@@ -0,0 +1,15 @@
+package Opt81 is
+
+ type String_Access is access String;
+
+ type Rec is record
+ A : String_Access;
+ end record;
+
+ for Rec use record
+ A at 0 range 0 .. (Standard'Word_Size - 1);
+ end record;
+
+ procedure Copy(From, To : Rec);
+
+end Opt81;
diff --git a/gcc/testsuite/gnat.dg/predicate12.adb b/gcc/testsuite/gnat.dg/predicate12.adb
new file mode 100644
index 0000000..3c076c0
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate12.adb
@@ -0,0 +1,6 @@
+-- { dg-do compile }
+-- { dg-options "-gnata" }
+
+package body Predicate12 is
+ procedure Dummy is null;
+end Predicate12;
diff --git a/gcc/testsuite/gnat.dg/predicate12.ads b/gcc/testsuite/gnat.dg/predicate12.ads
new file mode 100644
index 0000000..f51e649
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/predicate12.ads
@@ -0,0 +1,42 @@
+package Predicate12 is
+
+ subtype Index_Type is Positive range 1 .. 100;
+ type Array_Type is array(Index_Type) of Integer;
+
+ type Search_Engine is interface;
+
+ procedure Search
+ (S : in Search_Engine;
+ Search_Item : in Integer;
+ Items : in Array_Type;
+ Found : out Boolean;
+ Result : out Index_Type) is abstract
+ with
+ Pre'Class =>
+ (for all J in Items'Range =>
+ (for all K in J + 1 .. Items'Last => Items(J) <= Items(K))),
+ Post'Class =>
+ (if Found then Search_Item = Items(Result)
+ else (for all J in Items'Range => Items(J) /= Search_Item));
+
+ type Binary_Search_Engine is new Search_Engine with null record;
+
+ procedure Search
+ (S : in Binary_Search_Engine;
+ Search_Item : in Integer;
+ Items : in Array_Type;
+ Found : out Boolean;
+ Result : out Index_Type) is null;
+
+ type Forward_Search_Engine is new Search_Engine with null record;
+
+ procedure Search
+ (S : in Forward_Search_Engine;
+ Search_Item : in Integer;
+ Items : in Array_Type;
+ Found : out Boolean;
+ Result : out Index_Type) is null;
+
+ procedure Dummy;
+
+end Predicate12;
diff --git a/gcc/testsuite/gnat.dg/range_check6.adb b/gcc/testsuite/gnat.dg/range_check6.adb
new file mode 100644
index 0000000..00fa705
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/range_check6.adb
@@ -0,0 +1,28 @@
+-- { dg-do run }
+-- { dg-options "-O0 -gnatVa" }
+
+procedure Range_Check6 is
+
+ type Byte is range -2**7 .. 2**7-1;
+ for Byte'Size use 8;
+
+ subtype Hour is Byte range 0 .. 23;
+
+ type Rec is record
+ B : Byte;
+ end record;
+
+ procedure Encode (H : in out Hour) is
+ begin
+ null;
+ end;
+
+ R : Rec;
+
+begin
+ R.B := 24;
+ Encode (R.B);
+ raise Program_Error;
+exception
+ when Constraint_Error => null;
+end;
diff --git a/gcc/testsuite/gnat.dg/range_check7.adb b/gcc/testsuite/gnat.dg/range_check7.adb
new file mode 100644
index 0000000..def43c9
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/range_check7.adb
@@ -0,0 +1,22 @@
+-- { dg-do compile }
+-- { dg-options "-gnatVa" }
+
+procedure Range_Check7 is
+
+ type Short is range -32768 .. 32767;
+
+ type Int is range -2 ** 31 .. 2 ** 31 - 1;
+
+ subtype Nat is Int range 0 .. Int'Last;
+
+ type Ptr is access all Short;
+
+ procedure Proc (P : Ptr) is
+ N : constant Nat := Nat (P.all);
+ begin
+ null;
+ end;
+
+begin
+ null;
+end;
diff --git a/gcc/testsuite/gnat.dg/renaming15.adb b/gcc/testsuite/gnat.dg/renaming15.adb
new file mode 100644
index 0000000..a0b13cd
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/renaming15.adb
@@ -0,0 +1,32 @@
+-- { dg-do compile }
+
+with Ada.Containers.Hashed_Maps;
+with Ada.Text_IO;
+
+procedure Renaming15 is
+ use Ada.Containers;
+
+ subtype String_T is String (1 .. 3);
+
+ function Hash (Aircraft_Id : Integer) return Hash_Type is
+ (Hash_Type (Aircraft_Id) * (2 ** 31 - 1));
+ function Equal (Left, Right : Integer) return Boolean is (Left = Right);
+ package Radar_Map is new Hashed_Maps (Integer, String_T, Hash, Equal);
+
+ Radars : Radar_Map.Map;
+
+ procedure Change_Elem_Value is
+ begin
+ for C in Radars.Iterate loop
+ declare
+ E : String_T renames Radar_Map.Element (C);
+ begin
+ E := "Xyz"; -- { dg-error "left hand side of assignment must be a variable" }
+ Ada.Text_IO.Put_Line (E);
+ end;
+ end loop;
+ end Change_Elem_Value;
+begin
+ Radars.Include (1, "jjj");
+ Change_Elem_Value;
+end Renaming15;
diff --git a/gcc/testsuite/gnat.dg/rep_clause9.adb b/gcc/testsuite/gnat.dg/rep_clause9.adb
new file mode 100644
index 0000000..e7a350e
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/rep_clause9.adb
@@ -0,0 +1,23 @@
+-- { dg-do run }
+
+procedure Rep_Clause9 is
+
+ type Day_Of_Week
+ is (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday);
+
+ type New_Day_Of_Week is new Day_Of_Week range Monday .. Friday;
+ for New_Day_Of_Week use
+ (Sunday => -4, Monday => -2, Tuesday => 1, Wednesday => 100,
+ Thursday => 1000, Friday => 10000, Saturday => 10001);
+
+ V1 : New_Day_Of_Week;
+
+begin
+ if Integer'Image(New_Day_Of_Week'Pos(Monday)) /= " 1" then
+ raise Program_Error;
+ end if;
+ V1 := Monday;
+ if Integer'Image(New_Day_Of_Week'Pos(V1)) /= " 1" then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/slice10.adb b/gcc/testsuite/gnat.dg/slice10.adb
new file mode 100644
index 0000000..4793258
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/slice10.adb
@@ -0,0 +1,29 @@
+-- { dg-do run }
+
+procedure Slice10 is
+
+ subtype Str is String (1 .. 3);
+
+ type T is record
+ B : Boolean;
+ S : Str;
+ end record;
+
+ for T use record
+ B at 0 range 0 .. 0;
+ S at 0 range 1 .. 24;
+ end record;
+
+ function Match (X, Y: T; Length : Positive) return Boolean is
+ begin
+ return X.S (1 .. Length) = Y.S (1 .. Length);
+ end;
+
+ X, Y : T := (B => True, S => "123");
+
+begin
+ X.B := False;
+ if not match (X, Y, 3) then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/suppress_initialization2.adb b/gcc/testsuite/gnat.dg/suppress_initialization2.adb
new file mode 100644
index 0000000..a54272e
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/suppress_initialization2.adb
@@ -0,0 +1,5 @@
+package body Suppress_Initialization2 is
+
+ procedure Dummy is null;
+
+end Suppress_Initialization2;
diff --git a/gcc/testsuite/gnat.dg/suppress_initialization2.ads b/gcc/testsuite/gnat.dg/suppress_initialization2.ads
new file mode 100644
index 0000000..2594ab1
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/suppress_initialization2.ads
@@ -0,0 +1,13 @@
+pragma Initialize_Scalars;
+
+with System;
+
+package Suppress_Initialization2 is
+
+ subtype Sub_Addr is System.Address with Suppress_Initialization;
+
+ O : Sub_Addr with Thread_Local_Storage; -- OK: no error should be reported
+
+ procedure Dummy;
+
+end Suppress_Initialization2;
diff --git a/gcc/testsuite/gnat.dg/tag2.adb b/gcc/testsuite/gnat.dg/tag2.adb
new file mode 100644
index 0000000..77e4842
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/tag2.adb
@@ -0,0 +1,20 @@
+-- { dg-do run }
+
+with Ada.Tags; use Ada.Tags;
+with Tag2_Pkg; use Tag2_Pkg;
+
+procedure Tag2 is
+
+ procedure Do_Add_Monitor (Monitor : in out Synchronous_Monitor) is
+ Name : constant String :=
+ Expanded_Name (Monitor_Interface'Class (Monitor)'Tag);
+ begin
+ if Name /= "TAG2_PKG.VIRTUAL_INTEGER_REGISTER_REFRESHER" then
+ raise Program_Error;
+ end if;
+ end;
+
+ Obj : Virtual_Integer_Register_Refresher (20);
+begin
+ Do_Add_Monitor (Synchronous_Monitor (Obj));
+end;
diff --git a/gcc/testsuite/gnat.dg/tag2_pkg.ads b/gcc/testsuite/gnat.dg/tag2_pkg.ads
new file mode 100644
index 0000000..3fd5923
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/tag2_pkg.ads
@@ -0,0 +1,16 @@
+package Tag2_Pkg is
+ type Monitor_Interface is interface;
+
+ type Root is abstract tagged null record;
+
+ type Monitor_Type is abstract new Root
+ and Monitor_Interface with null record;
+
+ type Synchronous_Monitor (Size : Positive) is new Monitor_Type with
+ record
+ Queue : String (1 .. Size);
+ end record;
+
+ type Virtual_Integer_Register_Refresher (Size : Positive) is
+ new Synchronous_Monitor (Size) with null record;
+end;
diff --git a/gcc/testsuite/gnat.dg/tagged3.adb b/gcc/testsuite/gnat.dg/tagged3.adb
new file mode 100644
index 0000000..1468ee2
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/tagged3.adb
@@ -0,0 +1,42 @@
+-- { dg-do run }
+
+with Tagged3_Pkg; use Tagged3_Pkg;
+procedure Tagged3 is
+ package SP is
+ type Ref is tagged private;
+
+ procedure Set (Self : in out Ref'Class; Data : Parent'Class);
+
+ type Reference_Type (Element : access Parent'Class)
+ is limited null record with Implicit_Dereference => Element;
+
+ function Get (Self : Ref'Class) return Reference_Type;
+
+ private
+ type Element_Access is access all Parent'Class;
+ type Ref is tagged record
+ Data : Element_Access;
+ end record;
+ end;
+
+ package body SP is
+ procedure Set (Self : in out Ref'Class; Data : Parent'Class) is
+ begin
+ Self.Data := new Parent'Class'(Data);
+ end;
+
+ function Get (Self : Ref'Class) return Reference_Type is
+ begin
+ return Reference_Type'(Element => Self.Data);
+ end;
+ end;
+
+ DC : Child;
+ RC : SP.Ref;
+begin
+ RC.Set (DC);
+ Prim1 (RC.Get.Element); -- Test
+ if not Tagged3_Pkg.Child_Prim1_Called then
+ raise Program_Error;
+ end if;
+end;
diff --git a/gcc/testsuite/gnat.dg/tagged3_pkg.adb b/gcc/testsuite/gnat.dg/tagged3_pkg.adb
new file mode 100644
index 0000000..c4629af
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/tagged3_pkg.adb
@@ -0,0 +1,12 @@
+with Ada.Text_IO; use Ada.Text_IO;
+package body Tagged3_Pkg is
+ procedure Prim1 (Self : access Parent) is
+ begin
+ raise Program_Error;
+ end;
+
+ procedure Prim1 (Self : access Child) is
+ begin
+ Child_Prim1_Called := True;
+ end;
+end;
diff --git a/gcc/testsuite/gnat.dg/tagged3_pkg.ads b/gcc/testsuite/gnat.dg/tagged3_pkg.ads
new file mode 100644
index 0000000..d32afe2
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/tagged3_pkg.ads
@@ -0,0 +1,9 @@
+package Tagged3_Pkg is
+ type Parent is tagged null record;
+ procedure Prim1 (Self : access Parent);
+
+ type Child is new Parent with null record;
+ procedure Prim1 (Self : access Child);
+
+ Child_Prim1_Called : Boolean := False;
+end;
diff --git a/gcc/testsuite/gnat.dg/tagged4.adb b/gcc/testsuite/gnat.dg/tagged4.adb
new file mode 100644
index 0000000..7611b9e
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/tagged4.adb
@@ -0,0 +1,28 @@
+-- { dg-do compile }
+
+procedure Tagged4 is
+ type T0 is tagged null record;
+
+ generic
+ type F1 is tagged private;
+ procedure Gen1;
+
+ procedure Gen1 is
+ type Inst1 is new F1 with null record; -- { dg-error "ancestor type \"F1\" is formal type of enclosing generic unit \\(RM 3\\.9\\.1 \\(4\\/2\\)\\)" }
+ begin
+ null;
+ end Gen1;
+
+ generic
+ type F2 is interface;
+ procedure Gen2;
+
+ procedure Gen2 is
+ type Inst2 is new T0 and F2 with null record; -- { dg-error "ancestor type \"F2\" is formal type of enclosing generic unit \\(RM 3\\.9\\.1 \\(4\\/2\\)\\)" }
+ begin
+ null;
+ end Gen2;
+
+begin
+ null;
+end Tagged4;
diff --git a/gcc/testsuite/gnat.dg/task5.adb b/gcc/testsuite/gnat.dg/task5.adb
new file mode 100644
index 0000000..cc8ec63
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/task5.adb
@@ -0,0 +1,26 @@
+procedure Task5 is
+
+ task type T is
+ entry E (V1, V2 : Integer);
+ end T;
+
+ T_Obj : T;
+
+ task body T is
+ V1 : Integer;
+ V2 : Integer;
+ V3 : Integer;
+ begin
+ accept E (V1, V2 : Integer) do
+ T.V1 := V1;
+ T.V2 := V2;
+
+ T_Obj.V1 := V1; -- { dg-error "invalid reference to private operation of some object of type \"T\"" }
+ T_Obj.V2 := V2; -- { dg-error "invalid reference to private operation of some object of type \"T\"" }
+ T_Obj.V3 := V3; -- { dg-error "invalid reference to private operation of some object of type \"T\"" }
+ end E;
+ end T;
+
+begin
+ null;
+end Task5;
diff --git a/gcc/testsuite/gnat.dg/test_casesi.adb b/gcc/testsuite/gnat.dg/test_casesi.adb
new file mode 100644
index 0000000..a4318c9
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/test_casesi.adb
@@ -0,0 +1,12 @@
+-- { dg-do run }
+-- { dg-options "-O2" }
+
+with Casesi;
+procedure Test_Casesi is
+begin
+ Casesi.Try (1);
+ Casesi.Try (2);
+ Casesi.Try (3);
+end;
+
+
diff --git a/gcc/testsuite/gnat.dg/valid_scalars2.adb b/gcc/testsuite/gnat.dg/valid_scalars2.adb
new file mode 100644
index 0000000..949cb83
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/valid_scalars2.adb
@@ -0,0 +1,25 @@
+-- { dg-do run }
+-- { dg-options "-O0 -gnata -gnateV" }
+
+with Ada.Exceptions; use Ada.Exceptions;
+
+procedure Valid_Scalars2 is
+
+ Traced : Boolean := False;
+
+ procedure Trace (E : in Exception_Occurrence) is
+ pragma Assert (E'Valid_scalars);
+ begin
+ Traced := True;
+ end Trace;
+
+begin
+ raise Program_Error;
+exception
+ when E : others =>
+ pragma Assert (E'Valid_scalars);
+ Trace (E);
+ if not Traced then
+ raise Program_Error;
+ end if;
+end Valid_Scalars2;
diff --git a/gcc/testsuite/gnat.dg/warn27.adb b/gcc/testsuite/gnat.dg/warn27.adb
new file mode 100644
index 0000000..d4b9059
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn27.adb
@@ -0,0 +1,10 @@
+-- { dg-do compile }
+
+procedure Warn27 is
+ Dummy : Boolean;
+
+ pragma Compile_Time_Warning (Dummy, "warning"); -- { dg-warning "condition is not known at compile time" }
+ pragma Compile_Time_Error (Dummy, "error"); -- { dg-warning "condition is not known at compile time" }
+begin
+ pragma Unreferenced (Dummy);
+end Warn27;
diff --git a/gcc/testsuite/gnat.dg/warn28.adb b/gcc/testsuite/gnat.dg/warn28.adb
new file mode 100644
index 0000000..c397dda
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn28.adb
@@ -0,0 +1,36 @@
+-- { dg-do compile }
+-- { dg-options "-gnatwa" }
+
+package body Warn28 is
+
+ function Id (X : Integer) return Integer is (2 * X);
+
+ procedure TheProcedure1 (TheParameter : in Integer)
+ is
+ X : Integer;
+ begin
+
+ X := Id (TheParameter);
+ if X < 3 then
+ X := X ** 3;
+ end if;
+ end TheProcedure1;
+
+ procedure Junk (It : Integer) is -- { dg-warning "formal parameter \"It\" is not referenced" }
+ X : Integer := Id (34);
+ begin
+ if X < 3 then
+ X := X ** 3;
+ end if;
+ end;
+
+ procedure TheProcedure (TheParameter : in Integer) -- { dg-warning "formal parameter \"TheParameter\" is not referenced" }
+ is
+
+ begin
+
+ null;
+
+ end TheProcedure;
+
+end Warn28;
diff --git a/gcc/testsuite/gnat.dg/warn28.ads b/gcc/testsuite/gnat.dg/warn28.ads
new file mode 100644
index 0000000..c06c33e
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn28.ads
@@ -0,0 +1,9 @@
+package Warn28 is
+
+ procedure TheProcedure1 (TheParameter : in Integer);
+ procedure Junk (It : Integer);
+
+ generic
+ procedure TheProcedure (TheParameter : in Integer);
+
+end Warn28;
diff --git a/gcc/testsuite/gnat.dg/warn29.adb b/gcc/testsuite/gnat.dg/warn29.adb
new file mode 100644
index 0000000..ec3b9ee
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn29.adb
@@ -0,0 +1,11 @@
+-- { dg-do compile }
+-- { dg-options "-gnatwa" }
+
+with Text_IO; use Text_IO;
+
+package body Warn29 is
+ procedure P (X : T; Y : Integer) is
+ begin
+ Put_Line ("hello");
+ end P;
+end Warn29;
diff --git a/gcc/testsuite/gnat.dg/warn29.ads b/gcc/testsuite/gnat.dg/warn29.ads
new file mode 100644
index 0000000..56c202a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn29.ads
@@ -0,0 +1,4 @@
+package Warn29 is
+ type T is tagged null record;
+ procedure P (X : T; Y : Integer);
+end Warn29;
diff --git a/gcc/testsuite/lib/options.exp b/gcc/testsuite/lib/options.exp
index b850307..c8f0c70 100644
--- a/gcc/testsuite/lib/options.exp
+++ b/gcc/testsuite/lib/options.exp
@@ -34,21 +34,30 @@ proc check_for_options_with_filter { language gcc_options exclude \
compiler_patterns \
compiler_non_patterns \
expected_failure } {
- set filename test-[pid]
- set fd [open $filename.c w]
- puts $fd "int main (void) { return 0; }"
- close $fd
- remote_download host $filename.c
-
set test "compiler driver $gcc_options option(s):"
set gcc_options "\{additional_flags=$gcc_options\}"
switch "$language" {
- "c" { set compiler cc1 }
+ "c" {
+ set compiler cc1
+ set suffix c
+ }
+ "c++" {
+ set compiler cc1plus
+ set suffix cc
+ }
default { error "unknown language" }
}
- set gcc_output [gcc_target_compile $filename.c $filename.x executable $gcc_options]
- remote_file build delete $filename.c $filename.x $filename.gcno
+
+ set filebase test-[pid]
+ set srcfname $filebase.$suffix
+ set fd [open $srcfname w]
+ puts $fd "int main (void) { return 0; }"
+ close $fd
+ remote_download host $srcfname
+
+ set gcc_output [gcc_target_compile $srcfname $filebase.x executable $gcc_options]
+ remote_file build delete $srcfname $filebase.x $filebase.gcno
if { $exclude != "" } {
set lines [split $gcc_output "\n"]
diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp
index 35ccbc8..0f1b246 100644
--- a/gcc/testsuite/lib/scanasm.exp
+++ b/gcc/testsuite/lib/scanasm.exp
@@ -460,15 +460,23 @@ proc object-size { args } {
set text [lindex $output 1]
set lines [split $text "\n"]
+ set l0match {^\s*text\s+data\s+bss\s+dec\s+hex\s+filename\s*$}
+ set l1match {^\s*\d+\s+\d+\s+\d+\s+\d+\s+[\da-fA-F]+\s+}
+
+ if { [istarget *-*-darwin*] } {
+ set l0match {^\s*__TEXT\s+__DATA\s+__OBJC\s+others\s+dec\s+hex\s*$}
+ set l1match {^\s*\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+[\da-fA-F]+\s+}
+ }
+
set line0 [lindex $lines 0]
- if ![regexp {^\s*text\s+data\s+bss\s+dec\s+hex\s+filename\s*$} $line0] {
+ if ![regexp $l0match $line0] {
verbose -log "$testcase object-size: $size did not produce expected first line: $line0"
unresolved "$testcase object-size $what $cmp $with"
return
}
set line1 [lindex $lines 1]
- if ![regexp {^\s*\d+\s+\d+\s+\d+\s+\d+\s+[\da-fA-F]+\s+} $line1] {
+ if ![regexp $l1match $line1] {
verbose -log "$testcase object-size: $size did not produce expected second line: $line1"
unresolved "$testcase object-size $what $cmp $with"
return
@@ -546,3 +554,169 @@ proc scan-lto-assembler { args } {
verbose "output_file: $output_file"
dg-scan "scan-lto-assembler" 1 $testcase $output_file $args
}
+
+# Read assembly file FILENAME and store a mapping from function names
+# to function bodies in array RESULT. FILENAME has already been uploaded
+# locally where necessary and is known to exist.
+
+proc parse_function_bodies { filename result } {
+ upvar $result up_result
+
+ # Regexp for the start of a function definition (name in \1).
+ set label {^([a-zA-Z_]\S+):$}
+
+ # Regexp for the end of a function definition.
+ set terminator {^\s*\.size}
+
+ # Regexp for lines that aren't interesting.
+ set fluff {^\s*(?:\.|//)}
+
+ set fd [open $filename r]
+ set in_function 0
+ while { [gets $fd line] >= 0 } {
+ if { [regexp $label $line dummy function_name] } {
+ set in_function 1
+ set function_body ""
+ } elseif { $in_function } {
+ if { [regexp $terminator $line] } {
+ set up_result($function_name) $function_body
+ set in_function 0
+ } elseif { ![regexp $fluff $line] } {
+ append function_body $line "\n"
+ }
+ }
+ }
+ close $fd
+}
+
+# FUNCTIONS is an array that maps function names to function bodies.
+# Return true if it contains a definition of function NAME and if
+# that definition matches BODY_REGEXP.
+
+proc check_function_body { functions name body_regexp } {
+ upvar $functions up_functions
+
+ if { ![info exists up_functions($name)] } {
+ return 0
+ }
+ return [regexp "^$body_regexp\$" $up_functions($name)]
+}
+
+# Check the implementations of functions against expected output. Used as:
+#
+# { dg-do { check-function-bodies PREFIX TERMINATOR[ OPTION] } }
+#
+# See sourcebuild.texi for details.
+
+proc check-function-bodies { args } {
+ if { [llength $args] < 2 } {
+ error "too few arguments to check-function-bodies"
+ }
+ if { [llength $args] > 3 } {
+ error "too many arguments to check-function-bodies"
+ }
+
+ if { [llength $args] == 3 } {
+ set required_flag [lindex $args 2]
+
+ upvar 2 dg-extra-tool-flags extra_tool_flags
+ set flags $extra_tool_flags
+
+ global torture_current_flags
+ if { [info exists torture_current_flags] } {
+ append flags " " $torture_current_flags
+ }
+ if { ![regexp " $required_flag " $flags] } {
+ return
+ }
+ }
+
+ set testcase [testname-for-summary]
+ # The name might include a list of options; extract the file name.
+ set filename [lindex $testcase 0]
+
+ global srcdir
+ set input_filename "$srcdir/$filename"
+ set output_filename "[file rootname [file tail $filename]].s"
+
+ set prefix [lindex $args 0]
+ set prefix_len [string length $prefix]
+ set terminator [lindex $args 1]
+ if { [string equal $terminator ""] } {
+ set terminator "*/"
+ }
+ set terminator_len [string length $terminator]
+
+ set have_bodies 0
+ if { [is_remote host] } {
+ remote_upload host "$filename"
+ }
+ if { [file exists $output_filename] } {
+ parse_function_bodies $output_filename functions
+ set have_bodies 1
+ } else {
+ verbose -log "$testcase: output file does not exist"
+ }
+
+ set count 0
+ set function_regexp ""
+ set label {^(\S+):$}
+
+ set lineno 1
+ set fd [open $input_filename r]
+ set in_function 0
+ while { [gets $fd line] >= 0 } {
+ if { [string equal -length $prefix_len $line $prefix] } {
+ set line [string trim [string range $line $prefix_len end]]
+ if { !$in_function } {
+ if { [regexp "^(.*\\S)\\s+{(.*)}\$" $line dummy \
+ line selector] } {
+ set selector [dg-process-target $selector]
+ } else {
+ set selector "P"
+ }
+ if { ![regexp $label $line dummy function_name] } {
+ close $fd
+ error "check-function-bodies: line $lineno does not have a function label"
+ }
+ set in_function 1
+ set function_regexp ""
+ } elseif { [string equal $line "("] } {
+ append function_regexp "(?:"
+ } elseif { [string equal $line "|"] } {
+ append function_regexp "|"
+ } elseif { [string equal $line ")"] } {
+ append function_regexp ")"
+ } elseif { [string equal $line "..."] } {
+ append function_regexp ".*"
+ } else {
+ append function_regexp "\t" $line "\n"
+ }
+ } elseif { [string equal -length $terminator_len $line $terminator] } {
+ if { ![string equal $selector "N"] } {
+ if { [string equal $selector "F"] } {
+ setup_xfail "*-*-*"
+ }
+ set testname "$testcase check-function-bodies $function_name"
+ if { !$have_bodies } {
+ unresolved $testname
+ } elseif { [check_function_body functions $function_name \
+ $function_regexp] } {
+ pass $testname
+ } else {
+ fail $testname
+ }
+ }
+ set in_function 0
+ incr count
+ }
+ incr lineno
+ }
+ close $fd
+ if { $in_function } {
+ error "check-function-bodies: missing \"$terminator\""
+ }
+ if { $count == 0 } {
+ error "check-function-bodies: no matches found"
+ }
+}
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 815e837..300d22a 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -364,6 +364,18 @@ proc check_weak_override_available { } {
return [check_weak_available]
}
+# The noinit attribute is only supported by some targets.
+# This proc returns 1 if it's supported, 0 if it's not.
+
+proc check_effective_target_noinit { } {
+ if { [istarget arm*-*-eabi]
+ || [istarget msp430-*-*] } {
+ return 1
+ }
+
+ return 0
+}
+
###############################
# proc check_visibility_available { what_kind }
###############################
@@ -6294,9 +6306,18 @@ proc check_effective_target_vect_aligned_arrays { } {
proc check_effective_target_natural_alignment_32 { } {
# FIXME: 32bit powerpc: guaranteed only if MASK_ALIGN_NATURAL/POWER.
+ # FIXME: m68k has -malign-int
return [check_cached_effective_target_indexed natural_alignment_32 {
if { ([istarget *-*-darwin*] && [is-effective-target lp64])
- || [istarget avr-*-*] } {
+ || [istarget avr-*-*]
+ || [istarget m68k-*-linux*]
+ || [istarget pru-*-*]
+ || [istarget stormy16-*-*]
+ || [istarget rl78-*-*]
+ || [istarget pdp11-*-*]
+ || [istarget msp430-*-*]
+ || [istarget m32c-*-*]
+ || [istarget cris-*-*] } {
return 0
} else {
return 1
@@ -6311,8 +6332,9 @@ proc check_effective_target_natural_alignment_32 { } {
proc check_effective_target_natural_alignment_64 { } {
return [check_cached_effective_target_indexed natural_alignment_64 {
- expr { ([is-effective-target lp64] && ![istarget *-*-darwin*])
- || [istarget spu-*-*] }
+ expr { [is-effective-target natural_alignment_32]
+ && (([is-effective-target lp64] && ![istarget *-*-darwin*])
+ || [istarget spu-*-*]) }
}]
}
@@ -9463,6 +9485,16 @@ proc check_effective_target_arm_v8_3a_complex_neon_hw { } {
} [add_options_for_arm_v8_3a_complex_neon ""]]
}
+# Return 1 if the assembler supports assembling the Armv8.3 pointer authentication B key directive
+proc check_effective_target_arm_v8_3a_bkey_directive { } {
+ return [check_no_compiler_messages cet object {
+ int main(void) {
+ asm (".cfi_b_key_frame");
+ return 0;
+ }
+ }]
+}
+
# Returns 1 if the target is using glibc, 0 otherwise.
proc check_effective_target_glibc { } {
diff --git a/gcc/testsuite/obj-c++.dg/stubify-1.mm b/gcc/testsuite/obj-c++.dg/stubify-1.mm
index b82167e..a32e282 100644
--- a/gcc/testsuite/obj-c++.dg/stubify-1.mm
+++ b/gcc/testsuite/obj-c++.dg/stubify-1.mm
@@ -4,7 +4,7 @@
/* { dg-do compile { target *-*-darwin* } } */
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-options "-Os -mdynamic-no-pic -fno-exceptions -mmacosx-version-min=10.4 -mpic-symbol-stubs" } */
+/* { dg-options "-Os -mdynamic-no-pic -fno-exceptions -mmacosx-version-min=10.4 -msymbol-stubs" } */
typedef struct objc_object { } *id ;
int x = 41 ;
diff --git a/gcc/testsuite/obj-c++.dg/stubify-2.mm b/gcc/testsuite/obj-c++.dg/stubify-2.mm
index ee8e342..69fea8d 100644
--- a/gcc/testsuite/obj-c++.dg/stubify-2.mm
+++ b/gcc/testsuite/obj-c++.dg/stubify-2.mm
@@ -4,7 +4,7 @@
/* { dg-do compile { target *-*-darwin* } } */
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-options "-mdynamic-no-pic -fdump-rtl-jump -mmacosx-version-min=10.4 -mpic-symbol-stubs" } */
+/* { dg-options "-mdynamic-no-pic -fdump-rtl-jump -mmacosx-version-min=10.4 -msymbol-stubs" } */
typedef struct objc_object { } *id ;
int x = 41 ;
diff --git a/gcc/testsuite/objc.dg/stubify-1.m b/gcc/testsuite/objc.dg/stubify-1.m
index 1e160a1..641595c 100644
--- a/gcc/testsuite/objc.dg/stubify-1.m
+++ b/gcc/testsuite/objc.dg/stubify-1.m
@@ -4,7 +4,7 @@
/* { dg-do compile { target *-*-darwin* } } */
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-options "-Os -mdynamic-no-pic -mmacosx-version-min=10.4 -mpic-symbol-stubs" } */
+/* { dg-options "-Os -mdynamic-no-pic -mmacosx-version-min=10.4 -msymbol-stubs" } */
typedef struct objc_object { } *id ;
int x = 41 ;
diff --git a/gcc/testsuite/objc.dg/stubify-2.m b/gcc/testsuite/objc.dg/stubify-2.m
index 1f53b9c..904ac44 100644
--- a/gcc/testsuite/objc.dg/stubify-2.m
+++ b/gcc/testsuite/objc.dg/stubify-2.m
@@ -4,7 +4,7 @@
/* { dg-do compile { target *-*-darwin* } } */
/* { dg-skip-if "" { *-*-* } { "-fgnu-runtime" } { "" } } */
/* { dg-require-effective-target ilp32 } */
-/* { dg-options "-mdynamic-no-pic -fdump-rtl-jump -mmacosx-version-min=10.4 -mpic-symbol-stubs" } */
+/* { dg-options "-mdynamic-no-pic -fdump-rtl-jump -mmacosx-version-min=10.4 -msymbol-stubs" } */
typedef struct objc_object { } *id ;
int x = 41 ;
diff --git a/gcc/timevar.def b/gcc/timevar.def
index 626ce49..3551a43 100644
--- a/gcc/timevar.def
+++ b/gcc/timevar.def
@@ -68,6 +68,8 @@ DEFTIMEVAR (TV_PCH_CPP_RESTORE , "PCH preprocessor state restore")
DEFTIMEVAR (TV_CGRAPH , "callgraph construction")
DEFTIMEVAR (TV_CGRAPHOPT , "callgraph optimization")
+DEFTIMEVAR (TV_CGRAPH_FUNC_EXPANSION , "callgraph functions expansion")
+DEFTIMEVAR (TV_CGRAPH_IPA_PASSES , "callgraph ipa passes")
DEFTIMEVAR (TV_IPA_FNSUMMARY , "ipa function summary")
DEFTIMEVAR (TV_IPA_UNREACHABLE , "ipa dead code removal")
DEFTIMEVAR (TV_IPA_INHERITANCE , "ipa inheritance graph")
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 56ef63e..ddbb8b4 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -815,9 +815,10 @@ print_switch_values (print_switch_fn_type print_fn)
pos = print_single_switch (print_fn, 0,
SWITCH_TYPE_DESCRIPTIVE, _("options enabled: "));
+ unsigned lang_mask = lang_hooks.option_lang_mask ();
for (j = 0; j < cl_options_count; j++)
if (cl_options[j].cl_report
- && option_enabled (j, &global_options) > 0)
+ && option_enabled (j, lang_mask, &global_options) > 0)
pos = print_single_switch (print_fn, pos,
SWITCH_TYPE_ENABLED, cl_options[j].opt_text);
@@ -1088,6 +1089,7 @@ general_init (const char *argv0, bool init_signals)
/* Initialize the diagnostics reporting machinery, so option parsing
can give warnings and errors. */
diagnostic_initialize (global_dc, N_OPTS);
+ global_dc->lang_mask = lang_hooks.option_lang_mask ();
/* Set a default printer. Language specific initializations will
override it later. */
tree_diagnostics_defaults (global_dc);
@@ -1742,7 +1744,7 @@ process_options (void)
/* Address Sanitizer needs porting to each target architecture. */
if ((flag_sanitize & SANITIZE_ADDRESS)
- && !FRAME_GROWS_DOWNWARD)
+ && (!FRAME_GROWS_DOWNWARD || targetm.asan_shadow_offset == NULL))
{
warning_at (UNKNOWN_LOCATION, 0,
"%<-fsanitize=address%> and %<-fsanitize=kernel-address%> "
@@ -1750,14 +1752,6 @@ process_options (void)
flag_sanitize &= ~SANITIZE_ADDRESS;
}
- if ((flag_sanitize & SANITIZE_USER_ADDRESS)
- && targetm.asan_shadow_offset == NULL)
- {
- warning_at (UNKNOWN_LOCATION, 0,
- "%<-fsanitize=address%> not supported for this target");
- flag_sanitize &= ~SANITIZE_ADDRESS;
- }
-
/* Do not use IPA optimizations for register allocation if profiler is active
or patchable function entries are inserted for run-time instrumentation
or port does not emit prologue and epilogue as RTL. */
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index 35d4fab..c39d6d0 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -3237,8 +3237,7 @@ expand_block_edges (struct tm_region *const region, basic_block bb)
|| (gimple_call_flags (call_stmt) & ECF_TM_BUILTIN) == 0)
continue;
- if (DECL_FUNCTION_CODE (gimple_call_fndecl (call_stmt))
- == BUILT_IN_TM_ABORT)
+ if (gimple_call_builtin_p (call_stmt, BUILT_IN_TM_ABORT))
{
// If we have a ``_transaction_cancel [[outer]]'', there is only
// one abnormal edge: to the transaction marked OUTER.
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index 9e3372f..57eed67 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -1118,9 +1118,7 @@ use_internal_fn (gcall *call)
{
gimple_stmt_iterator gsi = gsi_for_stmt (call);
gcall *new_call = gimple_build_call_internal (IFN_SET_EDOM, 0);
- gimple_set_vuse (new_call, gimple_vuse (call));
- gimple_set_vdef (new_call, gimple_vdef (call));
- SSA_NAME_DEF_STMT (gimple_vdef (new_call)) = new_call;
+ gimple_move_vops (new_call, call);
gimple_set_location (new_call, gimple_location (call));
gsi_replace (&gsi, new_call, false);
call = new_call;
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 54ee63a..2648663 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -9579,7 +9579,8 @@ execute_fixup_cfg (void)
Keep access when store has side effect, i.e. in case when source
is volatile. */
if (gimple_store_p (stmt)
- && !gimple_has_side_effects (stmt))
+ && !gimple_has_side_effects (stmt)
+ && !optimize_debug)
{
tree lhs = get_base_address (gimple_get_lhs (stmt));
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index fa37a0dc..cfd8839 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -307,9 +307,12 @@ enum omp_clause_code {
OMP_CLAUSE_MAP,
/* OpenACC clause: use_device (variable-list).
- OpenMP clause: use_device_ptr (variable-list). */
+ OpenMP clause: use_device_ptr (ptr-list). */
OMP_CLAUSE_USE_DEVICE_PTR,
+ /* OpenMP clause: use_device_addr (variable-list). */
+ OMP_CLAUSE_USE_DEVICE_ADDR,
+
/* OpenMP clause: is_device_ptr (variable-list). */
OMP_CLAUSE_IS_DEVICE_PTR,
@@ -412,6 +415,9 @@ enum omp_clause_code {
/* OpenMP clause: simdlen (constant-integer-expression). */
OMP_CLAUSE_SIMDLEN,
+ /* OpenMP clause: device_type ({host,nohost,any}). */
+ OMP_CLAUSE_DEVICE_TYPE,
+
/* OpenMP clause: for. */
OMP_CLAUSE_FOR,
@@ -1465,6 +1471,13 @@ enum omp_clause_proc_bind_kind
OMP_CLAUSE_PROC_BIND_LAST
};
+enum omp_clause_device_type_kind
+{
+ OMP_CLAUSE_DEVICE_TYPE_HOST = 1,
+ OMP_CLAUSE_DEVICE_TYPE_NOHOST = 2,
+ OMP_CLAUSE_DEVICE_TYPE_ANY = 3
+};
+
enum omp_clause_linear_kind
{
OMP_CLAUSE_LINEAR_DEFAULT,
@@ -1541,6 +1554,7 @@ struct GTY(()) tree_omp_clause {
enum tree_code if_modifier;
enum omp_clause_defaultmap_kind defaultmap_kind;
enum omp_clause_bind_kind bind_kind;
+ enum omp_clause_device_type_kind device_type_kind;
/* The dimension a OMP_CLAUSE__GRIDDIM_ clause of a gridified target
construct describes. */
unsigned int dimension;
@@ -1820,6 +1834,18 @@ struct GTY(()) tree_decl_non_common {
tree result;
};
+/* Classify a special function declaration type. */
+
+enum function_decl_type
+{
+ NONE,
+ OPERATOR_NEW,
+ OPERATOR_DELETE,
+ LAMBDA_FUNCTION
+
+ /* 0 values left */
+};
+
/* FUNCTION_DECL inherits from DECL_NON_COMMON because of the use of the
arguments/result/saved_tree fields by front ends. It was either inherit
FUNCTION_DECL from non_common, or inherit non_common from FUNCTION_DECL,
@@ -1844,34 +1870,32 @@ struct GTY(()) tree_function_decl {
/* Index within a virtual table. */
tree vindex;
- /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
- DECL_FUNCTION_CODE. Otherwise unused.
- ??? The bitfield needs to be able to hold all target function
- codes as well. */
- ENUM_BITFIELD(built_in_function) function_code : 12;
- ENUM_BITFIELD(built_in_class) built_in_class : 2;
+ /* In a FUNCTION_DECL this is DECL_UNCHECKED_FUNCTION_CODE. */
+ unsigned int function_code;
+ ENUM_BITFIELD(built_in_class) built_in_class : 2;
unsigned static_ctor_flag : 1;
unsigned static_dtor_flag : 1;
-
unsigned uninlinable : 1;
unsigned possibly_inlined : 1;
unsigned novops_flag : 1;
unsigned returns_twice_flag : 1;
+
unsigned malloc_flag : 1;
- unsigned operator_new_flag : 1;
unsigned declared_inline_flag : 1;
unsigned no_inline_warning_flag : 1;
-
unsigned no_instrument_function_entry_exit : 1;
unsigned no_limit_stack : 1;
unsigned disregard_inline_limits : 1;
unsigned pure_flag : 1;
unsigned looping_const_or_pure_flag : 1;
+
+ /* Align the bitfield to boundary of a byte. */
+ ENUM_BITFIELD(function_decl_type) decl_type: 2;
unsigned has_debug_args_flag : 1;
unsigned versioned_function : 1;
- unsigned lambda_function: 1;
- /* No bits left. */
+
+ /* 12 bits left for future expansion. */
};
struct GTY(()) tree_translation_unit_decl {
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index d9e540f..da67e39 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -2141,9 +2141,7 @@ predicate_load_or_store (gimple_stmt_iterator *gsi, gassign *stmt, tree mask)
new_stmt
= gimple_build_call_internal (IFN_MASK_STORE, 4, addr, ptr,
mask, rhs);
- gimple_set_vuse (new_stmt, gimple_vuse (stmt));
- gimple_set_vdef (new_stmt, gimple_vdef (stmt));
- SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
+ gimple_move_vops (new_stmt, stmt);
}
gimple_call_set_nothrow (new_stmt, true);
return new_stmt;
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 4311309..46bbec1 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -4895,7 +4895,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
we may get confused if the compiler sees that the inlined new
function returns a pointer which was just deleted. See bug
33407. */
- if (DECL_IS_OPERATOR_NEW (fn))
+ if (DECL_IS_OPERATOR_NEW_P (fn))
{
return_slot = NULL;
modify_dest = NULL;
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 1527456..4df07ed 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -169,6 +169,16 @@ create_tmp_var_for (struct nesting_info *info, tree type, const char *prefix)
return tmp_var;
}
+/* Like build_simple_mem_ref, but set TREE_THIS_NOTRAP on the result. */
+
+static tree
+build_simple_mem_ref_notrap (tree ptr)
+{
+ tree t = build_simple_mem_ref (ptr);
+ TREE_THIS_NOTRAP (t) = 1;
+ return t;
+}
+
/* Take the address of EXP to be used within function CONTEXT.
Mark it for addressability as necessary. */
@@ -877,7 +887,7 @@ get_static_chain (struct nesting_info *info, tree target_context,
{
tree field = get_chain_field (i);
- x = build_simple_mem_ref (x);
+ x = build_simple_mem_ref_notrap (x);
x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
x = init_tmp_var (info, x, gsi);
}
@@ -914,12 +924,12 @@ get_frame_field (struct nesting_info *info, tree target_context,
{
tree field = get_chain_field (i);
- x = build_simple_mem_ref (x);
+ x = build_simple_mem_ref_notrap (x);
x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
x = init_tmp_var (info, x, gsi);
}
- x = build_simple_mem_ref (x);
+ x = build_simple_mem_ref_notrap (x);
}
x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
@@ -963,16 +973,16 @@ get_nonlocal_debug_decl (struct nesting_info *info, tree decl)
for (i = info->outer; i->context != target_context; i = i->outer)
{
field = get_chain_field (i);
- x = build_simple_mem_ref (x);
+ x = build_simple_mem_ref_notrap (x);
x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
}
- x = build_simple_mem_ref (x);
+ x = build_simple_mem_ref_notrap (x);
}
field = lookup_field_for_decl (i, decl, INSERT);
x = build3 (COMPONENT_REF, TREE_TYPE (field), x, field, NULL_TREE);
if (use_pointer_in_frame (decl))
- x = build_simple_mem_ref (x);
+ x = build_simple_mem_ref_notrap (x);
/* ??? We should be remapping types as well, surely. */
new_decl = build_decl (DECL_SOURCE_LOCATION (decl),
@@ -1060,7 +1070,7 @@ convert_nonlocal_reference_op (tree *tp, int *walk_subtrees, void *data)
if (use_pointer_in_frame (t))
{
x = init_tmp_var (info, x, &wi->gsi);
- x = build_simple_mem_ref (x);
+ x = build_simple_mem_ref_notrap (x);
}
}
@@ -1217,6 +1227,7 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
case OMP_CLAUSE_TO_DECLARE:
case OMP_CLAUSE_LINK:
case OMP_CLAUSE_USE_DEVICE_PTR:
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
case OMP_CLAUSE_IS_DEVICE_PTR:
do_decl_clause:
decl = OMP_CLAUSE_DECL (clause);
@@ -1937,6 +1948,7 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
case OMP_CLAUSE_TO_DECLARE:
case OMP_CLAUSE_LINK:
case OMP_CLAUSE_USE_DEVICE_PTR:
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
case OMP_CLAUSE_IS_DEVICE_PTR:
do_decl_clause:
decl = OMP_CLAUSE_DECL (clause);
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 9bea132..53b3f55 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -465,6 +465,9 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
case OMP_CLAUSE_USE_DEVICE_PTR:
name = "use_device_ptr";
goto print_remap;
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
+ name = "use_device_addr";
+ goto print_remap;
case OMP_CLAUSE_IS_DEVICE_PTR:
name = "is_device_ptr";
goto print_remap;
@@ -948,6 +951,25 @@ dump_omp_clause (pretty_printer *pp, tree clause, int spc, dump_flags_t flags)
pp_right_paren (pp);
break;
+ case OMP_CLAUSE_DEVICE_TYPE:
+ pp_string (pp, "device_type(");
+ switch (OMP_CLAUSE_DEVICE_TYPE_KIND (clause))
+ {
+ case OMP_CLAUSE_DEVICE_TYPE_HOST:
+ pp_string (pp, "host");
+ break;
+ case OMP_CLAUSE_DEVICE_TYPE_NOHOST:
+ pp_string (pp, "nohost");
+ break;
+ case OMP_CLAUSE_DEVICE_TYPE_ANY:
+ pp_string (pp, "any");
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ pp_right_paren (pp);
+ break;
+
case OMP_CLAUSE_SAFELEN:
pp_string (pp, "safelen(");
dump_generic_node (pp, OMP_CLAUSE_SAFELEN_EXPR (clause),
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index 4b72a25..50b2700 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -876,8 +876,8 @@ enum t_bool {
};
-static t_bool follow_ssa_edge (class loop *loop, gimple *, gphi *,
- tree *, int);
+static t_bool follow_ssa_edge_expr (class loop *loop, gimple *, tree, gphi *,
+ tree *, int);
/* Follow the ssa edge into the binary expression RHS0 CODE RHS1.
Return true if the strongly connected component has been found. */
@@ -912,8 +912,8 @@ follow_ssa_edge_binary (class loop *loop, gimple *at_stmt,
(loop->num,
chrec_convert (type, evol, at_stmt),
code, rhs1, at_stmt);
- res = follow_ssa_edge
- (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi, &evol, limit);
+ res = follow_ssa_edge_expr
+ (loop, at_stmt, rhs0, halting_phi, &evol, limit);
if (res == t_true)
*evolution_of_loop = evol;
else if (res == t_false)
@@ -922,35 +922,14 @@ follow_ssa_edge_binary (class loop *loop, gimple *at_stmt,
(loop->num,
chrec_convert (type, *evolution_of_loop, at_stmt),
code, rhs0, at_stmt);
- res = follow_ssa_edge
- (loop, SSA_NAME_DEF_STMT (rhs1), halting_phi,
+ res = follow_ssa_edge_expr
+ (loop, at_stmt, rhs1, halting_phi,
evolution_of_loop, limit);
- if (res == t_true)
- ;
- else if (res == t_dont_know)
- *evolution_of_loop = chrec_dont_know;
}
-
- else if (res == t_dont_know)
- *evolution_of_loop = chrec_dont_know;
}
else
- {
- /* Match an assignment under the form:
- "a = b + ...". */
- *evolution_of_loop = add_to_evolution
- (loop->num, chrec_convert (type, *evolution_of_loop,
- at_stmt),
- code, rhs1, at_stmt);
- res = follow_ssa_edge
- (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi,
- evolution_of_loop, limit);
- if (res == t_true)
- ;
- else if (res == t_dont_know)
- *evolution_of_loop = chrec_dont_know;
- }
+ gcc_unreachable (); /* Handled in caller. */
}
else if (TREE_CODE (rhs1) == SSA_NAME)
@@ -961,13 +940,9 @@ follow_ssa_edge_binary (class loop *loop, gimple *at_stmt,
(loop->num, chrec_convert (type, *evolution_of_loop,
at_stmt),
code, rhs0, at_stmt);
- res = follow_ssa_edge
- (loop, SSA_NAME_DEF_STMT (rhs1), halting_phi,
+ res = follow_ssa_edge_expr
+ (loop, at_stmt, rhs1, halting_phi,
evolution_of_loop, limit);
- if (res == t_true)
- ;
- else if (res == t_dont_know)
- *evolution_of_loop = chrec_dont_know;
}
else
@@ -980,26 +955,7 @@ follow_ssa_edge_binary (class loop *loop, gimple *at_stmt,
case MINUS_EXPR:
/* This case is under the form "opnd0 = rhs0 - rhs1". */
if (TREE_CODE (rhs0) == SSA_NAME)
- {
- /* Match an assignment under the form:
- "a = b - ...". */
-
- /* We want only assignments of form "name - name" contribute to
- LIMIT, as the other cases do not necessarily contribute to
- the complexity of the expression. */
- if (TREE_CODE (rhs1) == SSA_NAME)
- limit++;
-
- *evolution_of_loop = add_to_evolution
- (loop->num, chrec_convert (type, *evolution_of_loop, at_stmt),
- MINUS_EXPR, rhs1, at_stmt);
- res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi,
- evolution_of_loop, limit);
- if (res == t_true)
- ;
- else if (res == t_dont_know)
- *evolution_of_loop = chrec_dont_know;
- }
+ gcc_unreachable (); /* Handled in caller. */
else
/* Otherwise, match an assignment under the form:
"a = ... - ...". */
@@ -1014,140 +970,6 @@ follow_ssa_edge_binary (class loop *loop, gimple *at_stmt,
return res;
}
-/* Follow the ssa edge into the expression EXPR.
- Return true if the strongly connected component has been found. */
-
-static t_bool
-follow_ssa_edge_expr (class loop *loop, gimple *at_stmt, tree expr,
- gphi *halting_phi, tree *evolution_of_loop,
- int limit)
-{
- enum tree_code code = TREE_CODE (expr);
- tree type = TREE_TYPE (expr), rhs0, rhs1;
- t_bool res;
-
- /* The EXPR is one of the following cases:
- - an SSA_NAME,
- - an INTEGER_CST,
- - a PLUS_EXPR,
- - a POINTER_PLUS_EXPR,
- - a MINUS_EXPR,
- - an ASSERT_EXPR,
- - other cases are not yet handled. */
-
- switch (code)
- {
- CASE_CONVERT:
- /* This assignment is under the form "a_1 = (cast) rhs. */
- res = follow_ssa_edge_expr (loop, at_stmt, TREE_OPERAND (expr, 0),
- halting_phi, evolution_of_loop, limit);
- *evolution_of_loop = chrec_convert (type, *evolution_of_loop, at_stmt);
- break;
-
- case INTEGER_CST:
- /* This assignment is under the form "a_1 = 7". */
- res = t_false;
- break;
-
- case SSA_NAME:
- /* This assignment is under the form: "a_1 = b_2". */
- res = follow_ssa_edge
- (loop, SSA_NAME_DEF_STMT (expr), halting_phi, evolution_of_loop, limit);
- break;
-
- case POINTER_PLUS_EXPR:
- case PLUS_EXPR:
- case MINUS_EXPR:
- /* This case is under the form "rhs0 +- rhs1". */
- rhs0 = TREE_OPERAND (expr, 0);
- rhs1 = TREE_OPERAND (expr, 1);
- type = TREE_TYPE (rhs0);
- STRIP_USELESS_TYPE_CONVERSION (rhs0);
- STRIP_USELESS_TYPE_CONVERSION (rhs1);
- res = follow_ssa_edge_binary (loop, at_stmt, type, rhs0, code, rhs1,
- halting_phi, evolution_of_loop, limit);
- break;
-
- case ADDR_EXPR:
- /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR. */
- if (TREE_CODE (TREE_OPERAND (expr, 0)) == MEM_REF)
- {
- expr = TREE_OPERAND (expr, 0);
- rhs0 = TREE_OPERAND (expr, 0);
- rhs1 = TREE_OPERAND (expr, 1);
- type = TREE_TYPE (rhs0);
- STRIP_USELESS_TYPE_CONVERSION (rhs0);
- STRIP_USELESS_TYPE_CONVERSION (rhs1);
- res = follow_ssa_edge_binary (loop, at_stmt, type,
- rhs0, POINTER_PLUS_EXPR, rhs1,
- halting_phi, evolution_of_loop, limit);
- }
- else
- res = t_false;
- break;
-
- case ASSERT_EXPR:
- /* This assignment is of the form: "a_1 = ASSERT_EXPR <a_2, ...>"
- It must be handled as a copy assignment of the form a_1 = a_2. */
- rhs0 = ASSERT_EXPR_VAR (expr);
- if (TREE_CODE (rhs0) == SSA_NAME)
- res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (rhs0),
- halting_phi, evolution_of_loop, limit);
- else
- res = t_false;
- break;
-
- default:
- res = t_false;
- break;
- }
-
- return res;
-}
-
-/* Follow the ssa edge into the right hand side of an assignment STMT.
- Return true if the strongly connected component has been found. */
-
-static t_bool
-follow_ssa_edge_in_rhs (class loop *loop, gimple *stmt,
- gphi *halting_phi, tree *evolution_of_loop,
- int limit)
-{
- enum tree_code code = gimple_assign_rhs_code (stmt);
- tree type = gimple_expr_type (stmt), rhs1, rhs2;
- t_bool res;
-
- switch (code)
- {
- CASE_CONVERT:
- /* This assignment is under the form "a_1 = (cast) rhs. */
- res = follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
- halting_phi, evolution_of_loop, limit);
- *evolution_of_loop = chrec_convert (type, *evolution_of_loop, stmt);
- break;
-
- case POINTER_PLUS_EXPR:
- case PLUS_EXPR:
- case MINUS_EXPR:
- rhs1 = gimple_assign_rhs1 (stmt);
- rhs2 = gimple_assign_rhs2 (stmt);
- type = TREE_TYPE (rhs1);
- res = follow_ssa_edge_binary (loop, stmt, type, rhs1, code, rhs2,
- halting_phi, evolution_of_loop, limit);
- break;
-
- default:
- if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
- res = follow_ssa_edge_expr (loop, stmt, gimple_assign_rhs1 (stmt),
- halting_phi, evolution_of_loop, limit);
- else
- res = t_false;
- break;
- }
-
- return res;
-}
-
/* Checks whether the I-th argument of a PHI comes from a backedge. */
static bool
@@ -1187,8 +1009,8 @@ follow_ssa_edge_in_condition_phi_branch (int i,
if (TREE_CODE (branch) == SSA_NAME)
{
*evolution_of_branch = init_cond;
- return follow_ssa_edge (loop, SSA_NAME_DEF_STMT (branch), halting_phi,
- evolution_of_branch, limit);
+ return follow_ssa_edge_expr (loop, condition_phi, branch, halting_phi,
+ evolution_of_branch, limit);
}
/* This case occurs when one of the condition branches sets
@@ -1295,65 +1117,176 @@ follow_ssa_edge_inner_loop_phi (class loop *outer_loop,
evolution_of_loop, limit);
}
-/* Follow an SSA edge from a loop-phi-node to itself, constructing a
- path that is analyzed on the return walk. */
+/* Follow the ssa edge into the expression EXPR.
+ Return true if the strongly connected component has been found. */
static t_bool
-follow_ssa_edge (class loop *loop, gimple *def, gphi *halting_phi,
- tree *evolution_of_loop, int limit)
+follow_ssa_edge_expr (class loop *loop, gimple *at_stmt, tree expr,
+ gphi *halting_phi, tree *evolution_of_loop,
+ int limit)
{
- class loop *def_loop;
+ enum tree_code code;
+ tree type, rhs0, rhs1 = NULL_TREE;
- if (gimple_nop_p (def))
- return t_false;
+ /* The EXPR is one of the following cases:
+ - an SSA_NAME,
+ - an INTEGER_CST,
+ - a PLUS_EXPR,
+ - a POINTER_PLUS_EXPR,
+ - a MINUS_EXPR,
+ - an ASSERT_EXPR,
+ - other cases are not yet handled. */
- /* Give up if the path is longer than the MAX that we allow. */
- if (limit > PARAM_VALUE (PARAM_SCEV_MAX_EXPR_COMPLEXITY))
- return t_dont_know;
+ /* For SSA_NAME look at the definition statement, handling
+ PHI nodes and otherwise expand appropriately for the expression
+ handling below. */
+tail_recurse:
+ if (TREE_CODE (expr) == SSA_NAME)
+ {
+ gimple *def = SSA_NAME_DEF_STMT (expr);
- def_loop = loop_containing_stmt (def);
+ if (gimple_nop_p (def))
+ return t_false;
- switch (gimple_code (def))
- {
- case GIMPLE_PHI:
- if (!loop_phi_node_p (def))
- /* DEF is a condition-phi-node. Follow the branches, and
- record their evolutions. Finally, merge the collected
- information and set the approximation to the main
- variable. */
- return follow_ssa_edge_in_condition_phi
- (loop, as_a <gphi *> (def), halting_phi, evolution_of_loop,
- limit);
-
- /* When the analyzed phi is the halting_phi, the
- depth-first search is over: we have found a path from
- the halting_phi to itself in the loop. */
- if (def == halting_phi)
- return t_true;
+ /* Give up if the path is longer than the MAX that we allow. */
+ if (limit > PARAM_VALUE (PARAM_SCEV_MAX_EXPR_COMPLEXITY))
+ {
+ *evolution_of_loop = chrec_dont_know;
+ return t_dont_know;
+ }
- /* Otherwise, the evolution of the HALTING_PHI depends
- on the evolution of another loop-phi-node, i.e. the
- evolution function is a higher degree polynomial. */
- if (def_loop == loop)
+ if (gphi *phi = dyn_cast <gphi *>(def))
+ {
+ if (!loop_phi_node_p (phi))
+ /* DEF is a condition-phi-node. Follow the branches, and
+ record their evolutions. Finally, merge the collected
+ information and set the approximation to the main
+ variable. */
+ return follow_ssa_edge_in_condition_phi
+ (loop, phi, halting_phi, evolution_of_loop, limit);
+
+ /* When the analyzed phi is the halting_phi, the
+ depth-first search is over: we have found a path from
+ the halting_phi to itself in the loop. */
+ if (phi == halting_phi)
+ return t_true;
+
+ /* Otherwise, the evolution of the HALTING_PHI depends
+ on the evolution of another loop-phi-node, i.e. the
+ evolution function is a higher degree polynomial. */
+ class loop *def_loop = loop_containing_stmt (def);
+ if (def_loop == loop)
+ return t_false;
+
+ /* Inner loop. */
+ if (flow_loop_nested_p (loop, def_loop))
+ return follow_ssa_edge_inner_loop_phi
+ (loop, phi, halting_phi, evolution_of_loop,
+ limit + 1);
+
+ /* Outer loop. */
+ return t_false;
+ }
+
+ /* At this level of abstraction, the program is just a set
+ of GIMPLE_ASSIGNs and PHI_NODEs. In principle there is no
+ other def to be handled. */
+ if (!is_gimple_assign (def))
return t_false;
- /* Inner loop. */
- if (flow_loop_nested_p (loop, def_loop))
- return follow_ssa_edge_inner_loop_phi
- (loop, as_a <gphi *> (def), halting_phi, evolution_of_loop,
- limit + 1);
+ code = gimple_assign_rhs_code (def);
+ switch (get_gimple_rhs_class (code))
+ {
+ case GIMPLE_BINARY_RHS:
+ rhs0 = gimple_assign_rhs1 (def);
+ rhs1 = gimple_assign_rhs2 (def);
+ break;
+ case GIMPLE_UNARY_RHS:
+ case GIMPLE_SINGLE_RHS:
+ rhs0 = gimple_assign_rhs1 (def);
+ break;
+ default:
+ return t_false;
+ }
+ type = TREE_TYPE (gimple_assign_lhs (def));
+ at_stmt = def;
+ }
+ else
+ {
+ code = TREE_CODE (expr);
+ type = TREE_TYPE (expr);
+ switch (code)
+ {
+ CASE_CONVERT:
+ rhs0 = TREE_OPERAND (expr, 0);
+ break;
+ case POINTER_PLUS_EXPR:
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ rhs0 = TREE_OPERAND (expr, 0);
+ rhs1 = TREE_OPERAND (expr, 1);
+ break;
+ default:
+ rhs0 = expr;
+ }
+ }
+
+ switch (code)
+ {
+ CASE_CONVERT:
+ {
+ /* This assignment is under the form "a_1 = (cast) rhs. */
+ t_bool res = follow_ssa_edge_expr (loop, at_stmt, rhs0, halting_phi,
+ evolution_of_loop, limit);
+ *evolution_of_loop = chrec_convert (type, *evolution_of_loop, at_stmt);
+ return res;
+ }
- /* Outer loop. */
+ case INTEGER_CST:
+ /* This assignment is under the form "a_1 = 7". */
return t_false;
- case GIMPLE_ASSIGN:
- return follow_ssa_edge_in_rhs (loop, def, halting_phi,
- evolution_of_loop, limit);
+ case ADDR_EXPR:
+ {
+ /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR. */
+ if (TREE_CODE (TREE_OPERAND (rhs0, 0)) != MEM_REF)
+ return t_false;
+ tree mem = TREE_OPERAND (rhs0, 0);
+ rhs0 = TREE_OPERAND (mem, 0);
+ rhs1 = TREE_OPERAND (mem, 1);
+ code = POINTER_PLUS_EXPR;
+ }
+ /* Fallthru. */
+ case POINTER_PLUS_EXPR:
+ case PLUS_EXPR:
+ case MINUS_EXPR:
+ /* This case is under the form "rhs0 +- rhs1". */
+ STRIP_USELESS_TYPE_CONVERSION (rhs0);
+ STRIP_USELESS_TYPE_CONVERSION (rhs1);
+ if (TREE_CODE (rhs0) == SSA_NAME
+ && (TREE_CODE (rhs1) != SSA_NAME || code == MINUS_EXPR))
+ {
+ /* Match an assignment under the form:
+ "a = b +- ...".
+ Use tail-recursion for the simple case. */
+ *evolution_of_loop = add_to_evolution
+ (loop->num, chrec_convert (type, *evolution_of_loop,
+ at_stmt),
+ code, rhs1, at_stmt);
+ expr = rhs0;
+ goto tail_recurse;
+ }
+ /* Else search for the SCC in both rhs0 and rhs1. */
+ return follow_ssa_edge_binary (loop, at_stmt, type, rhs0, code, rhs1,
+ halting_phi, evolution_of_loop, limit);
+
+ case ASSERT_EXPR:
+ /* This assignment is of the form: "a_1 = ASSERT_EXPR <a_2, ...>"
+ It must be handled as a copy assignment of the form a_1 = a_2. */
+ expr = ASSERT_EXPR_VAR (rhs0);
+ goto tail_recurse;
default:
- /* At this level of abstraction, the program is just a set
- of GIMPLE_ASSIGNs and PHI_NODEs. In principle there is no
- other node to be handled. */
return t_false;
}
}
@@ -1447,7 +1380,6 @@ analyze_evolution_in_loop (gphi *loop_phi_node,
for (i = 0; i < n; i++)
{
tree arg = PHI_ARG_DEF (loop_phi_node, i);
- gimple *ssa_chain;
tree ev_fn;
t_bool res;
@@ -1460,11 +1392,10 @@ analyze_evolution_in_loop (gphi *loop_phi_node,
{
bool val = false;
- ssa_chain = SSA_NAME_DEF_STMT (arg);
-
/* Pass in the initial condition to the follow edge function. */
ev_fn = init_cond;
- res = follow_ssa_edge (loop, ssa_chain, loop_phi_node, &ev_fn, 0);
+ res = follow_ssa_edge_expr (loop, loop_phi_node, arg,
+ loop_phi_node, &ev_fn, 0);
/* If ev_fn has no evolution in the inner loop, and the
init_cond is not equal to ev_fn, then we have an
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 03c1a2a..1505ce5 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -1812,11 +1812,15 @@ build_reconstructed_reference (location_t, tree base, struct access *model)
while (!types_compatible_p (TREE_TYPE (expr), TREE_TYPE (base)))
{
if (!handled_component_p (expr))
- return NULL;
+ return NULL_TREE;
prev_expr = expr;
expr = TREE_OPERAND (expr, 0);
}
+ /* Guard against broken VIEW_CONVERT_EXPRs... */
+ if (!prev_expr)
+ return NULL_TREE;
+
TREE_OPERAND (prev_expr, 0) = base;
tree ref = unshare_expr (model->expr);
TREE_OPERAND (prev_expr, 0) = expr;
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 4dd7035..458b218 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -2598,7 +2598,7 @@ optimize_stack_restore (gimple_stmt_iterator i)
|| ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callee)))
return NULL_TREE;
- if (DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE)
+ if (fndecl_built_in_p (callee, BUILT_IN_STACK_RESTORE))
goto second_stack_restore;
}
@@ -2657,9 +2657,6 @@ optimize_stdarg_builtin (gimple *call)
bool va_list_simple_ptr;
location_t loc = gimple_location (call);
- if (gimple_code (call) != GIMPLE_CALL)
- return NULL_TREE;
-
callee = gimple_call_fndecl (call);
cfun_va_list = targetm.fn_abi_va_list (callee);
@@ -2962,12 +2959,10 @@ optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip,
bit, flag);
gimple_call_set_lhs (g, new_lhs);
gimple_set_location (g, gimple_location (call));
- gimple_set_vuse (g, gimple_vuse (call));
- gimple_set_vdef (g, gimple_vdef (call));
+ gimple_move_vops (g, call);
bool throws = stmt_can_throw_internal (cfun, call);
gimple_call_set_nothrow (as_a <gcall *> (g),
gimple_call_nothrow_p (as_a <gcall *> (call)));
- SSA_NAME_DEF_STMT (gimple_vdef (call)) = g;
gimple_stmt_iterator gsi = *gsip;
gsi_insert_after (&gsi, g, GSI_NEW_STMT);
edge e = NULL;
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index 6398c1e..80d5f5c 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -115,6 +115,14 @@ static bool cfg_altered;
static int *bb_postorder;
+/* True if we should treat any stmt with a vdef as necessary. */
+
+static inline bool
+keep_all_vdefs_p ()
+{
+ return optimize_debug;
+}
+
/* If STMT is not already marked necessary, mark it, and add it to the
worklist if ADD_TO_WORKLIST is true. */
@@ -237,6 +245,12 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive)
default:;
}
+
+ if (callee != NULL_TREE
+ && flag_allocation_dce
+ && DECL_IS_REPLACEABLE_OPERATOR_NEW_P (callee))
+ return;
+
/* Most, but not all function calls are required. Function calls that
produce no result and have no side effects (i.e. const pure
functions) are unnecessary. */
@@ -311,6 +325,12 @@ mark_stmt_if_obviously_necessary (gimple *stmt, bool aggressive)
return;
}
+ if (gimple_vdef (stmt) && keep_all_vdefs_p ())
+ {
+ mark_stmt_necessary (stmt, true);
+ return;
+ }
+
return;
}
@@ -526,6 +546,9 @@ mark_aliased_reaching_defs_necessary_1 (ao_ref *ref, tree vdef, void *data)
static void
mark_aliased_reaching_defs_necessary (gimple *stmt, tree ref)
{
+ /* Should have been caught before calling this function. */
+ gcc_checking_assert (!keep_all_vdefs_p ());
+
unsigned int chain;
ao_ref refd;
gcc_assert (!chain_ovfl);
@@ -588,6 +611,11 @@ mark_all_reaching_defs_necessary_1 (ao_ref *ref ATTRIBUTE_UNUSED,
default:;
}
+
+ if (callee != NULL_TREE
+ && (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (callee)
+ || DECL_IS_OPERATOR_DELETE_P (callee)))
+ return false;
}
if (! gimple_clobber_p (def_stmt))
@@ -599,6 +627,8 @@ mark_all_reaching_defs_necessary_1 (ao_ref *ref ATTRIBUTE_UNUSED,
static void
mark_all_reaching_defs_necessary (gimple *stmt)
{
+ /* Should have been caught before calling this function. */
+ gcc_checking_assert (!keep_all_vdefs_p ());
walk_aliased_vdefs (NULL, gimple_vuse (stmt),
mark_all_reaching_defs_necessary_1, NULL, &visited);
}
@@ -774,7 +804,11 @@ propagate_necessity (bool aggressive)
/* If this is a call to free which is directly fed by an
allocation function do not mark that necessary through
processing the argument. */
- if (gimple_call_builtin_p (stmt, BUILT_IN_FREE))
+ bool is_delete_operator
+ = (is_gimple_call (stmt)
+ && gimple_call_operator_delete_p (as_a <gcall *> (stmt)));
+ if (is_delete_operator
+ || gimple_call_builtin_p (stmt, BUILT_IN_FREE))
{
tree ptr = gimple_call_arg (stmt, 0);
gimple *def_stmt;
@@ -784,11 +818,25 @@ propagate_necessity (bool aggressive)
if (TREE_CODE (ptr) == SSA_NAME
&& is_gimple_call (def_stmt = SSA_NAME_DEF_STMT (ptr))
&& (def_callee = gimple_call_fndecl (def_stmt))
- && DECL_BUILT_IN_CLASS (def_callee) == BUILT_IN_NORMAL
- && (DECL_FUNCTION_CODE (def_callee) == BUILT_IN_ALIGNED_ALLOC
- || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_MALLOC
- || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_CALLOC))
- continue;
+ && ((DECL_BUILT_IN_CLASS (def_callee) == BUILT_IN_NORMAL
+ && (DECL_FUNCTION_CODE (def_callee) == BUILT_IN_ALIGNED_ALLOC
+ || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_MALLOC
+ || DECL_FUNCTION_CODE (def_callee) == BUILT_IN_CALLOC))
+ || DECL_IS_REPLACEABLE_OPERATOR_NEW_P (def_callee)))
+ {
+ /* Delete operators can have alignment and (or) size as next
+ arguments. When being a SSA_NAME, they must be marked
+ as necessary. */
+ if (is_delete_operator && gimple_call_num_args (stmt) >= 2)
+ for (unsigned i = 1; i < gimple_call_num_args (stmt); i++)
+ {
+ tree arg = gimple_call_arg (stmt, i);
+ if (TREE_CODE (arg) == SSA_NAME)
+ mark_operand_necessary (arg);
+ }
+
+ continue;
+ }
}
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
@@ -798,6 +846,10 @@ propagate_necessity (bool aggressive)
if (!use)
continue;
+ /* No need to search for vdefs if we intrinsicly keep them all. */
+ if (keep_all_vdefs_p ())
+ continue;
+
/* If we dropped to simple mode make all immediately
reachable definitions necessary. */
if (chain_ovfl)
@@ -842,6 +894,11 @@ propagate_necessity (bool aggressive)
|| DECL_FUNCTION_CODE (callee) == BUILT_IN_ASSUME_ALIGNED))
continue;
+ if (callee != NULL_TREE
+ && (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (callee)
+ || DECL_IS_OPERATOR_DELETE_P (callee)))
+ continue;
+
/* Calls implicitly load from memory, their arguments
in addition may explicitly perform memory loads. */
mark_all_reaching_defs_necessary (stmt);
@@ -1262,7 +1319,9 @@ eliminate_unnecessary_stmts (void)
defining statement of its argument is not necessary
(and thus is getting removed). */
if (gimple_plf (stmt, STMT_NECESSARY)
- && gimple_call_builtin_p (stmt, BUILT_IN_FREE))
+ && (gimple_call_builtin_p (stmt, BUILT_IN_FREE)
+ || (is_gimple_call (stmt)
+ && gimple_call_operator_delete_p (as_a <gcall *> (stmt)))))
{
tree ptr = gimple_call_arg (stmt, 0);
if (TREE_CODE (ptr) == SSA_NAME)
@@ -1319,12 +1378,13 @@ eliminate_unnecessary_stmts (void)
did not mark as necessary, it will confuse the
special logic we apply to malloc/free pair removal. */
&& (!(call = gimple_call_fndecl (stmt))
- || DECL_BUILT_IN_CLASS (call) != BUILT_IN_NORMAL
- || (DECL_FUNCTION_CODE (call) != BUILT_IN_ALIGNED_ALLOC
- && DECL_FUNCTION_CODE (call) != BUILT_IN_MALLOC
- && DECL_FUNCTION_CODE (call) != BUILT_IN_CALLOC
- && !ALLOCA_FUNCTION_CODE_P
- (DECL_FUNCTION_CODE (call)))))
+ || ((DECL_BUILT_IN_CLASS (call) != BUILT_IN_NORMAL
+ || (DECL_FUNCTION_CODE (call) != BUILT_IN_ALIGNED_ALLOC
+ && DECL_FUNCTION_CODE (call) != BUILT_IN_MALLOC
+ && DECL_FUNCTION_CODE (call) != BUILT_IN_CALLOC
+ && !ALLOCA_FUNCTION_CODE_P
+ (DECL_FUNCTION_CODE (call))))
+ && !DECL_IS_REPLACEABLE_OPERATOR_NEW_P (call))))
{
something_changed = true;
if (dump_file && (dump_flags & TDF_DETAILS))
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 2d03866..bcb5cf4 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -901,7 +901,7 @@ simplify_stmt_for_jump_threading (gimple *stmt,
if (TREE_CODE (op) != SSA_NAME)
return NULL_TREE;
- value_range *vr = x_vr_values->get_value_range (op);
+ const value_range *vr = x_vr_values->get_value_range (op);
if (vr->undefined_p ()
|| vr->varying_p ()
|| vr->symbolic_p ())
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index 2828c6b..c464c89 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -1403,7 +1403,7 @@ simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2)
build_int_cst (TREE_TYPE (len1), src_len));
update_stmt (stmt1);
unlink_stmt_vdef (stmt2);
- gsi_remove (gsi_p, true);
+ gsi_replace (gsi_p, gimple_build_nop (), false);
fwprop_invalidate_lattice (gimple_get_lhs (stmt2));
release_defs (stmt2);
if (lhs1 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY)
@@ -2299,13 +2299,14 @@ pass_forwprop::execute (function *fun)
int postorder_num = pre_and_rev_post_order_compute_fn (cfun, NULL,
postorder, false);
auto_vec<gimple *, 4> to_fixup;
+ auto_vec<gimple *, 32> to_remove;
to_purge = BITMAP_ALLOC (NULL);
for (int i = 0; i < postorder_num; ++i)
{
gimple_stmt_iterator gsi;
basic_block bb = BASIC_BLOCK_FOR_FN (fun, postorder[i]);
- /* Propagate into PHIs and record degenerate ones in the lattice. */
+ /* Record degenerate PHIs in the lattice. */
for (gphi_iterator si = gsi_start_phis (bb); !gsi_end_p (si);
gsi_next (&si))
{
@@ -2321,17 +2322,20 @@ pass_forwprop::execute (function *fun)
FOR_EACH_PHI_ARG (use_p, phi, it, SSA_OP_USE)
{
tree use = USE_FROM_PTR (use_p);
- tree tem = fwprop_ssa_val (use);
if (! first)
- first = tem;
- else if (! operand_equal_p (first, tem, 0))
- all_same = false;
- if (tem != use
- && may_propagate_copy (use, tem))
- propagate_value (use_p, tem);
+ first = use;
+ else if (! operand_equal_p (first, use, 0))
+ {
+ all_same = false;
+ break;
+ }
}
if (all_same)
- fwprop_set_lattice_val (res, first);
+ {
+ if (may_propagate_copy (res, first))
+ to_remove.safe_push (phi);
+ fwprop_set_lattice_val (res, first);
+ }
}
/* Apply forward propagation to all stmts in the basic-block.
@@ -2648,148 +2652,223 @@ pass_forwprop::execute (function *fun)
/* Combine stmts with the stmts defining their operands.
Note we update GSI within the loop as necessary. */
- for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple *stmt = gsi_stmt (gsi);
- gimple *orig_stmt = stmt;
- bool changed = false;
- bool was_noreturn = (is_gimple_call (stmt)
- && gimple_call_noreturn_p (stmt));
/* Mark stmt as potentially needing revisiting. */
gimple_set_plf (stmt, GF_PLF_1, false);
- if (fold_stmt (&gsi, fwprop_ssa_val))
+ /* Substitute from our lattice. We need to do so only once. */
+ bool substituted_p = false;
+ use_operand_p usep;
+ ssa_op_iter iter;
+ FOR_EACH_SSA_USE_OPERAND (usep, stmt, iter, SSA_OP_USE)
{
- changed = true;
- stmt = gsi_stmt (gsi);
- if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
- bitmap_set_bit (to_purge, bb->index);
- if (!was_noreturn
- && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
- to_fixup.safe_push (stmt);
- /* Cleanup the CFG if we simplified a condition to
- true or false. */
- if (gcond *cond = dyn_cast <gcond *> (stmt))
- if (gimple_cond_true_p (cond)
- || gimple_cond_false_p (cond))
- cfg_changed = true;
- update_stmt (stmt);
+ tree use = USE_FROM_PTR (usep);
+ tree val = fwprop_ssa_val (use);
+ if (val && val != use && may_propagate_copy (use, val))
+ {
+ propagate_value (usep, val);
+ substituted_p = true;
+ }
}
+ if (substituted_p
+ && is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
+ recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
- switch (gimple_code (stmt))
+ bool changed;
+ do
{
- case GIMPLE_ASSIGN:
- {
- tree rhs1 = gimple_assign_rhs1 (stmt);
- enum tree_code code = gimple_assign_rhs_code (stmt);
+ gimple *orig_stmt = stmt = gsi_stmt (gsi);
+ bool was_noreturn = (is_gimple_call (stmt)
+ && gimple_call_noreturn_p (stmt));
+ changed = false;
- if (code == COND_EXPR
- || code == VEC_COND_EXPR)
+ if (fold_stmt (&gsi, fwprop_ssa_val))
+ {
+ changed = true;
+ stmt = gsi_stmt (gsi);
+ /* Cleanup the CFG if we simplified a condition to
+ true or false. */
+ if (gcond *cond = dyn_cast <gcond *> (stmt))
+ if (gimple_cond_true_p (cond)
+ || gimple_cond_false_p (cond))
+ cfg_changed = true;
+ }
+
+ if (changed || substituted_p)
+ {
+ if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
+ bitmap_set_bit (to_purge, bb->index);
+ if (!was_noreturn
+ && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
+ to_fixup.safe_push (stmt);
+ update_stmt (stmt);
+ substituted_p = false;
+ }
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_ASSIGN:
{
- /* In this case the entire COND_EXPR is in rhs1. */
- if (forward_propagate_into_cond (&gsi))
+ tree rhs1 = gimple_assign_rhs1 (stmt);
+ enum tree_code code = gimple_assign_rhs_code (stmt);
+
+ if (code == COND_EXPR
+ || code == VEC_COND_EXPR)
{
- changed = true;
- stmt = gsi_stmt (gsi);
+ /* In this case the entire COND_EXPR is in rhs1. */
+ if (forward_propagate_into_cond (&gsi))
+ {
+ changed = true;
+ stmt = gsi_stmt (gsi);
+ }
}
+ else if (TREE_CODE_CLASS (code) == tcc_comparison)
+ {
+ int did_something;
+ did_something = forward_propagate_into_comparison (&gsi);
+ if (maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (gsi)))
+ bitmap_set_bit (to_purge, bb->index);
+ if (did_something == 2)
+ cfg_changed = true;
+ changed = did_something != 0;
+ }
+ else if ((code == PLUS_EXPR
+ || code == BIT_IOR_EXPR
+ || code == BIT_XOR_EXPR)
+ && simplify_rotate (&gsi))
+ changed = true;
+ else if (code == VEC_PERM_EXPR)
+ {
+ int did_something = simplify_permutation (&gsi);
+ if (did_something == 2)
+ cfg_changed = true;
+ changed = did_something != 0;
+ }
+ else if (code == BIT_FIELD_REF)
+ changed = simplify_bitfield_ref (&gsi);
+ else if (code == CONSTRUCTOR
+ && TREE_CODE (TREE_TYPE (rhs1)) == VECTOR_TYPE)
+ changed = simplify_vector_constructor (&gsi);
+ break;
}
- else if (TREE_CODE_CLASS (code) == tcc_comparison)
+
+ case GIMPLE_SWITCH:
+ changed = simplify_gimple_switch (as_a <gswitch *> (stmt));
+ break;
+
+ case GIMPLE_COND:
{
- int did_something;
- did_something = forward_propagate_into_comparison (&gsi);
- if (maybe_clean_or_replace_eh_stmt (stmt, gsi_stmt (gsi)))
- bitmap_set_bit (to_purge, bb->index);
+ int did_something = forward_propagate_into_gimple_cond
+ (as_a <gcond *> (stmt));
if (did_something == 2)
cfg_changed = true;
changed = did_something != 0;
+ break;
}
- else if ((code == PLUS_EXPR
- || code == BIT_IOR_EXPR
- || code == BIT_XOR_EXPR)
- && simplify_rotate (&gsi))
- changed = true;
- else if (code == VEC_PERM_EXPR)
+
+ case GIMPLE_CALL:
{
- int did_something = simplify_permutation (&gsi);
- if (did_something == 2)
- cfg_changed = true;
- changed = did_something != 0;
+ tree callee = gimple_call_fndecl (stmt);
+ if (callee != NULL_TREE
+ && fndecl_built_in_p (callee, BUILT_IN_NORMAL))
+ changed = simplify_builtin_call (&gsi, callee);
+ break;
}
- else if (code == BIT_FIELD_REF)
- changed = simplify_bitfield_ref (&gsi);
- else if (code == CONSTRUCTOR
- && TREE_CODE (TREE_TYPE (rhs1)) == VECTOR_TYPE)
- changed = simplify_vector_constructor (&gsi);
- break;
- }
-
- case GIMPLE_SWITCH:
- changed = simplify_gimple_switch (as_a <gswitch *> (stmt));
- break;
- case GIMPLE_COND:
- {
- int did_something
- = forward_propagate_into_gimple_cond (as_a <gcond *> (stmt));
- if (did_something == 2)
- cfg_changed = true;
- changed = did_something != 0;
- break;
- }
-
- case GIMPLE_CALL:
- {
- tree callee = gimple_call_fndecl (stmt);
- if (callee != NULL_TREE
- && fndecl_built_in_p (callee, BUILT_IN_NORMAL))
- changed = simplify_builtin_call (&gsi, callee);
- break;
- }
+ default:;
+ }
- default:;
+ if (changed)
+ {
+ /* If the stmt changed then re-visit it and the statements
+ inserted before it. */
+ for (; !gsi_end_p (gsi); gsi_prev (&gsi))
+ if (gimple_plf (gsi_stmt (gsi), GF_PLF_1))
+ break;
+ if (gsi_end_p (gsi))
+ gsi = gsi_start_bb (bb);
+ else
+ gsi_next (&gsi);
+ }
}
+ while (changed);
- if (changed)
- {
- /* If the stmt changed then re-visit it and the statements
- inserted before it. */
- for (; !gsi_end_p (gsi); gsi_prev (&gsi))
- if (gimple_plf (gsi_stmt (gsi), GF_PLF_1))
- break;
- if (gsi_end_p (gsi))
- gsi = gsi_start_bb (bb);
- else
- gsi_next (&gsi);
- }
- else
- {
- /* Stmt no longer needs to be revisited. */
- gimple_set_plf (stmt, GF_PLF_1, true);
+ /* Stmt no longer needs to be revisited. */
+ stmt = gsi_stmt (gsi);
+ gcc_checking_assert (!gimple_plf (stmt, GF_PLF_1));
+ gimple_set_plf (stmt, GF_PLF_1, true);
- /* Fill up the lattice. */
- if (gimple_assign_single_p (stmt))
+ /* Fill up the lattice. */
+ if (gimple_assign_single_p (stmt))
+ {
+ tree lhs = gimple_assign_lhs (stmt);
+ tree rhs = gimple_assign_rhs1 (stmt);
+ if (TREE_CODE (lhs) == SSA_NAME)
{
- tree lhs = gimple_assign_lhs (stmt);
- tree rhs = gimple_assign_rhs1 (stmt);
- if (TREE_CODE (lhs) == SSA_NAME)
- {
- tree val = lhs;
- if (TREE_CODE (rhs) == SSA_NAME)
- val = fwprop_ssa_val (rhs);
- else if (is_gimple_min_invariant (rhs))
- val = rhs;
- fwprop_set_lattice_val (lhs, val);
- }
+ tree val = lhs;
+ if (TREE_CODE (rhs) == SSA_NAME)
+ val = fwprop_ssa_val (rhs);
+ else if (is_gimple_min_invariant (rhs))
+ val = rhs;
+ /* If we can propagate the lattice-value mark the
+ stmt for removal. */
+ if (val != lhs
+ && may_propagate_copy (lhs, val))
+ to_remove.safe_push (stmt);
+ fwprop_set_lattice_val (lhs, val);
}
-
- gsi_next (&gsi);
}
+ else if (gimple_nop_p (stmt))
+ to_remove.safe_push (stmt);
}
+
+ /* Substitute in destination PHI arguments. */
+ edge_iterator ei;
+ edge e;
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ for (gphi_iterator gsi = gsi_start_phis (e->dest);
+ !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gphi *phi = gsi.phi ();
+ use_operand_p use_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, e);
+ tree arg = USE_FROM_PTR (use_p);
+ if (TREE_CODE (arg) != SSA_NAME
+ || virtual_operand_p (arg))
+ continue;
+ tree val = fwprop_ssa_val (arg);
+ if (val != arg
+ && may_propagate_copy (arg, val))
+ propagate_value (use_p, val);
+ }
}
free (postorder);
lattice.release ();
+ /* Remove stmts in reverse order to make debug stmt creation possible. */
+ while (!to_remove.is_empty())
+ {
+ gimple *stmt = to_remove.pop ();
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Removing dead stmt ");
+ print_gimple_stmt (dump_file, stmt, 0);
+ fprintf (dump_file, "\n");
+ }
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+ if (gimple_code (stmt) == GIMPLE_PHI)
+ remove_phi_node (&gsi, true);
+ else
+ {
+ unlink_stmt_vdef (stmt);
+ gsi_remove (&gsi, true);
+ release_defs (stmt);
+ }
+ }
+
/* Fixup stmts that became noreturn calls. This may require splitting
blocks and thus isn't possible during the walk. Do this
in reverse order so we don't inadvertedly remove a stmt we want to
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 12176e0..c247d74 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -1579,10 +1579,12 @@ static unsigned *bb_loop_postorder;
/* qsort sort function to sort blocks after their loop fathers postorder. */
static int
-sort_bbs_in_loop_postorder_cmp (const void *bb1_, const void *bb2_)
+sort_bbs_in_loop_postorder_cmp (const void *bb1_, const void *bb2_,
+ void *bb_loop_postorder_)
{
- basic_block bb1 = *(basic_block *)const_cast<void *>(bb1_);
- basic_block bb2 = *(basic_block *)const_cast<void *>(bb2_);
+ unsigned *bb_loop_postorder = (unsigned *)bb_loop_postorder_;
+ basic_block bb1 = *(const basic_block *)bb1_;
+ basic_block bb2 = *(const basic_block *)bb2_;
class loop *loop1 = bb1->loop_father;
class loop *loop2 = bb2->loop_father;
if (loop1->num == loop2->num)
@@ -1593,10 +1595,12 @@ sort_bbs_in_loop_postorder_cmp (const void *bb1_, const void *bb2_)
/* qsort sort function to sort ref locs after their loop fathers postorder. */
static int
-sort_locs_in_loop_postorder_cmp (const void *loc1_, const void *loc2_)
+sort_locs_in_loop_postorder_cmp (const void *loc1_, const void *loc2_,
+ void *bb_loop_postorder_)
{
- mem_ref_loc *loc1 = (mem_ref_loc *)const_cast<void *>(loc1_);
- mem_ref_loc *loc2 = (mem_ref_loc *)const_cast<void *>(loc2_);
+ unsigned *bb_loop_postorder = (unsigned *)bb_loop_postorder_;
+ const mem_ref_loc *loc1 = (const mem_ref_loc *)loc1_;
+ const mem_ref_loc *loc2 = (const mem_ref_loc *)loc2_;
class loop *loop1 = gimple_bb (loc1->stmt)->loop_father;
class loop *loop2 = gimple_bb (loc2->stmt)->loop_father;
if (loop1->num == loop2->num)
@@ -1622,7 +1626,8 @@ analyze_memory_references (void)
if (bb->loop_father != current_loops->tree_root)
bbs[i++] = bb;
n = i;
- qsort (bbs, n, sizeof (basic_block), sort_bbs_in_loop_postorder_cmp);
+ gcc_sort_r (bbs, n, sizeof (basic_block), sort_bbs_in_loop_postorder_cmp,
+ bb_loop_postorder);
/* Visit blocks in loop postorder and assign mem-ref IDs in that order.
That results in better locality for all the bitmaps. */
@@ -1637,10 +1642,10 @@ analyze_memory_references (void)
loop postorder number. */
im_mem_ref *ref;
FOR_EACH_VEC_ELT (memory_accesses.refs_list, i, ref)
- ref->accesses_in_loop.qsort (sort_locs_in_loop_postorder_cmp);
+ ref->accesses_in_loop.sort (sort_locs_in_loop_postorder_cmp,
+ bb_loop_postorder);
free (bbs);
-// free (bb_loop_postorder);
/* Propagate the information about accessed memory references up
the loop hierarchy. */
@@ -1700,8 +1705,10 @@ mem_refs_may_alias_p (im_mem_ref *mem1, im_mem_ref *mem2,
in a loop. */
static int
-find_ref_loc_in_loop_cmp (const void *loop_, const void *loc_)
+find_ref_loc_in_loop_cmp (const void *loop_, const void *loc_,
+ void *bb_loop_postorder_)
{
+ unsigned *bb_loop_postorder = (unsigned *)bb_loop_postorder_;
class loop *loop = (class loop *)const_cast<void *>(loop_);
mem_ref_loc *loc = (mem_ref_loc *)const_cast<void *>(loc_);
class loop *loc_loop = gimple_bb (loc->stmt)->loop_father;
@@ -1726,7 +1733,8 @@ for_all_locs_in_loop (class loop *loop, im_mem_ref *ref, FN fn)
/* Search for the cluster of locs in the accesses_in_loop vector
which is sorted after postorder index of the loop father. */
- loc = ref->accesses_in_loop.bsearch (loop, find_ref_loc_in_loop_cmp);
+ loc = ref->accesses_in_loop.bsearch (loop, find_ref_loc_in_loop_cmp,
+ bb_loop_postorder);
if (!loc)
return false;
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index b7bbde4..5fea155 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -1040,14 +1040,9 @@ pass_cse_reciprocals::execute (function *fun)
else
stmt2 = gimple_build_call_internal_vec (ifn, args);
gimple_call_set_lhs (stmt2, arg1);
- if (gimple_vdef (call))
- {
- gimple_set_vdef (stmt2, gimple_vdef (call));
- SSA_NAME_DEF_STMT (gimple_vdef (stmt2)) = stmt2;
- }
+ gimple_move_vops (stmt2, call);
gimple_call_set_nothrow (stmt2,
gimple_call_nothrow_p (call));
- gimple_set_vuse (stmt2, gimple_vuse (call));
gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
gsi_replace (&gsi2, stmt2, true);
}
@@ -3044,6 +3039,8 @@ last_fma_candidate_feeds_initial_phi (fma_deferring_state *state,
/* Combine the multiplication at MUL_STMT with operands MULOP1 and MULOP2
with uses in additions and subtractions to form fused multiply-add
operations. Returns true if successful and MUL_STMT should be removed.
+ If MUL_COND is nonnull, the multiplication in MUL_STMT is conditional
+ on MUL_COND, otherwise it is unconditional.
If STATE indicates that we are deferring FMA transformation, that means
that we do not produce FMAs for basic blocks which look like:
@@ -3060,7 +3057,7 @@ last_fma_candidate_feeds_initial_phi (fma_deferring_state *state,
static bool
convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2,
- fma_deferring_state *state)
+ fma_deferring_state *state, tree mul_cond = NULL_TREE)
{
tree mul_result = gimple_get_lhs (mul_stmt);
tree type = TREE_TYPE (mul_result);
@@ -3174,6 +3171,9 @@ convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2,
return false;
}
+ if (mul_cond && cond != mul_cond)
+ return false;
+
if (cond)
{
if (cond == result || else_value == result)
@@ -3785,38 +3785,48 @@ math_opts_dom_walker::after_dom_children (basic_block bb)
}
else if (is_gimple_call (stmt))
{
- tree fndecl = gimple_call_fndecl (stmt);
- if (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
+ switch (gimple_call_combined_fn (stmt))
{
- switch (DECL_FUNCTION_CODE (fndecl))
+ CASE_CFN_POW:
+ if (gimple_call_lhs (stmt)
+ && TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST
+ && real_equal (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),
+ &dconst2)
+ && convert_mult_to_fma (stmt,
+ gimple_call_arg (stmt, 0),
+ gimple_call_arg (stmt, 0),
+ &fma_state))
{
- case BUILT_IN_POWF:
- case BUILT_IN_POW:
- case BUILT_IN_POWL:
- if (gimple_call_lhs (stmt)
- && TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST
- && real_equal
- (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),
- &dconst2)
- && convert_mult_to_fma (stmt,
- gimple_call_arg (stmt, 0),
- gimple_call_arg (stmt, 0),
- &fma_state))
- {
- unlink_stmt_vdef (stmt);
- if (gsi_remove (&gsi, true)
- && gimple_purge_dead_eh_edges (bb))
- *m_cfg_changed_p = true;
- release_defs (stmt);
- continue;
- }
- break;
+ unlink_stmt_vdef (stmt);
+ if (gsi_remove (&gsi, true)
+ && gimple_purge_dead_eh_edges (bb))
+ *m_cfg_changed_p = true;
+ release_defs (stmt);
+ continue;
+ }
+ break;
- default:;
+ case CFN_COND_MUL:
+ if (convert_mult_to_fma (stmt,
+ gimple_call_arg (stmt, 1),
+ gimple_call_arg (stmt, 2),
+ &fma_state,
+ gimple_call_arg (stmt, 0)))
+
+ {
+ gsi_remove (&gsi, true);
+ release_defs (stmt);
+ continue;
}
+ break;
+
+ case CFN_LAST:
+ cancel_fma_deferring (&fma_state);
+ break;
+
+ default:
+ break;
}
- else
- cancel_fma_deferring (&fma_state);
}
gsi_next (&gsi);
}
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 36da4c6a..c618601 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -2013,8 +2013,6 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block)
}
}
-static sbitmap has_abnormal_preds;
-
/* Compute the ANTIC set for BLOCK.
If succs(BLOCK) > 1 then
@@ -2352,7 +2350,7 @@ compute_antic (void)
/* If any predecessor edges are abnormal, we punt, so antic_in is empty.
We pre-build the map of blocks with incoming abnormal edges here. */
- has_abnormal_preds = sbitmap_alloc (last_basic_block_for_fn (cfun));
+ auto_sbitmap has_abnormal_preds (last_basic_block_for_fn (cfun));
bitmap_clear (has_abnormal_preds);
FOR_ALL_BB_FN (block, cfun)
@@ -2436,8 +2434,6 @@ compute_antic (void)
block->index));
}
}
-
- sbitmap_free (has_abnormal_preds);
}
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c
index 6b78dc1..0862f83 100644
--- a/gcc/tree-ssa-propagate.c
+++ b/gcc/tree-ssa-propagate.c
@@ -625,8 +625,7 @@ finish_update_gimple_call (gimple_stmt_iterator *si_p, gimple *new_stmt,
{
gimple_call_set_lhs (new_stmt, gimple_call_lhs (stmt));
move_ssa_defining_stmt_for_defs (new_stmt, stmt);
- gimple_set_vuse (new_stmt, gimple_vuse (stmt));
- gimple_set_vdef (new_stmt, gimple_vdef (stmt));
+ gimple_move_vops (new_stmt, stmt);
gimple_set_location (new_stmt, gimple_location (stmt));
if (gimple_block (new_stmt) == NULL_TREE)
gimple_set_block (new_stmt, gimple_block (stmt));
@@ -706,8 +705,7 @@ update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
STRIP_USELESS_TYPE_CONVERSION (expr);
new_stmt = gimple_build_assign (lhs, expr);
move_ssa_defining_stmt_for_defs (new_stmt, stmt);
- gimple_set_vuse (new_stmt, gimple_vuse (stmt));
- gimple_set_vdef (new_stmt, gimple_vdef (stmt));
+ gimple_move_vops (new_stmt, stmt);
}
else if (!TREE_SIDE_EFFECTS (expr))
{
@@ -732,8 +730,7 @@ update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
else
lhs = create_tmp_var (TREE_TYPE (expr));
new_stmt = gimple_build_assign (lhs, expr);
- gimple_set_vuse (new_stmt, gimple_vuse (stmt));
- gimple_set_vdef (new_stmt, gimple_vdef (stmt));
+ gimple_move_vops (new_stmt, stmt);
move_ssa_defining_stmt_for_defs (new_stmt, stmt);
}
gimple_set_location (new_stmt, gimple_location (stmt));
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 9369c36..eb7e4be 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1249,113 +1249,123 @@ static bool
vn_reference_maybe_forwprop_address (vec<vn_reference_op_s> *ops,
unsigned int *i_p)
{
- unsigned int i = *i_p;
- vn_reference_op_t op = &(*ops)[i];
- vn_reference_op_t mem_op = &(*ops)[i - 1];
- gimple *def_stmt;
- enum tree_code code;
- poly_offset_int off;
-
- def_stmt = SSA_NAME_DEF_STMT (op->op0);
- if (!is_gimple_assign (def_stmt))
- return false;
-
- code = gimple_assign_rhs_code (def_stmt);
- if (code != ADDR_EXPR
- && code != POINTER_PLUS_EXPR)
- return false;
-
- off = poly_offset_int::from (wi::to_poly_wide (mem_op->op0), SIGNED);
+ bool changed = false;
+ vn_reference_op_t op;
- /* The only thing we have to do is from &OBJ.foo.bar add the offset
- from .foo.bar to the preceding MEM_REF offset and replace the
- address with &OBJ. */
- if (code == ADDR_EXPR)
+ do
{
- tree addr, addr_base;
- poly_int64 addr_offset;
-
- addr = gimple_assign_rhs1 (def_stmt);
- addr_base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0),
- &addr_offset);
- /* If that didn't work because the address isn't invariant propagate
- the reference tree from the address operation in case the current
- dereference isn't offsetted. */
- if (!addr_base
- && *i_p == ops->length () - 1
- && known_eq (off, 0)
- /* This makes us disable this transform for PRE where the
- reference ops might be also used for code insertion which
- is invalid. */
- && default_vn_walk_kind == VN_WALKREWRITE)
+ unsigned int i = *i_p;
+ op = &(*ops)[i];
+ vn_reference_op_t mem_op = &(*ops)[i - 1];
+ gimple *def_stmt;
+ enum tree_code code;
+ poly_offset_int off;
+
+ def_stmt = SSA_NAME_DEF_STMT (op->op0);
+ if (!is_gimple_assign (def_stmt))
+ return changed;
+
+ code = gimple_assign_rhs_code (def_stmt);
+ if (code != ADDR_EXPR
+ && code != POINTER_PLUS_EXPR)
+ return changed;
+
+ off = poly_offset_int::from (wi::to_poly_wide (mem_op->op0), SIGNED);
+
+ /* The only thing we have to do is from &OBJ.foo.bar add the offset
+ from .foo.bar to the preceding MEM_REF offset and replace the
+ address with &OBJ. */
+ if (code == ADDR_EXPR)
{
- auto_vec<vn_reference_op_s, 32> tem;
- copy_reference_ops_from_ref (TREE_OPERAND (addr, 0), &tem);
- /* Make sure to preserve TBAA info. The only objects not
- wrapped in MEM_REFs that can have their address taken are
- STRING_CSTs. */
- if (tem.length () >= 2
- && tem[tem.length () - 2].opcode == MEM_REF)
+ tree addr, addr_base;
+ poly_int64 addr_offset;
+
+ addr = gimple_assign_rhs1 (def_stmt);
+ addr_base = get_addr_base_and_unit_offset (TREE_OPERAND (addr, 0),
+ &addr_offset);
+ /* If that didn't work because the address isn't invariant propagate
+ the reference tree from the address operation in case the current
+ dereference isn't offsetted. */
+ if (!addr_base
+ && *i_p == ops->length () - 1
+ && known_eq (off, 0)
+ /* This makes us disable this transform for PRE where the
+ reference ops might be also used for code insertion which
+ is invalid. */
+ && default_vn_walk_kind == VN_WALKREWRITE)
{
- vn_reference_op_t new_mem_op = &tem[tem.length () - 2];
- new_mem_op->op0
- = wide_int_to_tree (TREE_TYPE (mem_op->op0),
- wi::to_poly_wide (new_mem_op->op0));
+ auto_vec<vn_reference_op_s, 32> tem;
+ copy_reference_ops_from_ref (TREE_OPERAND (addr, 0), &tem);
+ /* Make sure to preserve TBAA info. The only objects not
+ wrapped in MEM_REFs that can have their address taken are
+ STRING_CSTs. */
+ if (tem.length () >= 2
+ && tem[tem.length () - 2].opcode == MEM_REF)
+ {
+ vn_reference_op_t new_mem_op = &tem[tem.length () - 2];
+ new_mem_op->op0
+ = wide_int_to_tree (TREE_TYPE (mem_op->op0),
+ wi::to_poly_wide (new_mem_op->op0));
+ }
+ else
+ gcc_assert (tem.last ().opcode == STRING_CST);
+ ops->pop ();
+ ops->pop ();
+ ops->safe_splice (tem);
+ --*i_p;
+ return true;
}
- else
- gcc_assert (tem.last ().opcode == STRING_CST);
- ops->pop ();
- ops->pop ();
- ops->safe_splice (tem);
- --*i_p;
- return true;
+ if (!addr_base
+ || TREE_CODE (addr_base) != MEM_REF
+ || (TREE_CODE (TREE_OPERAND (addr_base, 0)) == SSA_NAME
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (addr_base,
+ 0))))
+ return changed;
+
+ off += addr_offset;
+ off += mem_ref_offset (addr_base);
+ op->op0 = TREE_OPERAND (addr_base, 0);
+ }
+ else
+ {
+ tree ptr, ptroff;
+ ptr = gimple_assign_rhs1 (def_stmt);
+ ptroff = gimple_assign_rhs2 (def_stmt);
+ if (TREE_CODE (ptr) != SSA_NAME
+ || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr)
+ /* Make sure to not endlessly recurse.
+ See gcc.dg/tree-ssa/20040408-1.c for an example. Can easily
+ happen when we value-number a PHI to its backedge value. */
+ || SSA_VAL (ptr) == op->op0
+ || !poly_int_tree_p (ptroff))
+ return changed;
+
+ off += wi::to_poly_offset (ptroff);
+ op->op0 = ptr;
}
- if (!addr_base
- || TREE_CODE (addr_base) != MEM_REF
- || (TREE_CODE (TREE_OPERAND (addr_base, 0)) == SSA_NAME
- && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (addr_base, 0))))
- return false;
-
- off += addr_offset;
- off += mem_ref_offset (addr_base);
- op->op0 = TREE_OPERAND (addr_base, 0);
- }
- else
- {
- tree ptr, ptroff;
- ptr = gimple_assign_rhs1 (def_stmt);
- ptroff = gimple_assign_rhs2 (def_stmt);
- if (TREE_CODE (ptr) != SSA_NAME
- || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr)
- /* Make sure to not endlessly recurse.
- See gcc.dg/tree-ssa/20040408-1.c for an example. Can easily
- happen when we value-number a PHI to its backedge value. */
- || SSA_VAL (ptr) == op->op0
- || !poly_int_tree_p (ptroff))
- return false;
- off += wi::to_poly_offset (ptroff);
- op->op0 = ptr;
+ mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off);
+ if (tree_fits_shwi_p (mem_op->op0))
+ mem_op->off = tree_to_shwi (mem_op->op0);
+ else
+ mem_op->off = -1;
+ /* ??? Can end up with endless recursion here!?
+ gcc.c-torture/execute/strcmp-1.c */
+ if (TREE_CODE (op->op0) == SSA_NAME)
+ op->op0 = SSA_VAL (op->op0);
+ if (TREE_CODE (op->op0) != SSA_NAME)
+ op->opcode = TREE_CODE (op->op0);
+
+ changed = true;
}
+ /* Tail-recurse. */
+ while (TREE_CODE (op->op0) == SSA_NAME);
- mem_op->op0 = wide_int_to_tree (TREE_TYPE (mem_op->op0), off);
- if (tree_fits_shwi_p (mem_op->op0))
- mem_op->off = tree_to_shwi (mem_op->op0);
- else
- mem_op->off = -1;
- /* ??? Can end up with endless recursion here!?
- gcc.c-torture/execute/strcmp-1.c */
- if (TREE_CODE (op->op0) == SSA_NAME)
- op->op0 = SSA_VAL (op->op0);
- if (TREE_CODE (op->op0) != SSA_NAME)
- op->opcode = TREE_CODE (op->op0);
-
- /* And recurse. */
- if (TREE_CODE (op->op0) == SSA_NAME)
- vn_reference_maybe_forwprop_address (ops, i_p);
- else if (TREE_CODE (op->op0) == ADDR_EXPR)
+ /* Fold a remaining *&. */
+ if (TREE_CODE (op->op0) == ADDR_EXPR)
vn_reference_fold_indirect (ops, i_p);
- return true;
+
+ return changed;
}
/* Optimize the reference REF to a constant if possible or return
@@ -1818,7 +1828,7 @@ vn_walk_cb_data::push_partial_def (const pd_data &pd, tree vuse,
if (TREE_CODE (pd.rhs) == CONSTRUCTOR)
/* Empty CONSTRUCTOR. */
memset (buffer + MAX (0, pd.offset),
- 0, MIN ((HOST_WIDE_INT)sizeof (buffer),
+ 0, MIN ((HOST_WIDE_INT)sizeof (buffer) - MAX (0, pd.offset),
pd.size + MIN (0, pd.offset)));
else
{
@@ -1833,7 +1843,7 @@ vn_walk_cb_data::push_partial_def (const pd_data &pd, tree vuse,
pad = GET_MODE_SIZE (mode) - pd.size;
}
len = native_encode_expr (pd.rhs, buffer + MAX (0, pd.offset),
- sizeof (buffer - MAX (0, pd.offset)),
+ sizeof (buffer) - MAX (0, pd.offset),
MAX (0, -pd.offset) + pad);
if (len <= 0 || len < (pd.size - MAX (0, -pd.offset)))
{
@@ -2126,36 +2136,17 @@ class rpo_elim : public eliminate_dom_walker
{
public:
rpo_elim(basic_block entry_)
- : eliminate_dom_walker (CDI_DOMINATORS, NULL), entry (entry_) {}
- ~rpo_elim();
+ : eliminate_dom_walker (CDI_DOMINATORS, NULL), entry (entry_),
+ m_avail_freelist (NULL) {}
virtual tree eliminate_avail (basic_block, tree op);
virtual void eliminate_push_avail (basic_block, tree);
basic_block entry;
- /* Instead of having a local availability lattice for each
- basic-block and availability at X defined as union of
- the local availabilities at X and its dominators we're
- turning this upside down and track availability per
- value given values are usually made available at very
- few points (at least one).
- So we have a value -> vec<location, leader> map where
- LOCATION is specifying the basic-block LEADER is made
- available for VALUE. We push to this vector in RPO
- order thus for iteration we can simply pop the last
- entries.
- LOCATION is the basic-block index and LEADER is its
- SSA name version. */
- /* ??? We'd like to use auto_vec here with embedded storage
- but that doesn't play well until we can provide move
- constructors and use std::move on hash-table expansion.
- So for now this is a bit more expensive than necessary.
- We eventually want to switch to a chaining scheme like
- for hashtable entries for unwinding which would make
- making the vector part of the vn_ssa_aux structure possible. */
- typedef hash_map<tree, vec<std::pair<int, int> > > rpo_avail_t;
- rpo_avail_t m_rpo_avail;
+ /* Freelist of avail entries which are allocated from the vn_ssa_aux
+ obstack. */
+ vn_avail *m_avail_freelist;
};
/* Global RPO state for access from hooks. */
@@ -6197,14 +6188,6 @@ vn_lookup_simplify_result (gimple_match_op *res_op)
return res;
}
-rpo_elim::~rpo_elim ()
-{
- /* Release the avail vectors. */
- for (rpo_avail_t::iterator i = m_rpo_avail.begin ();
- i != m_rpo_avail.end (); ++i)
- (*i).second.release ();
-}
-
/* Return a leader for OPs value that is valid at BB. */
tree
@@ -6220,16 +6203,15 @@ rpo_elim::eliminate_avail (basic_block bb, tree op)
{
if (SSA_NAME_IS_DEFAULT_DEF (valnum))
return valnum;
- vec<std::pair<int, int> > *av = m_rpo_avail.get (valnum);
- if (!av || av->is_empty ())
+ vn_avail *av = VN_INFO (valnum)->avail;
+ if (!av)
return NULL_TREE;
- int i = av->length () - 1;
- if ((*av)[i].first == bb->index)
+ if (av->location == bb->index)
/* On tramp3d 90% of the cases are here. */
- return ssa_name ((*av)[i].second);
+ return ssa_name (av->leader);
do
{
- basic_block abb = BASIC_BLOCK_FOR_FN (cfun, (*av)[i].first);
+ basic_block abb = BASIC_BLOCK_FOR_FN (cfun, av->location);
/* ??? During elimination we have to use availability at the
definition site of a use we try to replace. This
is required to not run into inconsistencies because
@@ -6243,7 +6225,7 @@ rpo_elim::eliminate_avail (basic_block bb, tree op)
executable. */
if (dominated_by_p_w_unex (bb, abb))
{
- tree leader = ssa_name ((*av)[i].second);
+ tree leader = ssa_name (av->leader);
/* Prevent eliminations that break loop-closed SSA. */
if (loops_state_satisfies_p (LOOP_CLOSED_SSA)
&& ! SSA_NAME_IS_DEFAULT_DEF (leader)
@@ -6265,8 +6247,9 @@ rpo_elim::eliminate_avail (basic_block bb, tree op)
/* ??? Can we somehow skip to the immediate dominator
RPO index (bb_to_rpo)? Again, maybe not worth, on
tramp3d the worst number of elements in the vector is 9. */
+ av = av->next;
}
- while (--i >= 0);
+ while (av);
}
else if (valnum != VN_TOP)
/* valnum is is_gimple_min_invariant. */
@@ -6280,7 +6263,8 @@ void
rpo_elim::eliminate_push_avail (basic_block bb, tree leader)
{
tree valnum = VN_INFO (leader)->valnum;
- if (valnum == VN_TOP)
+ if (valnum == VN_TOP
+ || is_gimple_min_invariant (valnum))
return;
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -6290,15 +6274,19 @@ rpo_elim::eliminate_push_avail (basic_block bb, tree leader)
print_generic_expr (dump_file, valnum);
fprintf (dump_file, "\n");
}
- bool existed;
- vec<std::pair<int, int> > &av = m_rpo_avail.get_or_insert (valnum, &existed);
- if (!existed)
+ vn_ssa_aux_t value = VN_INFO (valnum);
+ vn_avail *av;
+ if (m_avail_freelist)
{
- new (&av) vec<std::pair<int, int> >;
- av = vNULL;
- av.reserve_exact (2);
+ av = m_avail_freelist;
+ m_avail_freelist = m_avail_freelist->next;
}
- av.safe_push (std::make_pair (bb->index, SSA_NAME_VERSION (leader)));
+ else
+ av = XOBNEW (&vn_ssa_aux_obstack, vn_avail);
+ av->location = bb->index;
+ av->leader = SSA_NAME_VERSION (leader);
+ av->next = value->avail;
+ value->avail = av;
}
/* Valueization hook for RPO VN plus required state. */
@@ -6780,15 +6768,17 @@ do_unwind (unwind_state *to, int rpo_idx, rpo_elim &avail, int *bb_to_rpo)
/* Prune [rpo_idx, ] from avail. */
/* ??? This is O(number-of-values-in-region) which is
O(region-size) rather than O(iteration-piece). */
- for (rpo_elim::rpo_avail_t::iterator i
- = avail.m_rpo_avail.begin ();
- i != avail.m_rpo_avail.end (); ++i)
+ for (hash_table<vn_ssa_aux_hasher>::iterator i = vn_ssa_aux_hash->begin ();
+ i != vn_ssa_aux_hash->end (); ++i)
{
- while (! (*i).second.is_empty ())
+ while ((*i)->avail)
{
- if (bb_to_rpo[(*i).second.last ().first] < rpo_idx)
+ if (bb_to_rpo[(*i)->avail->location] < rpo_idx)
break;
- (*i).second.pop ();
+ vn_avail *av = (*i)->avail;
+ (*i)->avail = (*i)->avail->next;
+ av->next = avail.m_avail_freelist;
+ avail.m_avail_freelist = av;
}
}
}
@@ -7184,11 +7174,16 @@ do_rpo_vn (function *fn, edge entry, bitmap exit_bbs,
max_visited = rpo_state[i].visited;
}
unsigned nvalues = 0, navail = 0;
- for (rpo_elim::rpo_avail_t::iterator i = avail.m_rpo_avail.begin ();
- i != avail.m_rpo_avail.end (); ++i)
+ for (hash_table<vn_ssa_aux_hasher>::iterator i = vn_ssa_aux_hash->begin ();
+ i != vn_ssa_aux_hash->end (); ++i)
{
nvalues++;
- navail += (*i).second.length ();
+ vn_avail *av = (*i)->avail;
+ while (av)
+ {
+ navail++;
+ av = av->next;
+ }
}
statistics_counter_event (cfun, "RPO blocks", n);
statistics_counter_event (cfun, "RPO blocks visited", nblk);
diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h
index 93718b2..1a5f238 100644
--- a/gcc/tree-ssa-sccvn.h
+++ b/gcc/tree-ssa-sccvn.h
@@ -193,6 +193,25 @@ vn_constant_eq_with_type (tree c1, tree c2)
&& types_compatible_p (TREE_TYPE (c1), TREE_TYPE (c2)));
}
+/* Instead of having a local availability lattice for each basic-block
+ and availability at X defined as union of the local availabilities
+ at X and its dominators we're turning this upside down and track
+ availability per value given values are usually made available at very
+ few points.
+ So we have a chain of LOCATION, LEADER entries where LOCATION is
+ specifying the basic-block LEADER is made available for VALUE.
+ We prepend to this chain in RPO order thus for iteration we can simply
+ remove the last entries.
+ LOCATION is the basic-block index and LEADER is its SSA name version. */
+struct vn_avail
+{
+ vn_avail *next;
+ /* The basic-block LEADER is made available. */
+ int location;
+ /* The LEADER for the value we are chained on. */
+ int leader;
+};
+
typedef struct vn_ssa_aux
{
/* SSA name this vn_ssa_aux is associated with in the lattice. */
@@ -202,6 +221,10 @@ typedef struct vn_ssa_aux
/* Statements to insert if needs_insertion is true. */
gimple_seq expr;
+ /* AVAIL entries, last in RPO order is first. This is only tracked
+ for SSA names also serving as values (NAME == VALNUM). */
+ vn_avail *avail;
+
/* Unique identifier that all expressions with the same value have. */
unsigned int value_id;
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index 88b6bd7..ef2b6ae 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -1195,14 +1195,13 @@ adjust_last_stmt (strinfo *si, gimple *stmt, bool is_strcat)
to constants. */
tree
-set_strlen_range (tree lhs, wide_int max, tree bound /* = NULL_TREE */)
+set_strlen_range (tree lhs, wide_int min, wide_int max,
+ tree bound /* = NULL_TREE */)
{
if (TREE_CODE (lhs) != SSA_NAME
|| !INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
return NULL_TREE;
- wide_int min = wi::zero (max.get_precision ());
-
if (bound)
{
/* For strnlen, adjust MIN and MAX as necessary. If the bound
@@ -1312,7 +1311,8 @@ maybe_set_strlen_range (tree lhs, tree src, tree bound)
}
}
- return set_strlen_range (lhs, max, bound);
+ wide_int min = wi::zero (max.get_precision ());
+ return set_strlen_range (lhs, min, max, bound);
}
/* Handle a strlen call. If strlen of the argument is known, replace
@@ -1434,6 +1434,12 @@ handle_builtin_strlen (gimple_stmt_iterator *gsi)
tree adj = fold_build2_loc (loc, MINUS_EXPR,
TREE_TYPE (lhs), lhs, old);
adjust_related_strinfos (loc, si, adj);
+ /* Use the constant minimim length as the lower bound
+ of the non-constant length. */
+ wide_int min = wi::to_wide (old);
+ wide_int max
+ = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node)) - 2;
+ set_strlen_range (lhs, min, max);
}
else
{
@@ -3328,78 +3334,298 @@ handle_pointer_plus (gimple_stmt_iterator *gsi)
}
}
-/* If RHS, either directly or indirectly, refers to a string of constant
- length, return the length. Otherwise, if it refers to a character
- constant, return 1 if the constant is non-zero and 0 if it is nul.
- Otherwise, return a negative value. */
+/* Describes recursion limits used by count_nonzero_bytes. */
-static HOST_WIDE_INT
-get_min_string_length (tree rhs, bool *full_string_p)
+class ssa_name_limit_t
{
- if (INTEGRAL_TYPE_P (TREE_TYPE (rhs)))
+ bitmap visited; /* Bitmap of visited SSA_NAMEs. */
+ unsigned ssa_def_max; /* Longest chain of SSA_NAMEs to follow. */
+
+ /* Not copyable or assignable. */
+ ssa_name_limit_t (ssa_name_limit_t&);
+ void operator= (ssa_name_limit_t&);
+
+ public:
+
+ ssa_name_limit_t ()
+ : visited (NULL),
+ ssa_def_max (PARAM_VALUE (PARAM_SSA_NAME_DEF_CHAIN_LIMIT)) { }
+
+ int next_ssa_name (tree);
+
+ ~ssa_name_limit_t ()
{
- if (tree_expr_nonzero_p (rhs))
- {
- *full_string_p = false;
- return 1;
- }
+ if (visited)
+ BITMAP_FREE (visited);
+ }
+};
- *full_string_p = true;
- return 0;
+/* If the SSA_NAME has already been "seen" return a positive value.
+ Otherwise add it to VISITED. If the SSA_NAME limit has been
+ reached, return a negative value. Otherwise return zero. */
+
+int ssa_name_limit_t::next_ssa_name (tree ssa_name)
+{
+ if (!visited)
+ visited = BITMAP_ALLOC (NULL);
+
+ /* Return a positive value if SSA_NAME has already been visited. */
+ if (!bitmap_set_bit (visited, SSA_NAME_VERSION (ssa_name)))
+ return 1;
+
+ /* Return a negative value to let caller avoid recursing beyond
+ the specified limit. */
+ if (ssa_def_max == 0)
+ return -1;
+
+ --ssa_def_max;
+
+ return 0;
+}
+
+/* Determine the minimum and maximum number of leading non-zero bytes
+ in the representation of EXP and set LENRANGE[0] and LENRANGE[1]
+ to each. Set LENRANGE[2] to the total number of bytes in
+ the representation. Set *NULTREM if the representation contains
+ a zero byte, and set *ALLNUL if all the bytes are zero. Avoid
+ recursing deeper than the limits in SNLIM allow. Return true
+ on success and false otherwise. */
+
+static bool
+count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
+ unsigned HOST_WIDE_INT nbytes,
+ unsigned lenrange[3], bool *nulterm,
+ bool *allnul, bool *allnonnul, ssa_name_limit_t &snlim)
+{
+ int idx = get_stridx (exp);
+ if (idx > 0)
+ {
+ strinfo *si = get_strinfo (idx);
+ /* FIXME: Handle non-constant lengths in some range. */
+ if (!si || !tree_fits_shwi_p (si->nonzero_chars))
+ return false;
+
+ unsigned len = tree_to_shwi (si->nonzero_chars);
+ unsigned size = len + si->full_string_p;
+ if (size <= offset)
+ return false;
+
+ len -= offset;
+ size -= offset;
+
+ if (size < nbytes)
+ return false;
+
+ if (len < lenrange[0])
+ lenrange[0] = len;
+ if (lenrange[1] < len)
+ lenrange[1] = len;
+
+ if (!si->full_string_p)
+ *nulterm = false;
+
+ /* Since only the length of the string are known and
+ its contents, clear ALLNUL and ALLNONNUL purely on
+ the basis of the length. */
+ if (len)
+ *allnul = false;
+ else
+ *allnonnul = false;
+ return true;
}
- if (TREE_CODE (rhs) == MEM_REF
- && integer_zerop (TREE_OPERAND (rhs, 1)))
+ if (TREE_CODE (exp) == ADDR_EXPR)
+ exp = TREE_OPERAND (exp, 0);
+
+ if (TREE_CODE (exp) == SSA_NAME)
{
- rhs = TREE_OPERAND (rhs, 0);
- if (TREE_CODE (rhs) == ADDR_EXPR)
+ /* Handle a single-character specially. */
+ tree type = TREE_TYPE (exp);
+ if (TREE_CODE (type) == INTEGER_TYPE
+ && TYPE_MODE (type) == TYPE_MODE (char_type_node)
+ && TYPE_PRECISION (type) == TYPE_PRECISION (char_type_node))
{
- tree rhs_addr = rhs;
+ /* Determine if the character EXP is known to be non-zero
+ (even if its exact value is not known) and if so, recurse
+ once to set the range, etc. */
+ if (tree_expr_nonzero_p (exp))
+ return count_nonzero_bytes (build_int_cst (type, 1),
+ offset, nbytes, lenrange,
+ nulterm, allnul, allnonnul, snlim);
+ /* Don't know whether EXP is or isn't nonzero. */
+ return false;
+ }
- rhs = TREE_OPERAND (rhs, 0);
- if (TREE_CODE (rhs) != STRING_CST)
- {
- int idx = get_stridx (rhs_addr);
- if (idx > 0)
- {
- strinfo *si = get_strinfo (idx);
- if (si
- && tree_fits_shwi_p (si->nonzero_chars))
- {
- *full_string_p = si->full_string_p;
- return tree_to_shwi (si->nonzero_chars);
- }
- }
- }
+ gimple *stmt = SSA_NAME_DEF_STMT (exp);
+ if (gimple_code (stmt) != GIMPLE_PHI)
+ return false;
+
+ /* Avoid processing an SSA_NAME that has already been visited
+ or if an SSA_NAME limit has been reached. Indicate success
+ if the former and failure if the latter. */
+ if (int res = snlim.next_ssa_name (exp))
+ return res > 0;
+
+ /* Determine the minimum and maximum from the PHI arguments. */
+ unsigned int n = gimple_phi_num_args (stmt);
+ for (unsigned i = 0; i != n; i++)
+ {
+ tree def = gimple_phi_arg_def (stmt, i);
+ if (!count_nonzero_bytes (def, offset, nbytes, lenrange, nulterm,
+ allnul, allnonnul, snlim))
+ return false;
}
+
+ return true;
+ }
+
+ if (TREE_CODE (exp) == MEM_REF)
+ {
+ tree arg = TREE_OPERAND (exp, 0);
+ tree off = TREE_OPERAND (exp, 1);
+
+ if (TREE_CODE (off) != INTEGER_CST
+ || !tree_fits_uhwi_p (off))
+ return false;
+
+ unsigned HOST_WIDE_INT wioff = tree_to_uhwi (off);
+ if (INT_MAX < wioff)
+ return false;
+
+ offset += wioff;
+ if (INT_MAX < offset)
+ return false;
+
+ /* The size of the MEM_REF access determines the number of bytes. */
+ tree type = TREE_TYPE (exp);
+ if (tree typesize = TYPE_SIZE_UNIT (type))
+ nbytes = tree_to_uhwi (typesize);
+ else
+ return false;
+
+ /* Handle MEM_REF = SSA_NAME types of assignments. */
+ return count_nonzero_bytes (arg, offset, nbytes, lenrange, nulterm,
+ allnul, allnonnul, snlim);
+ }
+
+ if (TREE_CODE (exp) == VAR_DECL && TREE_READONLY (exp))
+ {
+ exp = DECL_INITIAL (exp);
+ if (!exp)
+ return false;
}
- if (TREE_CODE (rhs) == VAR_DECL
- && TREE_READONLY (rhs))
- rhs = DECL_INITIAL (rhs);
+ const char *prep = NULL;
+ if (TREE_CODE (exp) == STRING_CST)
+ {
+ unsigned nchars = TREE_STRING_LENGTH (exp);
+ if (nchars < offset)
+ return false;
+
+ if (!nbytes)
+ /* If NBYTES hasn't been determined earlier from MEM_REF,
+ set it here. It includes all internal nuls, including
+ the terminating one if the string has one. */
+ nbytes = nchars - offset;
+
+ prep = TREE_STRING_POINTER (exp) + offset;
+ }
- if (rhs && TREE_CODE (rhs) == STRING_CST)
+ unsigned char buf[256];
+ if (!prep)
{
- HOST_WIDE_INT len = strlen (TREE_STRING_POINTER (rhs));
- *full_string_p = len < TREE_STRING_LENGTH (rhs);
- return len;
+ /* If the pointer to representation hasn't been set above
+ for STRING_CST point it at the buffer. */
+ prep = reinterpret_cast <char *>(buf);
+ /* Try to extract the representation of the constant object
+ or expression starting from the offset. */
+ nbytes = native_encode_expr (exp, buf, sizeof buf, offset);
+ if (!nbytes)
+ return false;
+ }
+
+ /* Compute the number of leading nonzero bytes in the representation
+ and update the minimum and maximum. */
+ unsigned n = strnlen (prep, nbytes);
+
+ if (n < lenrange[0])
+ lenrange[0] = n;
+ if (lenrange[1] < n)
+ lenrange[1] = n;
+
+ /* Set the size of the representation. */
+ if (lenrange[2] < nbytes)
+ lenrange[2] = nbytes;
+
+ /* Clear NULTERM if none of the bytes is zero. */
+ if (n == nbytes)
+ *nulterm = false;
+
+ if (n)
+ {
+ /* When the initial number of non-zero bytes N is non-zero, reset
+ *ALLNUL; if N is less than that the size of the representation
+ also clear *ALLNONNUL. */
+ *allnul = false;
+ if (n < nbytes)
+ *allnonnul = false;
+ }
+ else if (*allnul || *allnonnul)
+ {
+ *allnonnul = false;
+
+ if (*allnul)
+ {
+ /* When either ALLNUL is set and N is zero, also determine
+ whether all subsequent bytes after the first one (which
+ is nul) are zero or nonzero and clear ALLNUL if not. */
+ for (const char *p = prep; p != prep + nbytes; ++p)
+ if (*p)
+ {
+ *allnul = false;
+ break;
+ }
+ }
}
- return -1;
+ return true;
+}
+
+/* Same as above except with an implicit SSA_NAME limit. */
+
+static bool
+count_nonzero_bytes (tree exp, unsigned lenrange[3], bool *nulterm,
+ bool *allnul, bool *allnonnul)
+{
+ /* Set to optimistic values so the caller doesn't have to worry about
+ initializing these and to what. On success, the function will clear
+ these if it determines their values are different but being recursive
+ it never sets either to true. On failure, their values are
+ unspecified. */
+ *nulterm = true;
+ *allnul = true;
+ *allnonnul = true;
+
+ ssa_name_limit_t snlim;
+ return count_nonzero_bytes (exp, 0, 0, lenrange, nulterm, allnul, allnonnul,
+ snlim);
}
-/* Handle a single or multiple character store either by single
- character assignment or by multi-character assignment from
- MEM_REF. */
+/* Handle a single or multibyte store other than by a built-in function,
+ either via a single character assignment or by multi-byte assignment
+ either via MEM_REF or via a type other than char (such as in
+ '*(int*)a = 12345'). Return true when handled. */
static bool
-handle_char_store (gimple_stmt_iterator *gsi)
+handle_store (gimple_stmt_iterator *gsi)
{
int idx = -1;
strinfo *si = NULL;
gimple *stmt = gsi_stmt (*gsi);
tree ssaname = NULL_TREE, lhs = gimple_assign_lhs (stmt);
tree rhs = gimple_assign_rhs1 (stmt);
+
+ /* The offset of the first byte in LHS modified by the the store. */
unsigned HOST_WIDE_INT offset = 0;
if (TREE_CODE (lhs) == MEM_REF
@@ -3428,23 +3654,80 @@ handle_char_store (gimple_stmt_iterator *gsi)
si = get_strinfo (idx);
}
+ /* Minimum and maximum leading non-zero bytes and the size of the store. */
+ unsigned lenrange[] = { UINT_MAX, 0, 0 };
+
+ /* Set to the minimum length of the string being assigned if known. */
+ unsigned HOST_WIDE_INT rhs_minlen;
+
/* STORING_NONZERO_P is true iff not all stored characters are zero.
+ STORING_ALL_NONZERO_P is true if all stored characters are zero.
STORING_ALL_ZEROS_P is true iff all stored characters are zero.
Both are false when it's impossible to determine which is true. */
bool storing_nonzero_p;
- bool storing_all_zeros_p = initializer_zerop (rhs, &storing_nonzero_p);
- if (!storing_nonzero_p)
- storing_nonzero_p = tree_expr_nonzero_p (rhs);
- bool full_string_p = storing_all_zeros_p;
+ bool storing_all_nonzero_p;
+ bool storing_all_zeros_p;
+ /* FULL_STRING_P is set when the stored sequence of characters form
+ a nul-terminated string. */
+ bool full_string_p;
- /* Set to the length of the string being assigned if known. */
- HOST_WIDE_INT rhslen;
+ const bool ranges_valid
+ = count_nonzero_bytes (rhs, lenrange, &full_string_p,
+ &storing_all_zeros_p, &storing_all_nonzero_p);
+ if (ranges_valid)
+ {
+ rhs_minlen = lenrange[0];
+ storing_nonzero_p = lenrange[1] > 0;
+
+ if (tree dstsize = compute_objsize (lhs, 1))
+ if (compare_tree_int (dstsize, lenrange[2]) < 0)
+ {
+ location_t loc = gimple_nonartificial_location (stmt);
+ warning_n (loc, OPT_Wstringop_overflow_,
+ lenrange[2],
+ "%Gwriting %u byte into a region of size %E",
+ "%Gwriting %u bytes into a region of size %E",
+ stmt, lenrange[2], dstsize);
+ }
+ }
+ else
+ {
+ rhs_minlen = HOST_WIDE_INT_M1U;
+ full_string_p = false;
+ storing_nonzero_p = false;
+ storing_all_zeros_p = false;
+ storing_all_nonzero_p = false;
+ }
if (si != NULL)
{
- int cmp = compare_nonzero_chars (si, offset);
- gcc_assert (offset == 0 || cmp >= 0);
- if (storing_all_zeros_p && cmp == 0 && si->full_string_p)
+ /* The corresponding element is set to 1 if the first and last
+ element, respectively, of the sequence of characters being
+ written over the string described by SI ends before
+ the terminating nul (if it has one), to zero if the nul is
+ being overwritten but not beyond, or negative otherwise. */
+ int store_before_nul[2];
+ if (ranges_valid)
+ {
+ /* The offset of the last stored byte. */
+ unsigned HOST_WIDE_INT endoff = offset + lenrange[2] - 1;
+ store_before_nul[0] = compare_nonzero_chars (si, offset);
+ if (endoff == offset)
+ store_before_nul[1] = store_before_nul[0];
+ else
+ store_before_nul[1] = compare_nonzero_chars (si, endoff);
+ }
+ else
+ {
+ store_before_nul[0] = compare_nonzero_chars (si, offset);
+ store_before_nul[1] = store_before_nul[0];
+ gcc_assert (offset == 0 || store_before_nul[0] >= 0);
+ }
+
+ if (storing_all_zeros_p
+ && store_before_nul[0] == 0
+ && store_before_nul[1] == 0
+ && si->full_string_p)
{
/* When overwriting a '\0' with a '\0', the store can be removed
if we know it has been stored in the current function. */
@@ -3463,16 +3746,21 @@ handle_char_store (gimple_stmt_iterator *gsi)
}
}
- if (cmp > 0
+ if (store_before_nul[1] > 0
&& storing_nonzero_p
+ && lenrange[0] == lenrange[1]
+ && lenrange[0] == lenrange[2]
&& TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE)
{
- /* Handle a single non-nul character store.
+ /* Handle a store of one or more non-nul characters that ends
+ before the terminating nul of the destination and so does
+ not affect its length
If si->nonzero_chars > OFFSET, we aren't overwriting '\0',
- and if we aren't storing '\0', we know that the length of the
- string and any other zero terminated string in memory remains
- the same. In that case we move to the next gimple statement and
- return to signal the caller that it shouldn't invalidate anything.
+ and if we aren't storing '\0', we know that the length of
+ the string and any other zero terminated string in memory
+ remains the same. In that case we move to the next gimple
+ statement and return to signal the caller that it shouldn't
+ invalidate anything.
This is benefical for cases like:
@@ -3493,7 +3781,7 @@ handle_char_store (gimple_stmt_iterator *gsi)
if (storing_all_zeros_p
|| storing_nonzero_p
- || (offset != 0 && cmp > 0))
+ || (offset != 0 && store_before_nul[1] > 0))
{
/* When STORING_NONZERO_P, we know that the string will start
with at least OFFSET + 1 nonzero characters. If storing
@@ -3506,22 +3794,15 @@ handle_char_store (gimple_stmt_iterator *gsi)
OFFSET characters long.
Otherwise, we're storing an unknown value at offset OFFSET,
- so need to clip the nonzero_chars to OFFSET. */
- bool full_string_p = storing_all_zeros_p;
- HOST_WIDE_INT len = 1;
- if (storing_nonzero_p)
- {
- /* Try to get the minimum length of the string (or
- individual character) being stored. If it fails,
- STORING_NONZERO_P guarantees it's at least 1. */
- len = get_min_string_length (rhs, &full_string_p);
- if (len < 0)
- len = 1;
- }
-
+ so need to clip the nonzero_chars to OFFSET.
+ Use the minimum length of the string (or individual character)
+ being stored if it's known. Otherwise, STORING_NONZERO_P
+ guarantees it's at least 1. */
+ HOST_WIDE_INT len
+ = storing_nonzero_p && ranges_valid ? lenrange[0] : 1;
location_t loc = gimple_location (stmt);
tree oldlen = si->nonzero_chars;
- if (cmp == 0 && si->full_string_p)
+ if (store_before_nul[1] == 0 && si->full_string_p)
/* We're overwriting the nul terminator with a nonzero or
unknown character. If the previous stmt was a memcpy,
its length may be decreased. */
@@ -3534,7 +3815,14 @@ handle_char_store (gimple_stmt_iterator *gsi)
}
else
si->nonzero_chars = build_int_cst (size_type_node, offset);
- si->full_string_p = full_string_p;
+
+ /* Set FULL_STRING_P only if the length of the strings being
+ written is the same, and clear it if the strings have
+ different lengths. In the latter case the length stored
+ in si->NONZERO_CHARS becomes the lower bound.
+ FIXME: Handle the upper bound of the length if possible. */
+ si->full_string_p = full_string_p && lenrange[0] == lenrange[1];
+
if (storing_all_zeros_p
&& ssaname
&& !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname))
@@ -3564,11 +3852,23 @@ handle_char_store (gimple_stmt_iterator *gsi)
if (idx != 0)
{
tree ptr = (ssaname ? ssaname : build_fold_addr_expr (lhs));
- HOST_WIDE_INT slen = (storing_all_zeros_p
- ? 0
- : (storing_nonzero_p
- ? get_min_string_length (rhs, &full_string_p)
- : -1));
+
+ HOST_WIDE_INT slen;
+ if (storing_all_zeros_p)
+ slen = 0;
+ else if (storing_nonzero_p && ranges_valid)
+ {
+ /* FIXME: Handle the upper bound of the length when
+ LENRANGE[0] != LENRANGE[1]. */
+ slen = lenrange[0];
+ if (lenrange[0] != lenrange[1])
+ /* Set the minimum length but ignore the maximum
+ for now. */
+ full_string_p = false;
+ }
+ else
+ slen = -1;
+
tree len = (slen <= 0
? size_zero_node
: build_int_cst (size_type_node, slen));
@@ -3583,18 +3883,18 @@ handle_char_store (gimple_stmt_iterator *gsi)
}
}
else if (idx == 0
- && (rhslen = get_min_string_length (rhs, &full_string_p)) >= 0
+ && rhs_minlen < HOST_WIDE_INT_M1U
&& ssaname == NULL_TREE
&& TREE_CODE (TREE_TYPE (lhs)) == ARRAY_TYPE)
{
HOST_WIDE_INT a = int_size_in_bytes (TREE_TYPE (lhs));
- if (a > 0 && (unsigned HOST_WIDE_INT) a > (unsigned HOST_WIDE_INT) rhslen)
+ if (a > 0 && (unsigned HOST_WIDE_INT) a > rhs_minlen)
{
int idx = new_addr_stridx (lhs);
if (idx != 0)
{
si = new_strinfo (build_fold_addr_expr (lhs), idx,
- build_int_cst (size_type_node, rhslen),
+ build_int_cst (size_type_node, rhs_minlen),
full_string_p);
set_strinfo (idx, si);
si->dont_invalidate = true;
@@ -3707,6 +4007,16 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple *stmt)
}
}
+/* Return true if TYPE corresponds to a narrow character type. */
+
+static bool
+is_char_type (tree type)
+{
+ return (TREE_CODE (type) == INTEGER_TYPE
+ && TYPE_MODE (type) == TYPE_MODE (char_type_node)
+ && TYPE_PRECISION (type) == TYPE_PRECISION (char_type_node));
+}
+
/* Attempt to check for validity of the performed access a single statement
at *GSI using string length knowledge, and to optimize it.
If the given basic block needs clean-up of EH, CLEANUP_EH is set to
@@ -3907,18 +4217,32 @@ strlen_check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh)
}
}
else if (TREE_CODE (lhs) != SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
- {
- tree type = TREE_TYPE (lhs);
- if (TREE_CODE (type) == ARRAY_TYPE)
- type = TREE_TYPE (type);
- if (TREE_CODE (type) == INTEGER_TYPE
- && TYPE_MODE (type) == TYPE_MODE (char_type_node)
- && TYPE_PRECISION (type) == TYPE_PRECISION (char_type_node))
- {
- if (! handle_char_store (gsi))
- return false;
- }
- }
+ {
+ tree type = TREE_TYPE (lhs);
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ type = TREE_TYPE (type);
+
+ bool is_char_store = is_char_type (type);
+ if (!is_char_store && TREE_CODE (lhs) == MEM_REF)
+ {
+ /* To consider stores into char objects via integer types
+ other than char but not those to non-character objects,
+ determine the type of the destination rather than just
+ the type of the access. */
+ tree ref = TREE_OPERAND (lhs, 0);
+ type = TREE_TYPE (ref);
+ if (TREE_CODE (type) == POINTER_TYPE)
+ type = TREE_TYPE (type);
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ type = TREE_TYPE (type);
+ if (is_char_type (type))
+ is_char_store = true;
+ }
+
+ /* Handle a single or multibyte assignment. */
+ if (is_char_store && !handle_store (gsi))
+ return false;
+ }
}
else if (gcond *cond = dyn_cast<gcond *> (stmt))
{
diff --git a/gcc/tree-ssa-strlen.h b/gcc/tree-ssa-strlen.h
index 0b68465..395c74e 100644
--- a/gcc/tree-ssa-strlen.h
+++ b/gcc/tree-ssa-strlen.h
@@ -23,6 +23,6 @@
extern bool is_strlen_related_p (tree, tree);
extern bool maybe_diag_stxncpy_trunc (gimple_stmt_iterator, tree, tree);
-extern tree set_strlen_range (tree, wide_int, tree = NULL_TREE);
+extern tree set_strlen_range (tree, wide_int, wide_int, tree = NULL_TREE);
#endif // GCC_TREE_SSA_STRLEN_H
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index f8962d6..75c6fae 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -2071,36 +2071,73 @@ condense_visit (constraint_graph_t graph, class scc_info *si, unsigned int n)
/* See if any components have been identified. */
if (si->dfs[n] == my_dfs)
{
- while (si->scc_stack.length () != 0
- && si->dfs[si->scc_stack.last ()] >= my_dfs)
+ if (si->scc_stack.length () != 0
+ && si->dfs[si->scc_stack.last ()] >= my_dfs)
{
- unsigned int w = si->scc_stack.pop ();
- si->node_mapping[w] = n;
-
- if (!bitmap_bit_p (graph->direct_nodes, w))
- bitmap_clear_bit (graph->direct_nodes, n);
-
- /* Unify our nodes. */
- if (graph->preds[w])
- {
- if (!graph->preds[n])
- graph->preds[n] = BITMAP_ALLOC (&predbitmap_obstack);
- bitmap_ior_into (graph->preds[n], graph->preds[w]);
- }
- if (graph->implicit_preds[w])
+ /* Find the first node of the SCC and do non-bitmap work. */
+ bool direct_p = true;
+ unsigned first = si->scc_stack.length ();
+ do
{
- if (!graph->implicit_preds[n])
- graph->implicit_preds[n] = BITMAP_ALLOC (&predbitmap_obstack);
- bitmap_ior_into (graph->implicit_preds[n],
- graph->implicit_preds[w]);
+ --first;
+ unsigned int w = si->scc_stack[first];
+ si->node_mapping[w] = n;
+ if (!bitmap_bit_p (graph->direct_nodes, w))
+ direct_p = false;
}
- if (graph->points_to[w])
+ while (first > 0
+ && si->dfs[si->scc_stack[first - 1]] >= my_dfs);
+ if (!direct_p)
+ bitmap_clear_bit (graph->direct_nodes, n);
+
+ /* Want to reduce to node n, push that first. */
+ si->scc_stack.reserve (1);
+ si->scc_stack.quick_push (si->scc_stack[first]);
+ si->scc_stack[first] = n;
+
+ unsigned scc_size = si->scc_stack.length () - first;
+ unsigned split = scc_size / 2;
+ unsigned carry = scc_size - split * 2;
+ while (split > 0)
{
- if (!graph->points_to[n])
- graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack);
- bitmap_ior_into (graph->points_to[n],
- graph->points_to[w]);
+ for (unsigned i = 0; i < split; ++i)
+ {
+ unsigned a = si->scc_stack[first + i];
+ unsigned b = si->scc_stack[first + split + carry + i];
+
+ /* Unify our nodes. */
+ if (graph->preds[b])
+ {
+ if (!graph->preds[a])
+ std::swap (graph->preds[a], graph->preds[b]);
+ else
+ bitmap_ior_into_and_free (graph->preds[a],
+ &graph->preds[b]);
+ }
+ if (graph->implicit_preds[b])
+ {
+ if (!graph->implicit_preds[a])
+ std::swap (graph->implicit_preds[a],
+ graph->implicit_preds[b]);
+ else
+ bitmap_ior_into_and_free (graph->implicit_preds[a],
+ &graph->implicit_preds[b]);
+ }
+ if (graph->points_to[b])
+ {
+ if (!graph->points_to[a])
+ std::swap (graph->points_to[a], graph->points_to[b]);
+ else
+ bitmap_ior_into_and_free (graph->points_to[a],
+ &graph->points_to[b]);
+ }
+ }
+ unsigned remain = split + carry;
+ split = remain / 2;
+ carry = remain - split * 2;
}
+ /* Actually pop the SCC. */
+ si->scc_stack.truncate (first);
}
bitmap_set_bit (si->deleted, n);
}
@@ -3252,9 +3289,29 @@ get_constraint_for_component_ref (tree t, vec<ce_s> *results,
return;
}
- /* Pretend to take the address of the base, we'll take care of
- adding the required subset of sub-fields below. */
- get_constraint_for_1 (t, results, true, lhs_p);
+ /* Avoid creating pointer-offset constraints, so handle MEM_REF
+ offsets directly. Pretend to take the address of the base,
+ we'll take care of adding the required subset of sub-fields below. */
+ if (TREE_CODE (t) == MEM_REF
+ && !integer_zerop (TREE_OPERAND (t, 0)))
+ {
+ poly_offset_int off = mem_ref_offset (t);
+ off <<= LOG2_BITS_PER_UNIT;
+ off += bitpos;
+ poly_int64 off_hwi;
+ if (off.to_shwi (&off_hwi))
+ bitpos = off_hwi;
+ else
+ {
+ bitpos = 0;
+ bitmaxsize = -1;
+ }
+ get_constraint_for_1 (TREE_OPERAND (t, 0), results, false, lhs_p);
+ do_deref (results);
+ }
+ else
+ get_constraint_for_1 (t, results, true, lhs_p);
+
/* Strip off nothing_id. */
if (results->length () == 2)
{
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 39ea22f..1776a6d 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -183,7 +183,7 @@ record_temporary_equivalences_from_phis (edge e,
else if (TREE_CODE (src) == INTEGER_CST)
new_vr->set (src);
else
- new_vr->set_varying ();
+ new_vr->set_varying (TREE_TYPE (src));
/* This is a temporary range for DST, so push it. */
evrp_range_analyzer->push_value_range (dst, new_vr);
@@ -331,6 +331,7 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
{
tree fndecl = gimple_call_fndecl (stmt);
if (fndecl
+ && fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
&& (DECL_FUNCTION_CODE (fndecl) == BUILT_IN_OBJECT_SIZE
|| DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P))
continue;
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 8b80bce..3911db9 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -440,14 +440,16 @@ get_range_info (const_tree name, value_range_base &vr)
wide_int wmin, wmax;
enum value_range_kind kind = get_range_info (name, &wmin, &wmax);
- if (kind == VR_VARYING || kind == VR_UNDEFINED)
- min = max = NULL;
+ if (kind == VR_VARYING)
+ vr.set_varying (TREE_TYPE (name));
+ else if (kind == VR_UNDEFINED)
+ vr.set_undefined ();
else
{
min = wide_int_to_tree (TREE_TYPE (name), wmin);
max = wide_int_to_tree (TREE_TYPE (name), wmax);
+ vr.set (kind, min, max);
}
- vr.set (kind, min, max);
return kind;
}
diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c
index dc8bbf8..dcd511e 100644
--- a/gcc/tree-streamer-in.c
+++ b/gcc/tree-streamer-in.c
@@ -324,8 +324,7 @@ unpack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
static void
unpack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
{
- DECL_BUILT_IN_CLASS (expr) = bp_unpack_enum (bp, built_in_class,
- BUILT_IN_LAST);
+ built_in_class cl = bp_unpack_enum (bp, built_in_class, BUILT_IN_LAST);
DECL_STATIC_CONSTRUCTOR (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_STATIC_DESTRUCTOR (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_UNINLINABLE (expr) = (unsigned) bp_unpack_value (bp, 1);
@@ -333,7 +332,8 @@ unpack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
DECL_IS_NOVOPS (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_IS_RETURNS_TWICE (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_IS_MALLOC (expr) = (unsigned) bp_unpack_value (bp, 1);
- DECL_IS_OPERATOR_NEW (expr) = (unsigned) bp_unpack_value (bp, 1);
+ DECL_SET_IS_OPERATOR_NEW (expr, (unsigned) bp_unpack_value (bp, 1));
+ DECL_SET_IS_OPERATOR_DELETE (expr, (unsigned) bp_unpack_value (bp, 1));
DECL_DECLARED_INLINE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_STATIC_CHAIN (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_NO_INLINE_WARNING_P (expr) = (unsigned) bp_unpack_value (bp, 1);
@@ -343,22 +343,22 @@ unpack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
DECL_DISREGARD_INLINE_LIMITS (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_PURE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_LOOPING_CONST_OR_PURE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
- if (DECL_BUILT_IN_CLASS (expr) != NOT_BUILT_IN)
+ unsigned int fcode = 0;
+ if (cl != NOT_BUILT_IN)
{
- DECL_FUNCTION_CODE (expr) = (enum built_in_function) bp_unpack_value (bp,
- 12);
- if (DECL_BUILT_IN_CLASS (expr) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (expr) >= END_BUILTINS)
+ fcode = bp_unpack_value (bp, 32);
+ if (cl == BUILT_IN_NORMAL && fcode >= END_BUILTINS)
fatal_error (input_location,
"machine independent builtin code out of range");
- else if (DECL_BUILT_IN_CLASS (expr) == BUILT_IN_MD)
+ else if (cl == BUILT_IN_MD)
{
- tree result = targetm.builtin_decl (DECL_FUNCTION_CODE (expr), true);
+ tree result = targetm.builtin_decl (fcode, true);
if (!result || result == error_mark_node)
fatal_error (input_location,
"target specific builtin not available");
}
}
+ set_decl_built_in_function (expr, cl, fcode);
}
diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c
index a83057e..aadc56c 100644
--- a/gcc/tree-streamer-out.c
+++ b/gcc/tree-streamer-out.c
@@ -295,7 +295,8 @@ pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
bp_pack_value (bp, DECL_IS_NOVOPS (expr), 1);
bp_pack_value (bp, DECL_IS_RETURNS_TWICE (expr), 1);
bp_pack_value (bp, DECL_IS_MALLOC (expr), 1);
- bp_pack_value (bp, DECL_IS_OPERATOR_NEW (expr), 1);
+ bp_pack_value (bp, DECL_IS_OPERATOR_NEW_P (expr), 1);
+ bp_pack_value (bp, DECL_IS_OPERATOR_DELETE_P (expr), 1);
bp_pack_value (bp, DECL_DECLARED_INLINE_P (expr), 1);
bp_pack_value (bp, DECL_STATIC_CHAIN (expr), 1);
bp_pack_value (bp, DECL_NO_INLINE_WARNING_P (expr), 1);
@@ -305,7 +306,7 @@ pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
bp_pack_value (bp, DECL_PURE_P (expr), 1);
bp_pack_value (bp, DECL_LOOPING_CONST_OR_PURE_P (expr), 1);
if (DECL_BUILT_IN_CLASS (expr) != NOT_BUILT_IN)
- bp_pack_value (bp, DECL_FUNCTION_CODE (expr), 12);
+ bp_pack_value (bp, DECL_UNCHECKED_FUNCTION_CODE (expr), 32);
}
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index a99cd11..a4b563e 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -491,6 +491,35 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
&& !stmt_can_throw_external (cfun, stmt))
return;
+ /* If the function returns a value, then at present, the tail call
+ must return the same type of value. There is conceptually a copy
+ between the object returned by the tail call candidate and the
+ object returned by CFUN itself.
+
+ This means that if we have:
+
+ lhs = f (&<retval>); // f reads from <retval>
+ // (lhs is usually also <retval>)
+
+ there is a copy between the temporary object returned by f and lhs,
+ meaning that any use of <retval> in f occurs before the assignment
+ to lhs begins. Thus the <retval> that is live on entry to the call
+ to f is really an independent local variable V that happens to be
+ stored in the RESULT_DECL rather than a local VAR_DECL.
+
+ Turning this into a tail call would remove the copy and make the
+ lifetimes of the return value and V overlap. The same applies to
+ tail recursion, since if f can read from <retval>, we have to assume
+ that CFUN might already have written to <retval> before the call.
+
+ The problem doesn't apply when <retval> is passed by value, but that
+ isn't a case we handle anyway. */
+ tree result_decl = DECL_RESULT (cfun->decl);
+ if (result_decl
+ && may_be_aliased (result_decl)
+ && ref_maybe_used_by_stmt_p (call, result_decl))
+ return;
+
/* We found the call, check whether it is suitable. */
tail_recursion = false;
func = gimple_call_fndecl (call);
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index 8430c98..ccb2e1e 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -1297,7 +1297,7 @@ vect_recog_pow_pattern (stmt_vec_info stmt_vinfo, tree *type_out)
{
if (flag_unsafe_math_optimizations
&& TREE_CODE (base) == REAL_CST
- && !gimple_call_internal_p (last_stmt))
+ && gimple_call_builtin_p (last_stmt, BUILT_IN_NORMAL))
{
combined_fn log_cfn;
built_in_function exp_bfn;
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 0220b18..52f2a06 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -1296,6 +1296,9 @@ vect_build_slp_tree_2 (vec_info *vinfo,
&& nops == 2
&& oprnds_info[1]->first_dt == vect_internal_def
&& is_gimple_assign (stmt_info->stmt)
+ /* Swapping operands for reductions breaks assumptions later on. */
+ && STMT_VINFO_DEF_TYPE (stmt_info) != vect_reduction_def
+ && STMT_VINFO_DEF_TYPE (stmt_info) != vect_double_reduction_def
/* Do so only if the number of not successful permutes was nor more
than a cut-ff as re-trying the recursive match on
possibly each level of the tree would expose exponential
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 601a6f5..dd9d45a 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -3376,7 +3376,7 @@ vectorizable_call (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
if (cfn != CFN_LAST)
fndecl = targetm.vectorize.builtin_vectorized_function
(cfn, vectype_out, vectype_in);
- else if (callee)
+ else if (callee && fndecl_built_in_p (callee, BUILT_IN_MD))
fndecl = targetm.vectorize.builtin_md_vectorized_function
(callee, vectype_out, vectype_in);
}
@@ -9510,8 +9510,7 @@ vectorizable_load (stmt_vec_info stmt_info, gimple_stmt_iterator *gsi,
new_stmt = gimple_build_assign (vec_dest, data_ref);
new_temp = make_ssa_name (vec_dest, new_stmt);
gimple_assign_set_lhs (new_stmt, new_temp);
- gimple_set_vdef (new_stmt, gimple_vdef (stmt_info->stmt));
- gimple_set_vuse (new_stmt, gimple_vuse (stmt_info->stmt));
+ gimple_move_vops (new_stmt, stmt_info->stmt);
vect_finish_stmt_generation (stmt_info, new_stmt, gsi);
msq = new_temp;
diff --git a/gcc/tree-vector-builder.c b/gcc/tree-vector-builder.c
index f31dc13..d02fb95 100644
--- a/gcc/tree-vector-builder.c
+++ b/gcc/tree-vector-builder.c
@@ -24,103 +24,6 @@ along with GCC; see the file COPYING3. If not see
#include "fold-const.h"
#include "tree-vector-builder.h"
-/* Try to start building a new vector of type TYPE that holds the result of
- a unary operation on VECTOR_CST T. ALLOW_STEPPED_P is true if the
- operation can handle stepped encodings directly, without having to
- expand the full sequence.
-
- Return true if the operation is possible, which it always is when
- ALLOW_STEPPED_P is true. Leave the builder unchanged otherwise. */
-
-bool
-tree_vector_builder::new_unary_operation (tree type, tree t,
- bool allow_stepped_p)
-{
- poly_uint64 full_nelts = TYPE_VECTOR_SUBPARTS (type);
- gcc_assert (known_eq (full_nelts, TYPE_VECTOR_SUBPARTS (TREE_TYPE (t))));
- unsigned int npatterns = VECTOR_CST_NPATTERNS (t);
- unsigned int nelts_per_pattern = VECTOR_CST_NELTS_PER_PATTERN (t);
- if (!allow_stepped_p && nelts_per_pattern > 2)
- {
- if (!full_nelts.is_constant ())
- return false;
- npatterns = full_nelts.to_constant ();
- nelts_per_pattern = 1;
- }
- new_vector (type, npatterns, nelts_per_pattern);
- return true;
-}
-
-/* Try to start building a new vector of type TYPE that holds the result of
- a binary operation on VECTOR_CSTs T1 and T2. ALLOW_STEPPED_P is true if
- the operation can handle stepped encodings directly, without having to
- expand the full sequence.
-
- Return true if the operation is possible. Leave the builder unchanged
- otherwise. */
-
-bool
-tree_vector_builder::new_binary_operation (tree type, tree t1, tree t2,
- bool allow_stepped_p)
-{
- poly_uint64 full_nelts = TYPE_VECTOR_SUBPARTS (type);
- gcc_assert (known_eq (full_nelts, TYPE_VECTOR_SUBPARTS (TREE_TYPE (t1)))
- && known_eq (full_nelts, TYPE_VECTOR_SUBPARTS (TREE_TYPE (t2))));
- /* Conceptually we split the patterns in T1 and T2 until we have
- an equal number for both. Each split pattern requires the same
- number of elements per pattern as the original. E.g. splitting:
-
- { 1, 2, 3, ... }
-
- into two gives:
-
- { 1, 3, 5, ... }
- { 2, 4, 6, ... }
-
- while splitting:
-
- { 1, 0, ... }
-
- into two gives:
-
- { 1, 0, ... }
- { 0, 0, ... }. */
- unsigned int npatterns = least_common_multiple (VECTOR_CST_NPATTERNS (t1),
- VECTOR_CST_NPATTERNS (t2));
- unsigned int nelts_per_pattern = MAX (VECTOR_CST_NELTS_PER_PATTERN (t1),
- VECTOR_CST_NELTS_PER_PATTERN (t2));
- if (!allow_stepped_p && nelts_per_pattern > 2)
- {
- if (!full_nelts.is_constant ())
- return false;
- npatterns = full_nelts.to_constant ();
- nelts_per_pattern = 1;
- }
- new_vector (type, npatterns, nelts_per_pattern);
- return true;
-}
-
-/* Return the number of elements that the caller needs to operate on in
- order to handle a binary operation on VECTOR_CSTs T1 and T2. This static
- function is used instead of new_binary_operation if the result of the
- operation is not a VECTOR_CST. */
-
-unsigned int
-tree_vector_builder::binary_encoded_nelts (tree t1, tree t2)
-{
- poly_uint64 nelts = TYPE_VECTOR_SUBPARTS (TREE_TYPE (t1));
- gcc_assert (known_eq (nelts, TYPE_VECTOR_SUBPARTS (TREE_TYPE (t2))));
- /* See new_binary_operation for details. */
- unsigned int npatterns = least_common_multiple (VECTOR_CST_NPATTERNS (t1),
- VECTOR_CST_NPATTERNS (t2));
- unsigned int nelts_per_pattern = MAX (VECTOR_CST_NELTS_PER_PATTERN (t1),
- VECTOR_CST_NELTS_PER_PATTERN (t2));
- unsigned HOST_WIDE_INT const_nelts;
- if (nelts.is_constant (&const_nelts))
- return MIN (npatterns * nelts_per_pattern, const_nelts);
- return npatterns * nelts_per_pattern;
-}
-
/* Return a vector element with the value BASE + FACTOR * STEP. */
tree
diff --git a/gcc/tree-vector-builder.h b/gcc/tree-vector-builder.h
index 0e36cd1..6a4cf6f 100644
--- a/gcc/tree-vector-builder.h
+++ b/gcc/tree-vector-builder.h
@@ -24,10 +24,11 @@ along with GCC; see the file COPYING3. If not see
/* This class is used to build VECTOR_CSTs from a sequence of elements.
See vector_builder for more details. */
-class tree_vector_builder : public vector_builder<tree, tree_vector_builder>
+class tree_vector_builder : public vector_builder<tree, tree,
+ tree_vector_builder>
{
- typedef vector_builder<tree, tree_vector_builder> parent;
- friend class vector_builder<tree, tree_vector_builder>;
+ typedef vector_builder<tree, tree, tree_vector_builder> parent;
+ friend class vector_builder<tree, tree, tree_vector_builder>;
public:
tree_vector_builder () : m_type (0) {}
@@ -37,10 +38,6 @@ public:
tree type () const { return m_type; }
void new_vector (tree, unsigned int, unsigned int);
- bool new_unary_operation (tree, tree, bool);
- bool new_binary_operation (tree, tree, tree, bool);
-
- static unsigned int binary_encoded_nelts (tree, tree);
private:
bool equal_p (const_tree, const_tree) const;
@@ -51,6 +48,15 @@ private:
bool can_elide_p (const_tree) const;
void note_representative (tree *, tree);
+ static poly_uint64 shape_nelts (const_tree t)
+ { return TYPE_VECTOR_SUBPARTS (t); }
+ static poly_uint64 nelts_of (const_tree t)
+ { return VECTOR_CST_NELTS (t); }
+ static unsigned int npatterns_of (const_tree t)
+ { return VECTOR_CST_NPATTERNS (t); }
+ static unsigned int nelts_per_pattern_of (const_tree t)
+ { return VECTOR_CST_NELTS_PER_PATTERN (t); }
+
tree m_type;
};
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 173e6b5..dc18152 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -289,10 +289,7 @@ adjust_simduid_builtins (hash_table<simduid_to_vf> *htab)
: BUILT_IN_GOMP_ORDERED_END);
gimple *g
= gimple_build_call (builtin_decl_explicit (bcode), 0);
- tree vdef = gimple_vdef (stmt);
- gimple_set_vdef (g, vdef);
- SSA_NAME_DEF_STMT (vdef) = g;
- gimple_set_vuse (g, gimple_vuse (stmt));
+ gimple_move_vops (g, stmt);
gsi_replace (&i, g, true);
continue;
}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index b79dfb2..8067f85 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -69,23 +69,20 @@ along with GCC; see the file COPYING3. If not see
#include "builtins.h"
#include "wide-int-range.h"
+static bool
+ranges_from_anti_range (const value_range_base *ar,
+ value_range_base *vr0, value_range_base *vr1,
+ bool handle_pointers = false);
+
/* Set of SSA names found live during the RPO traversal of the function
for still active basic-blocks. */
static sbitmap *live;
void
-value_range_base::set (enum value_range_kind kind, tree min, tree max)
-{
- m_kind = kind;
- m_min = min;
- m_max = max;
- if (flag_checking)
- check ();
-}
-
-void
value_range::set_equiv (bitmap equiv)
{
+ if (undefined_p () || varying_p ())
+ equiv = NULL;
/* Since updating the equivalence set involves deep copying the
bitmaps, only do it if absolutely necessary.
@@ -189,9 +186,11 @@ value_range_base::check ()
break;
}
case VR_UNDEFINED:
- case VR_VARYING:
gcc_assert (!min () && !max ());
break;
+ case VR_VARYING:
+ gcc_assert (m_min && m_max);
+ break;
default:
gcc_unreachable ();
}
@@ -217,6 +216,10 @@ value_range::check ()
bool
value_range_base::equal_p (const value_range_base &other) const
{
+ /* Ignore types for undefined. All undefines are equal. */
+ if (undefined_p ())
+ return m_kind == other.m_kind;
+
return (m_kind == other.m_kind
&& vrp_operand_equal_p (m_min, other.m_min)
&& vrp_operand_equal_p (m_max, other.m_max));
@@ -261,7 +264,8 @@ value_range_base::constant_p () const
void
value_range_base::set_undefined ()
{
- set (VR_UNDEFINED, NULL, NULL);
+ m_kind = VR_UNDEFINED;
+ m_min = m_max = NULL;
}
void
@@ -271,15 +275,24 @@ value_range::set_undefined ()
}
void
-value_range_base::set_varying ()
+value_range_base::set_varying (tree type)
{
- set (VR_VARYING, NULL, NULL);
+ m_kind = VR_VARYING;
+ if (supports_type_p (type))
+ {
+ m_min = vrp_val_min (type, true);
+ m_max = vrp_val_max (type, true);
+ }
+ else
+ /* We can't do anything range-wise with these types. */
+ m_min = m_max = error_mark_node;
}
void
-value_range::set_varying ()
+value_range::set_varying (tree type)
{
- set (VR_VARYING, NULL, NULL, NULL);
+ value_range_base::set_varying (type);
+ equiv_clear ();
}
/* Return TRUE if it is possible that range contains VAL. */
@@ -324,6 +337,24 @@ value_range::equiv_add (const_tree var,
bool
value_range_base::singleton_p (tree *result) const
{
+ if (m_kind == VR_ANTI_RANGE)
+ {
+ if (nonzero_p ())
+ {
+ if (TYPE_PRECISION (type ()) == 1)
+ {
+ if (result)
+ *result = m_max;
+ return true;
+ }
+ return false;
+ }
+
+ value_range_base vr0, vr1;
+ return (ranges_from_anti_range (this, &vr0, &vr1, true)
+ && vr1.undefined_p ()
+ && vr0.singleton_p (result));
+ }
if (m_kind == VR_RANGE
&& vrp_operand_equal_p (min (), max ())
&& is_gimple_min_invariant (min ()))
@@ -338,9 +369,7 @@ value_range_base::singleton_p (tree *result) const
tree
value_range_base::type () const
{
- /* Types are only valid for VR_RANGE and VR_ANTI_RANGE, which are
- known to have non-zero min/max. */
- gcc_assert (min ());
+ gcc_assert (m_min || undefined_p ());
return TREE_TYPE (min ());
}
@@ -378,12 +407,21 @@ value_range_base::dump (FILE *file) const
fprintf (file, "]");
}
else if (varying_p ())
- fprintf (file, "VARYING");
+ {
+ print_generic_expr (file, type ());
+ fprintf (file, " VARYING");
+ }
else
gcc_unreachable ();
}
void
+value_range_base::dump () const
+{
+ dump (stderr);
+}
+
+void
value_range::dump (FILE *file) const
{
value_range_base::dump (file);
@@ -407,6 +445,12 @@ value_range::dump (FILE *file) const
}
void
+value_range::dump () const
+{
+ dump (stderr);
+}
+
+void
dump_value_range (FILE *file, const value_range *vr)
{
if (!vr)
@@ -499,23 +543,28 @@ static assert_locus **asserts_for;
/* Return the maximum value for TYPE. */
tree
-vrp_val_max (const_tree type)
+vrp_val_max (const_tree type, bool handle_pointers)
{
- if (!INTEGRAL_TYPE_P (type))
- return NULL_TREE;
-
- return TYPE_MAX_VALUE (type);
+ if (INTEGRAL_TYPE_P (type))
+ return TYPE_MAX_VALUE (type);
+ if (POINTER_TYPE_P (type) && handle_pointers)
+ {
+ wide_int max = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
+ return wide_int_to_tree (const_cast<tree> (type), max);
+ }
+ return NULL_TREE;
}
/* Return the minimum value for TYPE. */
tree
-vrp_val_min (const_tree type)
+vrp_val_min (const_tree type, bool handle_pointers)
{
- if (!INTEGRAL_TYPE_P (type))
- return NULL_TREE;
-
- return TYPE_MIN_VALUE (type);
+ if (INTEGRAL_TYPE_P (type))
+ return TYPE_MIN_VALUE (type);
+ if (POINTER_TYPE_P (type) && handle_pointers)
+ return build_zero_cst (const_cast<tree> (type));
+ return NULL_TREE;
}
/* Return whether VAL is equal to the maximum value of its type.
@@ -626,8 +675,7 @@ intersect_range_with_nonzero_bits (enum value_range_kind vr_type,
extract ranges from var + CST op limit. */
void
-value_range_base::set_and_canonicalize (enum value_range_kind kind,
- tree min, tree max)
+value_range_base::set (enum value_range_kind kind, tree min, tree max)
{
/* Use the canonical setters for VR_UNDEFINED and VR_VARYING. */
if (kind == VR_UNDEFINED)
@@ -637,7 +685,14 @@ value_range_base::set_and_canonicalize (enum value_range_kind kind,
}
else if (kind == VR_VARYING)
{
- set_varying ();
+ gcc_assert (TREE_TYPE (min) == TREE_TYPE (max));
+ tree typ = TREE_TYPE (min);
+ if (supports_type_p (typ))
+ {
+ gcc_assert (vrp_val_min (typ, true));
+ gcc_assert (vrp_val_max (typ, true));
+ }
+ set_varying (typ);
return;
}
@@ -645,7 +700,9 @@ value_range_base::set_and_canonicalize (enum value_range_kind kind,
if (TREE_CODE (min) != INTEGER_CST
|| TREE_CODE (max) != INTEGER_CST)
{
- set (kind, min, max);
+ m_kind = kind;
+ m_min = min;
+ m_max = max;
return;
}
@@ -660,7 +717,7 @@ value_range_base::set_and_canonicalize (enum value_range_kind kind,
for VR_ANTI_RANGE empty range, so drop to varying as well. */
if (TYPE_PRECISION (TREE_TYPE (min)) == 1)
{
- set_varying ();
+ set_varying (TREE_TYPE (min));
return;
}
@@ -674,19 +731,20 @@ value_range_base::set_and_canonicalize (enum value_range_kind kind,
to varying in this case. */
if (tree_int_cst_lt (max, min))
{
- set_varying ();
+ set_varying (TREE_TYPE (min));
return;
}
kind = kind == VR_RANGE ? VR_ANTI_RANGE : VR_RANGE;
}
+ tree type = TREE_TYPE (min);
+
/* Anti-ranges that can be represented as ranges should be so. */
if (kind == VR_ANTI_RANGE)
{
/* For -fstrict-enums we may receive out-of-range ranges so consider
values < -INF and values > INF as -INF/INF as well. */
- tree type = TREE_TYPE (min);
bool is_min = (INTEGRAL_TYPE_P (type)
&& tree_int_cst_compare (min, TYPE_MIN_VALUE (type)) <= 0);
bool is_max = (INTEGRAL_TYPE_P (type)
@@ -696,7 +754,7 @@ value_range_base::set_and_canonicalize (enum value_range_kind kind,
{
/* We cannot deal with empty ranges, drop to varying.
??? This could be VR_UNDEFINED instead. */
- set_varying ();
+ set_varying (type);
return;
}
else if (TYPE_PRECISION (TREE_TYPE (min)) == 1
@@ -729,22 +787,37 @@ value_range_base::set_and_canonicalize (enum value_range_kind kind,
}
}
+ /* Normalize [MIN, MAX] into VARYING and ~[MIN, MAX] into UNDEFINED.
+
+ Avoid using TYPE_{MIN,MAX}_VALUE because -fstrict-enums can
+ restrict those to a subset of what actually fits in the type.
+ Instead use the extremes of the type precision which will allow
+ compare_range_with_value() to check if a value is inside a range,
+ whereas if we used TYPE_*_VAL, said function would just punt
+ upon seeing a VARYING. */
+ unsigned prec = TYPE_PRECISION (type);
+ signop sign = TYPE_SIGN (type);
+ if (wi::eq_p (wi::to_wide (min), wi::min_value (prec, sign))
+ && wi::eq_p (wi::to_wide (max), wi::max_value (prec, sign)))
+ {
+ if (kind == VR_RANGE)
+ set_varying (type);
+ else if (kind == VR_ANTI_RANGE)
+ set_undefined ();
+ else
+ gcc_unreachable ();
+ return;
+ }
+
/* Do not drop [-INF(OVF), +INF(OVF)] to varying. (OVF) has to be sticky
to make sure VRP iteration terminates, otherwise we can get into
oscillations. */
- set (kind, min, max);
-}
-
-void
-value_range::set_and_canonicalize (enum value_range_kind kind,
- tree min, tree max, bitmap equiv)
-{
- value_range_base::set_and_canonicalize (kind, min, max);
- if (this->kind () == VR_RANGE || this->kind () == VR_ANTI_RANGE)
- set_equiv (equiv);
- else
- equiv_clear ();
+ m_kind = kind;
+ m_min = min;
+ m_max = max;
+ if (flag_checking)
+ check ();
}
void
@@ -909,22 +982,17 @@ operand_less_p (tree val, tree val2)
/* LT is folded faster than GE and others. Inline the common case. */
if (TREE_CODE (val) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
return tree_int_cst_lt (val, val2);
+ else if (TREE_CODE (val) == SSA_NAME && TREE_CODE (val2) == SSA_NAME)
+ return val == val2 ? 0 : -2;
else
{
- tree tcmp;
-
- fold_defer_overflow_warnings ();
-
- tcmp = fold_binary_to_constant (LT_EXPR, boolean_type_node, val, val2);
-
- fold_undefer_and_ignore_overflow_warnings ();
-
- if (!tcmp
- || TREE_CODE (tcmp) != INTEGER_CST)
- return -2;
-
- if (!integer_zerop (tcmp))
+ int cmp = compare_values (val, val2);
+ if (cmp == -1)
return 1;
+ else if (cmp == 0 || cmp == 1)
+ return 0;
+ else
+ return -2;
}
return 0;
@@ -958,8 +1026,8 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
/* Convert the two values into the same type. This is needed because
sizetype causes sign extension even for unsigned types. */
- val2 = fold_convert (TREE_TYPE (val1), val2);
- STRIP_USELESS_TYPE_CONVERSION (val2);
+ if (!useless_type_conversion_p (TREE_TYPE (val1), TREE_TYPE (val2)))
+ val2 = fold_convert (TREE_TYPE (val1), val2);
const bool overflow_undefined
= INTEGRAL_TYPE_P (TREE_TYPE (val1))
@@ -1067,32 +1135,43 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
}
else
{
- tree t;
+ if (TREE_CODE (val1) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
+ {
+ /* We cannot compare overflowed values. */
+ if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2))
+ return -2;
+
+ return tree_int_cst_compare (val1, val2);
+ }
/* First see if VAL1 and VAL2 are not the same. */
- if (val1 == val2 || operand_equal_p (val1, val2, 0))
+ if (operand_equal_p (val1, val2, 0))
return 0;
+ fold_defer_overflow_warnings ();
+
/* If VAL1 is a lower address than VAL2, return -1. */
- if (operand_less_p (val1, val2) == 1)
- return -1;
+ tree t = fold_binary_to_constant (LT_EXPR, boolean_type_node, val1, val2);
+ if (t && integer_onep (t))
+ {
+ fold_undefer_and_ignore_overflow_warnings ();
+ return -1;
+ }
/* If VAL1 is a higher address than VAL2, return +1. */
- if (operand_less_p (val2, val1) == 1)
- return 1;
-
- /* If VAL1 is different than VAL2, return +2.
- For integer constants we either have already returned -1 or 1
- or they are equivalent. We still might succeed in proving
- something about non-trivial operands. */
- if (TREE_CODE (val1) != INTEGER_CST
- || TREE_CODE (val2) != INTEGER_CST)
+ t = fold_binary_to_constant (LT_EXPR, boolean_type_node, val2, val1);
+ if (t && integer_onep (t))
{
- t = fold_binary_to_constant (NE_EXPR, boolean_type_node, val1, val2);
- if (t && integer_onep (t))
- return 2;
+ fold_undefer_and_ignore_overflow_warnings ();
+ return 1;
}
+ /* If VAL1 is different than VAL2, return +2. */
+ t = fold_binary_to_constant (NE_EXPR, boolean_type_node, val1, val2);
+ fold_undefer_and_ignore_overflow_warnings ();
+ if (t && integer_onep (t))
+ return 2;
+
return -2;
}
}
@@ -1174,7 +1253,8 @@ vrp_set_zero_nonzero_bits (const tree expr_type,
static bool
ranges_from_anti_range (const value_range_base *ar,
- value_range_base *vr0, value_range_base *vr1)
+ value_range_base *vr0, value_range_base *vr1,
+ bool handle_pointers)
{
tree type = ar->type ();
@@ -1187,18 +1267,18 @@ ranges_from_anti_range (const value_range_base *ar,
if (ar->kind () != VR_ANTI_RANGE
|| TREE_CODE (ar->min ()) != INTEGER_CST
|| TREE_CODE (ar->max ()) != INTEGER_CST
- || !vrp_val_min (type)
- || !vrp_val_max (type))
+ || !vrp_val_min (type, handle_pointers)
+ || !vrp_val_max (type, handle_pointers))
return false;
- if (tree_int_cst_lt (vrp_val_min (type), ar->min ()))
+ if (tree_int_cst_lt (vrp_val_min (type, handle_pointers), ar->min ()))
vr0->set (VR_RANGE,
- vrp_val_min (type),
+ vrp_val_min (type, handle_pointers),
wide_int_to_tree (type, wi::to_wide (ar->min ()) - 1));
- if (tree_int_cst_lt (ar->max (), vrp_val_max (type)))
+ if (tree_int_cst_lt (ar->max (), vrp_val_max (type, handle_pointers)))
vr1->set (VR_RANGE,
wide_int_to_tree (type, wi::to_wide (ar->max ()) + 1),
- vrp_val_max (type));
+ vrp_val_max (type, handle_pointers));
if (vr0->undefined_p ())
{
*vr0 = *vr1;
@@ -1209,21 +1289,20 @@ ranges_from_anti_range (const value_range_base *ar,
}
/* Extract the components of a value range into a pair of wide ints in
- [WMIN, WMAX].
-
- If the value range is anything but a VR_*RANGE of constants, the
- resulting wide ints are set to [-MIN, +MAX] for the type. */
+ [WMIN, WMAX], after having normalized any symbolics from the input. */
static void inline
-extract_range_into_wide_ints (const value_range_base *vr,
- signop sign, unsigned prec,
- wide_int &wmin, wide_int &wmax)
+extract_range_into_wide_ints (const value_range_base *vr_,
+ tree type, wide_int &wmin, wide_int &wmax)
{
- gcc_assert (vr->kind () != VR_ANTI_RANGE || vr->symbolic_p ());
- if (range_int_cst_p (vr))
+ signop sign = TYPE_SIGN (type);
+ unsigned int prec = TYPE_PRECISION (type);
+ gcc_assert (vr_->kind () != VR_ANTI_RANGE || vr_->symbolic_p ());
+ value_range vr = vr_->normalize_symbolics ();
+ if (range_int_cst_p (&vr))
{
- wmin = wi::to_wide (vr->min ());
- wmax = wi::to_wide (vr->max ());
+ wmin = wi::to_wide (vr.min ());
+ wmax = wi::to_wide (vr.max ());
}
else
{
@@ -1238,7 +1317,7 @@ extract_range_into_wide_ints (const value_range_base *vr,
static void
extract_range_from_multiplicative_op (value_range_base *vr,
- enum tree_code code,
+ enum tree_code code, tree type,
const value_range_base *vr0,
const value_range_base *vr1)
{
@@ -1250,13 +1329,31 @@ extract_range_from_multiplicative_op (value_range_base *vr,
|| code == ROUND_DIV_EXPR
|| code == RSHIFT_EXPR
|| code == LSHIFT_EXPR);
- gcc_assert (vr0->kind () == VR_RANGE
- && vr0->kind () == vr1->kind ());
+ if (!range_int_cst_p (vr1))
+ {
+ vr->set_varying (type);
+ return;
+ }
+
+ /* Even if vr0 is VARYING or otherwise not usable, we can derive
+ useful ranges just from the shift count. E.g.
+ x >> 63 for signed 64-bit x is always [-1, 0]. */
+ value_range_base tem = vr0->normalize_symbolics ();
+ tree vr0_min, vr0_max;
+ if (tem.kind () == VR_RANGE)
+ {
+ vr0_min = tem.min ();
+ vr0_max = tem.max ();
+ }
+ else
+ {
+ vr0_min = vrp_val_min (type);
+ vr0_max = vrp_val_max (type);
+ }
- tree type = vr0->type ();
wide_int res_lb, res_ub;
- wide_int vr0_lb = wi::to_wide (vr0->min ());
- wide_int vr0_ub = wi::to_wide (vr0->max ());
+ wide_int vr0_lb = wi::to_wide (vr0_min);
+ wide_int vr0_ub = wi::to_wide (vr0_max);
wide_int vr1_lb = wi::to_wide (vr1->min ());
wide_int vr1_ub = wi::to_wide (vr1->max ());
bool overflow_undefined = TYPE_OVERFLOW_UNDEFINED (type);
@@ -1266,11 +1363,10 @@ extract_range_from_multiplicative_op (value_range_base *vr,
code, TYPE_SIGN (type), prec,
vr0_lb, vr0_ub, vr1_lb, vr1_ub,
overflow_undefined))
- vr->set_and_canonicalize (VR_RANGE,
- wide_int_to_tree (type, res_lb),
- wide_int_to_tree (type, res_ub));
+ vr->set (VR_RANGE, wide_int_to_tree (type, res_lb),
+ wide_int_to_tree (type, res_ub));
else
- vr->set_varying ();
+ vr->set_varying (type);
}
/* If BOUND will include a symbolic bound, adjust it accordingly,
@@ -1479,7 +1575,7 @@ extract_range_from_binary_expr (value_range_base *vr,
if (!INTEGRAL_TYPE_P (expr_type)
&& !POINTER_TYPE_P (expr_type))
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -1503,7 +1599,7 @@ extract_range_from_binary_expr (value_range_base *vr,
&& code != BIT_IOR_EXPR
&& code != BIT_XOR_EXPR)
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -1518,9 +1614,9 @@ extract_range_from_binary_expr (value_range_base *vr,
have UNDEFINED result for all or some value-ranges of the not UNDEFINED
operand. */
else if (vr0.undefined_p ())
- vr0.set_varying ();
+ vr0.set_varying (expr_type);
else if (vr1.undefined_p ())
- vr1.set_varying ();
+ vr1.set_varying (expr_type);
/* We get imprecise results from ranges_from_anti_range when
code is EXACT_DIV_EXPR. We could mask out bits in the resulting
@@ -1592,7 +1688,7 @@ extract_range_from_binary_expr (value_range_base *vr,
|| vr0.symbolic_p ()
|| vr1.symbolic_p ()))
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -1610,7 +1706,7 @@ extract_range_from_binary_expr (value_range_base *vr,
else if (vr0.zero_p () && vr1.zero_p ())
vr->set_zero (expr_type);
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
}
else if (code == POINTER_PLUS_EXPR)
{
@@ -1639,7 +1735,7 @@ extract_range_from_binary_expr (value_range_base *vr,
else if (vr0.zero_p () && vr1.zero_p ())
vr->set_zero (expr_type);
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
}
else if (code == BIT_AND_EXPR)
{
@@ -1650,10 +1746,10 @@ extract_range_from_binary_expr (value_range_base *vr,
else if (vr0.zero_p () || vr1.zero_p ())
vr->set_zero (expr_type);
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
}
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -1662,19 +1758,30 @@ extract_range_from_binary_expr (value_range_base *vr,
range and see what we end up with. */
if (code == PLUS_EXPR || code == MINUS_EXPR)
{
+ value_range_kind vr0_kind = vr0.kind (), vr1_kind = vr1.kind ();
+ tree vr0_min = vr0.min (), vr0_max = vr0.max ();
+ tree vr1_min = vr1.min (), vr1_max = vr1.max ();
/* This will normalize things such that calculating
[0,0] - VR_VARYING is not dropped to varying, but is
calculated as [MIN+1, MAX]. */
if (vr0.varying_p ())
- vr0.set (VR_RANGE, vrp_val_min (expr_type), vrp_val_max (expr_type));
+ {
+ vr0_kind = VR_RANGE;
+ vr0_min = vrp_val_min (expr_type);
+ vr0_max = vrp_val_max (expr_type);
+ }
if (vr1.varying_p ())
- vr1.set (VR_RANGE, vrp_val_min (expr_type), vrp_val_max (expr_type));
+ {
+ vr1_kind = VR_RANGE;
+ vr1_min = vrp_val_min (expr_type);
+ vr1_max = vrp_val_max (expr_type);
+ }
const bool minus_p = (code == MINUS_EXPR);
- tree min_op0 = vr0.min ();
- tree min_op1 = minus_p ? vr1.max () : vr1.min ();
- tree max_op0 = vr0.max ();
- tree max_op1 = minus_p ? vr1.min () : vr1.max ();
+ tree min_op0 = vr0_min;
+ tree min_op1 = minus_p ? vr1_max : vr1_min;
+ tree max_op0 = vr0_max;
+ tree max_op1 = minus_p ? vr1_min : vr1_max;
tree sym_min_op0 = NULL_TREE;
tree sym_min_op1 = NULL_TREE;
tree sym_max_op0 = NULL_TREE;
@@ -1687,7 +1794,7 @@ extract_range_from_binary_expr (value_range_base *vr,
single-symbolic ranges, try to compute the precise resulting range,
but only if we know that this resulting range will also be constant
or single-symbolic. */
- if (vr0.kind () == VR_RANGE && vr1.kind () == VR_RANGE
+ if (vr0_kind == VR_RANGE && vr1_kind == VR_RANGE
&& (TREE_CODE (min_op0) == INTEGER_CST
|| (sym_min_op0
= get_single_symbol (min_op0, &neg_min_op0, &min_op0)))
@@ -1720,7 +1827,7 @@ extract_range_from_binary_expr (value_range_base *vr,
if (((bool)min_ovf && sym_min_op0 != sym_min_op1)
|| ((bool)max_ovf && sym_max_op0 != sym_max_op1))
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -1731,7 +1838,7 @@ extract_range_from_binary_expr (value_range_base *vr,
wmin, wmax, min_ovf, max_ovf);
if (type == VR_VARYING)
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -1757,7 +1864,7 @@ extract_range_from_binary_expr (value_range_base *vr,
a single range or anti-range as the above is
[-INF+1, +INF(OVF)] intersected with ~[5, 5]
but one could use a scheme similar to equivalences for this. */
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
}
@@ -1767,14 +1874,14 @@ extract_range_from_binary_expr (value_range_base *vr,
wide_int wmin, wmax;
wide_int vr0_min, vr0_max;
wide_int vr1_min, vr1_max;
- extract_range_into_wide_ints (&vr0, sign, prec, vr0_min, vr0_max);
- extract_range_into_wide_ints (&vr1, sign, prec, vr1_min, vr1_max);
+ extract_range_into_wide_ints (&vr0, expr_type, vr0_min, vr0_max);
+ extract_range_into_wide_ints (&vr1, expr_type, vr1_min, vr1_max);
if (wide_int_range_min_max (wmin, wmax, code, sign, prec,
vr0_min, vr0_max, vr1_min, vr1_max))
vr->set (VR_RANGE, wide_int_to_tree (expr_type, wmin),
wide_int_to_tree (expr_type, wmax));
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
else if (code == MULT_EXPR)
@@ -1782,10 +1889,10 @@ extract_range_from_binary_expr (value_range_base *vr,
if (!range_int_cst_p (&vr0)
|| !range_int_cst_p (&vr1))
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
- extract_range_from_multiplicative_op (vr, code, &vr0, &vr1);
+ extract_range_from_multiplicative_op (vr, code, expr_type, &vr0, &vr1);
return;
}
else if (code == RSHIFT_EXPR
@@ -1800,13 +1907,8 @@ extract_range_from_binary_expr (value_range_base *vr,
{
if (code == RSHIFT_EXPR)
{
- /* Even if vr0 is VARYING or otherwise not usable, we can derive
- useful ranges just from the shift count. E.g.
- x >> 63 for signed 64-bit x is always [-1, 0]. */
- if (vr0.kind () != VR_RANGE || vr0.symbolic_p ())
- vr0.set (VR_RANGE, vrp_val_min (expr_type),
- vrp_val_max (expr_type));
- extract_range_from_multiplicative_op (vr, code, &vr0, &vr1);
+ extract_range_from_multiplicative_op (vr, code, expr_type,
+ &vr0, &vr1);
return;
}
else if (code == LSHIFT_EXPR
@@ -1822,12 +1924,12 @@ extract_range_from_binary_expr (value_range_base *vr,
{
min = wide_int_to_tree (expr_type, res_lb);
max = wide_int_to_tree (expr_type, res_ub);
- vr->set_and_canonicalize (VR_RANGE, min, max);
+ vr->set (VR_RANGE, min, max);
return;
}
}
}
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
else if (code == TRUNC_DIV_EXPR
@@ -1854,9 +1956,9 @@ extract_range_from_binary_expr (value_range_base *vr,
NOTE: As a future improvement, we may be able to do better
with mixed symbolic (anti-)ranges like [0, A]. See note in
ranges_from_anti_range. */
- extract_range_into_wide_ints (&vr0, sign, prec,
+ extract_range_into_wide_ints (&vr0, expr_type,
dividend_min, dividend_max);
- extract_range_into_wide_ints (&vr1, sign, prec,
+ extract_range_into_wide_ints (&vr1, expr_type,
divisor_min, divisor_max);
if (!wide_int_range_div (wmin, wmax, code, sign, prec,
dividend_min, dividend_max,
@@ -1864,7 +1966,7 @@ extract_range_from_binary_expr (value_range_base *vr,
TYPE_OVERFLOW_UNDEFINED (expr_type),
extra_range_p, extra_min, extra_max))
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
vr->set (VR_RANGE, wide_int_to_tree (expr_type, wmin),
@@ -1887,8 +1989,8 @@ extract_range_from_binary_expr (value_range_base *vr,
}
wide_int wmin, wmax, tmp;
wide_int vr0_min, vr0_max, vr1_min, vr1_max;
- extract_range_into_wide_ints (&vr0, sign, prec, vr0_min, vr0_max);
- extract_range_into_wide_ints (&vr1, sign, prec, vr1_min, vr1_max);
+ extract_range_into_wide_ints (&vr0, expr_type, vr0_min, vr0_max);
+ extract_range_into_wide_ints (&vr1, expr_type, vr1_min, vr1_max);
wide_int_range_trunc_mod (wmin, wmax, sign, prec,
vr0_min, vr0_max, vr1_min, vr1_max);
min = wide_int_to_tree (expr_type, wmin);
@@ -1906,8 +2008,8 @@ extract_range_from_binary_expr (value_range_base *vr,
&may_be_nonzero0, &must_be_nonzero0);
vrp_set_zero_nonzero_bits (expr_type, &vr1,
&may_be_nonzero1, &must_be_nonzero1);
- extract_range_into_wide_ints (&vr0, sign, prec, vr0_min, vr0_max);
- extract_range_into_wide_ints (&vr1, sign, prec, vr1_min, vr1_max);
+ extract_range_into_wide_ints (&vr0, expr_type, vr0_min, vr0_max);
+ extract_range_into_wide_ints (&vr1, expr_type, vr1_min, vr1_max);
if (code == BIT_AND_EXPR)
{
if (wide_int_range_bit_and (wmin, wmax, sign, prec,
@@ -1923,7 +2025,7 @@ extract_range_from_binary_expr (value_range_base *vr,
vr->set (VR_RANGE, min, max);
}
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
else if (code == BIT_IOR_EXPR)
@@ -1941,7 +2043,7 @@ extract_range_from_binary_expr (value_range_base *vr,
vr->set (VR_RANGE, min, max);
}
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
else if (code == BIT_XOR_EXPR)
@@ -1957,7 +2059,7 @@ extract_range_from_binary_expr (value_range_base *vr,
vr->set (VR_RANGE, min, max);
}
else
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
}
@@ -1971,7 +2073,7 @@ extract_range_from_binary_expr (value_range_base *vr,
|| max == NULL_TREE
|| TREE_OVERFLOW_P (max))
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -1980,7 +2082,7 @@ extract_range_from_binary_expr (value_range_base *vr,
Note that we do accept [-INF, -INF] and [+INF, +INF]. */
if (vrp_val_is_min (min) && vrp_val_is_max (max))
{
- vr->set_varying ();
+ vr->set_varying (expr_type);
return;
}
@@ -1990,7 +2092,7 @@ extract_range_from_binary_expr (value_range_base *vr,
/* If the new range has its limits swapped around (MIN > MAX),
then the operation caused one of them to wrap around, mark
the new range VARYING. */
- vr->set_varying ();
+ vr->set_varying (expr_type);
}
else
vr->set (type, min, max);
@@ -2016,7 +2118,7 @@ extract_range_from_unary_expr (value_range_base *vr,
|| !(INTEGRAL_TYPE_P (type)
|| POINTER_TYPE_P (type)))
{
- vr->set_varying ();
+ vr->set_varying (type);
return;
}
@@ -2088,7 +2190,7 @@ extract_range_from_unary_expr (value_range_base *vr,
else if (vr0.zero_p ())
vr->set_zero (type);
else
- vr->set_varying ();
+ vr->set_varying (type);
return;
}
@@ -2111,8 +2213,7 @@ extract_range_from_unary_expr (value_range_base *vr,
signop outer_sign = TYPE_SIGN (outer_type);
unsigned inner_prec = TYPE_PRECISION (inner_type);
unsigned outer_prec = TYPE_PRECISION (outer_type);
- extract_range_into_wide_ints (&vr0, inner_sign, inner_prec,
- vr0_min, vr0_max);
+ extract_range_into_wide_ints (&vr0, inner_type, vr0_min, vr0_max);
if (wide_int_range_convert (wmin, wmax,
inner_sign, inner_prec,
outer_sign, outer_prec,
@@ -2120,30 +2221,31 @@ extract_range_from_unary_expr (value_range_base *vr,
{
tree min = wide_int_to_tree (outer_type, wmin);
tree max = wide_int_to_tree (outer_type, wmax);
- vr->set_and_canonicalize (VR_RANGE, min, max);
+ vr->set (VR_RANGE, min, max);
}
else
- vr->set_varying ();
+ vr->set_varying (outer_type);
return;
}
else if (code == ABS_EXPR)
{
wide_int wmin, wmax;
wide_int vr0_min, vr0_max;
- extract_range_into_wide_ints (&vr0, sign, prec, vr0_min, vr0_max);
+ extract_range_into_wide_ints (&vr0, type, vr0_min, vr0_max);
if (wide_int_range_abs (wmin, wmax, sign, prec, vr0_min, vr0_max,
TYPE_OVERFLOW_UNDEFINED (type)))
vr->set (VR_RANGE, wide_int_to_tree (type, wmin),
wide_int_to_tree (type, wmax));
else
- vr->set_varying ();
+ vr->set_varying (type);
return;
}
else if (code == ABSU_EXPR)
{
wide_int wmin, wmax;
wide_int vr0_min, vr0_max;
- extract_range_into_wide_ints (&vr0, SIGNED, prec, vr0_min, vr0_max);
+ tree signed_type = make_signed_type (TYPE_PRECISION (type));
+ extract_range_into_wide_ints (&vr0, signed_type, vr0_min, vr0_max);
wide_int_range_absu (wmin, wmax, prec, vr0_min, vr0_max);
vr->set (VR_RANGE, wide_int_to_tree (type, wmin),
wide_int_to_tree (type, wmax));
@@ -2151,7 +2253,7 @@ extract_range_from_unary_expr (value_range_base *vr,
}
/* For unhandled operations fall back to varying. */
- vr->set_varying ();
+ vr->set_varying (type);
return;
}
@@ -4292,10 +4394,12 @@ class vrp_prop : public ssa_propagation_engine
class vr_values vr_values;
/* Temporary delegator to minimize code churn. */
- value_range *get_value_range (const_tree op)
+ const value_range *get_value_range (const_tree op)
{ return vr_values.get_value_range (op); }
+ void set_def_to_varying (const_tree def)
+ { vr_values.set_def_to_varying (def); }
void set_defs_to_varying (gimple *stmt)
- { return vr_values.set_defs_to_varying (stmt); }
+ { vr_values.set_defs_to_varying (stmt); }
void extract_range_from_stmt (gimple *stmt, edge *taken_edge_p,
tree *output_p, value_range *vr)
{ vr_values.extract_range_from_stmt (stmt, taken_edge_p, output_p, vr); }
@@ -5148,7 +5252,7 @@ vrp_prop::vrp_initialize ()
if (!stmt_interesting_for_vrp (phi))
{
tree lhs = PHI_RESULT (phi);
- get_value_range (lhs)->set_varying ();
+ set_def_to_varying (lhs);
prop_set_simulate_again (phi, false);
}
else
@@ -5343,7 +5447,7 @@ vrp_prop::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
use_operand_p use_p;
enum ssa_prop_result res = SSA_PROP_VARYING;
- get_value_range (lhs)->set_varying ();
+ set_def_to_varying (lhs);
FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
{
@@ -5412,8 +5516,10 @@ union_ranges (enum value_range_kind *vr0type,
enum value_range_kind vr1type,
tree vr1min, tree vr1max)
{
- bool mineq = vrp_operand_equal_p (*vr0min, vr1min);
- bool maxeq = vrp_operand_equal_p (*vr0max, vr1max);
+ int cmpmin = compare_values (*vr0min, vr1min);
+ int cmpmax = compare_values (*vr0max, vr1max);
+ bool mineq = cmpmin == 0;
+ bool maxeq = cmpmax == 0;
/* [] is vr0, () is vr1 in the following classification comments. */
if (mineq && maxeq)
@@ -5513,8 +5619,8 @@ union_ranges (enum value_range_kind *vr0type,
else
gcc_unreachable ();
}
- else if ((maxeq || operand_less_p (vr1max, *vr0max) == 1)
- && (mineq || operand_less_p (*vr0min, vr1min) == 1))
+ else if ((maxeq || cmpmax == 1)
+ && (mineq || cmpmin == -1))
{
/* [ ( ) ] or [( ) ] or [ ( )] */
if (*vr0type == VR_RANGE
@@ -5547,8 +5653,8 @@ union_ranges (enum value_range_kind *vr0type,
else
gcc_unreachable ();
}
- else if ((maxeq || operand_less_p (*vr0max, vr1max) == 1)
- && (mineq || operand_less_p (vr1min, *vr0min) == 1))
+ else if ((maxeq || cmpmax == -1)
+ && (mineq || cmpmin == 1))
{
/* ( [ ] ) or ([ ] ) or ( [ ]) */
if (*vr0type == VR_RANGE
@@ -5587,10 +5693,10 @@ union_ranges (enum value_range_kind *vr0type,
else
gcc_unreachable ();
}
- else if ((operand_less_p (vr1min, *vr0max) == 1
- || operand_equal_p (vr1min, *vr0max, 0))
- && operand_less_p (*vr0min, vr1min) == 1
- && operand_less_p (*vr0max, vr1max) == 1)
+ else if (cmpmin == -1
+ && cmpmax == -1
+ && (operand_less_p (vr1min, *vr0max) == 1
+ || operand_equal_p (vr1min, *vr0max, 0)))
{
/* [ ( ] ) or [ ]( ) */
if (*vr0type == VR_RANGE
@@ -5624,10 +5730,10 @@ union_ranges (enum value_range_kind *vr0type,
else
gcc_unreachable ();
}
- else if ((operand_less_p (*vr0min, vr1max) == 1
- || operand_equal_p (*vr0min, vr1max, 0))
- && operand_less_p (vr1min, *vr0min) == 1
- && operand_less_p (vr1max, *vr0max) == 1)
+ else if (cmpmin == 1
+ && cmpmax == 1
+ && (operand_less_p (*vr0min, vr1max) == 1
+ || operand_equal_p (*vr0min, vr1max, 0)))
{
/* ( [ ) ] or ( )[ ] */
if (*vr0type == VR_RANGE
@@ -6028,7 +6134,12 @@ value_range_base::intersect_helper (const value_range_base *vr0,
VR_RANGE can still be a VR_RANGE. Work on a temporary so we can
fall back to vr0 when this turns things to varying. */
value_range_base tem;
- tem.set_and_canonicalize (vr0type, vr0min, vr0max);
+ if (vr0type == VR_UNDEFINED)
+ tem.set_undefined ();
+ else if (vr0type == VR_VARYING)
+ tem.set_varying (vr0->type ());
+ else
+ tem.set (vr0type, vr0min, vr0max);
/* If that failed, use the saved original VR0. */
if (tem.varying_p ())
return *vr0;
@@ -6133,7 +6244,12 @@ value_range_base::union_helper (const value_range_base *vr0,
/* Work on a temporary so we can still use vr0 when union returns varying. */
value_range_base tem;
- tem.set_and_canonicalize (vr0type, vr0min, vr0max);
+ if (vr0type == VR_UNDEFINED)
+ tem.set_undefined ();
+ else if (vr0type == VR_VARYING)
+ tem.set_varying (vr0->type ());
+ else
+ tem.set (vr0type, vr0min, vr0max);
/* Failed to find an efficient meet. Before giving up and setting
the result to VARYING, see if we can at least derive a useful
@@ -6213,6 +6329,58 @@ value_range::union_ (const value_range *other)
}
}
+/* Normalize symbolics into constants. */
+
+value_range_base
+value_range_base::normalize_symbolics () const
+{
+ if (varying_p () || undefined_p ())
+ return *this;
+ tree ttype = type ();
+ bool min_symbolic = !is_gimple_min_invariant (min ());
+ bool max_symbolic = !is_gimple_min_invariant (max ());
+ if (!min_symbolic && !max_symbolic)
+ return *this;
+
+ // [SYM, SYM] -> VARYING
+ if (min_symbolic && max_symbolic)
+ {
+ value_range_base var;
+ var.set_varying (ttype);
+ return var;
+ }
+ if (kind () == VR_RANGE)
+ {
+ // [SYM, NUM] -> [-MIN, NUM]
+ if (min_symbolic)
+ return value_range_base (VR_RANGE, vrp_val_min (ttype), max ());
+ // [NUM, SYM] -> [NUM, +MAX]
+ return value_range_base (VR_RANGE, min (), vrp_val_max (ttype));
+ }
+ gcc_assert (kind () == VR_ANTI_RANGE);
+ // ~[SYM, NUM] -> [NUM + 1, +MAX]
+ if (min_symbolic)
+ {
+ if (!vrp_val_is_max (max ()))
+ {
+ tree n = wide_int_to_tree (ttype, wi::to_wide (max ()) + 1);
+ return value_range_base (VR_RANGE, n, vrp_val_max (ttype));
+ }
+ value_range_base var;
+ var.set_varying (ttype);
+ return var;
+ }
+ // ~[NUM, SYM] -> [-MIN, NUM - 1]
+ if (!vrp_val_is_min (min ()))
+ {
+ tree n = wide_int_to_tree (ttype, wi::to_wide (min ()) - 1);
+ return value_range_base (VR_RANGE, vrp_val_min (ttype), n);
+ }
+ value_range_base var;
+ var.set_varying (ttype);
+ return var;
+}
+
/* Visit all arguments for PHI node PHI that flow through executable
edges. If a valid value range can be derived from all the incoming
value ranges, set a new range for the LHS of PHI. */
@@ -6886,7 +7054,7 @@ determine_value_range_1 (value_range_base *vr, tree expr)
vr->set (kind, wide_int_to_tree (TREE_TYPE (expr), min),
wide_int_to_tree (TREE_TYPE (expr), max));
else
- vr->set_varying ();
+ vr->set_varying (TREE_TYPE (expr));
}
}
diff --git a/gcc/tree-vrp.h b/gcc/tree-vrp.h
index 4ec974f..c879a8c 100644
--- a/gcc/tree-vrp.h
+++ b/gcc/tree-vrp.h
@@ -58,7 +58,7 @@ public:
bool constant_p () const;
bool undefined_p () const;
bool varying_p () const;
- void set_varying ();
+ void set_varying (tree type);
void set_undefined ();
void union_ (const value_range_base *);
@@ -71,11 +71,14 @@ public:
/* Misc methods. */
tree type () const;
bool may_contain_p (tree) const;
- void set_and_canonicalize (enum value_range_kind, tree, tree);
bool zero_p () const;
bool nonzero_p () const;
bool singleton_p (tree *result = NULL) const;
void dump (FILE *) const;
+ void dump () const;
+
+ static bool supports_type_p (tree);
+ value_range_base normalize_symbolics () const;
protected:
void check ();
@@ -134,7 +137,7 @@ class GTY((user)) value_range : public value_range_base
/* Types of value ranges. */
void set_undefined ();
- void set_varying ();
+ void set_varying (tree);
/* Equivalence bitmap methods. */
bitmap equiv () const;
@@ -143,8 +146,8 @@ class GTY((user)) value_range : public value_range_base
/* Misc methods. */
void deep_copy (const value_range *);
- void set_and_canonicalize (enum value_range_kind, tree, tree, bitmap = NULL);
void dump (FILE *) const;
+ void dump () const;
private:
/* Deep-copies bitmap argument. */
@@ -254,6 +257,17 @@ struct assert_info
tree expr;
};
+// Return true if TYPE is a valid type for value_range to operate on.
+// Otherwise return FALSE.
+
+inline bool
+value_range_base::supports_type_p (tree type)
+{
+ if (type && (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)))
+ return type;
+ return NULL;
+}
+
extern void register_edge_assert_for (tree, edge, enum tree_code,
tree, tree, vec<assert_info> &);
extern bool stmt_interesting_for_vrp (gimple *);
@@ -270,8 +284,8 @@ extern int operand_less_p (tree, tree);
extern bool vrp_val_is_min (const_tree);
extern bool vrp_val_is_max (const_tree);
-extern tree vrp_val_min (const_tree);
-extern tree vrp_val_max (const_tree);
+extern tree vrp_val_min (const_tree, bool handle_pointers = false);
+extern tree vrp_val_max (const_tree, bool handle_pointers = false);
extern void extract_range_from_unary_expr (value_range_base *vr,
enum tree_code code,
diff --git a/gcc/tree.c b/gcc/tree.c
index 8cf75f2..ae29228 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -299,6 +299,7 @@ unsigned const char omp_clause_num_ops[] =
2, /* OMP_CLAUSE_TO */
2, /* OMP_CLAUSE_MAP */
1, /* OMP_CLAUSE_USE_DEVICE_PTR */
+ 1, /* OMP_CLAUSE_USE_DEVICE_ADDR */
1, /* OMP_CLAUSE_IS_DEVICE_PTR */
1, /* OMP_CLAUSE_INCLUSIVE */
1, /* OMP_CLAUSE_EXCLUSIVE */
@@ -331,6 +332,7 @@ unsigned const char omp_clause_num_ops[] =
0, /* OMP_CLAUSE_PROC_BIND */
1, /* OMP_CLAUSE_SAFELEN */
1, /* OMP_CLAUSE_SIMDLEN */
+ 0, /* OMP_CLAUSE_DEVICE_TYPE */
0, /* OMP_CLAUSE_FOR */
0, /* OMP_CLAUSE_PARALLEL */
0, /* OMP_CLAUSE_SECTIONS */
@@ -382,6 +384,7 @@ const char * const omp_clause_code_name[] =
"to",
"map",
"use_device_ptr",
+ "use_device_addr",
"is_device_ptr",
"inclusive",
"exclusive",
@@ -414,6 +417,7 @@ const char * const omp_clause_code_name[] =
"proc_bind",
"safelen",
"simdlen",
+ "device_type",
"for",
"parallel",
"sections",
@@ -1977,6 +1981,23 @@ build_index_vector (tree vec_type, poly_uint64 base, poly_uint64 step)
return v.build ();
}
+/* Return a VECTOR_CST of type VEC_TYPE in which the first NUM_A
+ elements are A and the rest are B. */
+
+tree
+build_vector_a_then_b (tree vec_type, unsigned int num_a, tree a, tree b)
+{
+ gcc_assert (known_le (num_a, TYPE_VECTOR_SUBPARTS (vec_type)));
+ unsigned int count = constant_lower_bound (TYPE_VECTOR_SUBPARTS (vec_type));
+ /* Optimize the constant case. */
+ if ((count & 1) == 0 && TYPE_VECTOR_SUBPARTS (vec_type).is_constant ())
+ count /= 2;
+ tree_vector_builder builder (vec_type, count, 2);
+ for (unsigned int i = 0; i < count * 2; ++i)
+ builder.quick_push (i < num_a ? a : b);
+ return builder.build ();
+}
+
/* Something has messed with the elements of CONSTRUCTOR C after it was built;
calculate TREE_CONSTANT and TREE_SIDE_EFFECTS. */
@@ -5527,8 +5548,7 @@ free_lang_data_in_type (tree type, class free_lang_data_d *fld)
free_lang_data_in_binfo (TYPE_BINFO (type));
/* We need to preserve link to bases and virtual table for all
polymorphic types to make devirtualization machinery working. */
- if (!BINFO_VTABLE (TYPE_BINFO (type))
- || !flag_devirtualize)
+ if (!BINFO_VTABLE (TYPE_BINFO (type)))
TYPE_BINFO (type) = NULL;
}
}
@@ -11376,6 +11396,73 @@ initializer_each_zero_or_onep (const_tree expr)
}
}
+/* Given an initializer INIT for a TYPE, return true if INIT is zero
+ so that it can be replaced by value initialization. This function
+ distinguishes betwen empty strings as initializers for arrays and
+ for pointers (which make it return false). */
+
+bool
+type_initializer_zero_p (tree type, tree init)
+{
+ if (type == error_mark_node || init == error_mark_node)
+ return false;
+
+ STRIP_NOPS (init);
+
+ if (POINTER_TYPE_P (type))
+ return TREE_CODE (init) != STRING_CST && initializer_zerop (init);
+
+ if (TREE_CODE (init) != CONSTRUCTOR)
+ return initializer_zerop (init);
+
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ tree elt_type = TREE_TYPE (type);
+ elt_type = TYPE_MAIN_VARIANT (elt_type);
+ if (elt_type == char_type_node)
+ return initializer_zerop (init);
+
+ tree elt_init;
+ unsigned HOST_WIDE_INT i;
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, elt_init)
+ if (!type_initializer_zero_p (elt_type, elt_init))
+ return false;
+ return true;
+ }
+
+ if (TREE_CODE (type) != RECORD_TYPE)
+ return initializer_zerop (init);
+
+ tree fld = TYPE_FIELDS (type);
+
+ tree fld_init;
+ unsigned HOST_WIDE_INT i;
+ FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, fld_init)
+ {
+ /* Advance to the next member, skipping over everything that
+ canot be initialized (including unnamed bit-fields). */
+ while (TREE_CODE (fld) != FIELD_DECL
+ || DECL_ARTIFICIAL (fld)
+ || (DECL_BIT_FIELD (fld) && !DECL_NAME (fld)))
+ {
+ fld = DECL_CHAIN (fld);
+ if (!fld)
+ return true;
+ continue;
+ }
+
+ tree fldtype = TREE_TYPE (fld);
+ if (!type_initializer_zero_p (fldtype, fld_init))
+ return false;
+
+ fld = DECL_CHAIN (fld);
+ if (!fld)
+ break;
+ }
+
+ return true;
+}
+
/* Check if vector VEC consists of all the equal elements and
that the number of elements corresponds to the type of VEC.
The function returns first element of the vector
@@ -12317,6 +12404,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
case OMP_CLAUSE_TO_DECLARE:
case OMP_CLAUSE_LINK:
case OMP_CLAUSE_USE_DEVICE_PTR:
+ case OMP_CLAUSE_USE_DEVICE_ADDR:
case OMP_CLAUSE_IS_DEVICE_PTR:
case OMP_CLAUSE_INCLUSIVE:
case OMP_CLAUSE_EXCLUSIVE:
@@ -12334,6 +12422,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
case OMP_CLAUSE_UNTIED:
case OMP_CLAUSE_MERGEABLE:
case OMP_CLAUSE_PROC_BIND:
+ case OMP_CLAUSE_DEVICE_TYPE:
case OMP_CLAUSE_INBRANCH:
case OMP_CLAUSE_NOTINBRANCH:
case OMP_CLAUSE_FOR:
diff --git a/gcc/tree.def b/gcc/tree.def
index 4a22d94..bfb486d 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -77,7 +77,10 @@ DEFTREECODE (BLOCK, "block", tcc_exceptional, 0)
/* Each data type is represented by a tree node whose code is one of
the following: */
/* Each node that represents a data type has a component TYPE_SIZE
- containing a tree that is an expression for the size in bits.
+ that evaluates either to a tree that is a (potentially non-constant)
+ expression representing the type size in bits, or to a null pointer
+ when the size of the type is unknown (for example, for incomplete
+ types such as arrays of unspecified bound).
The TYPE_MODE contains the machine mode for values of this type.
The TYPE_POINTER_TO field contains a type for a pointer to this type,
or zero if no such has been created yet.
diff --git a/gcc/tree.h b/gcc/tree.h
index 99d021e..37f6d57 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1517,10 +1517,11 @@ class auto_suppress_location_wrappers
#define OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ(NODE) \
(OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_init
-/* True if a LASTPRIVATE clause is for a C++ class IV on taskloop construct
- (thus should be lastprivate on the outer taskloop and firstprivate on
- task). */
-#define OMP_CLAUSE_LASTPRIVATE_TASKLOOP_IV(NODE) \
+/* True if a LASTPRIVATE clause is for a C++ class IV on taskloop or
+ loop construct (thus should be lastprivate on the outer taskloop and
+ firstprivate on task for the taskloop construct and carefully handled
+ for loop construct). */
+#define OMP_CLAUSE_LASTPRIVATE_LOOP_IV(NODE) \
TREE_PROTECTED (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LASTPRIVATE))
/* True if a LASTPRIVATE clause has CONDITIONAL: modifier. */
@@ -1619,6 +1620,9 @@ class auto_suppress_location_wrappers
#define OMP_CLAUSE_PROC_BIND_KIND(NODE) \
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_PROC_BIND)->omp_clause.subcode.proc_bind_kind)
+#define OMP_CLAUSE_DEVICE_TYPE_KIND(NODE) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEVICE_TYPE)->omp_clause.subcode.device_type_kind)
+
#define OMP_CLAUSE_COLLAPSE_EXPR(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_COLLAPSE), 0)
#define OMP_CLAUSE_COLLAPSE_ITERVAR(NODE) \
@@ -1948,7 +1952,10 @@ class auto_suppress_location_wrappers
so they must be checked as well. */
#define TYPE_UID(NODE) (TYPE_CHECK (NODE)->type_common.uid)
+/* Type size in bits as a tree expression. Need not be constant
+ and may be null. */
#define TYPE_SIZE(NODE) (TYPE_CHECK (NODE)->type_common.size)
+/* Likewise, type size in bytes. */
#define TYPE_SIZE_UNIT(NODE) (TYPE_CHECK (NODE)->type_common.size_unit)
#define TYPE_POINTER_TO(NODE) (TYPE_CHECK (NODE)->type_common.pointer_to)
#define TYPE_REFERENCE_TO(NODE) (TYPE_CHECK (NODE)->type_common.reference_to)
@@ -2476,7 +2483,7 @@ extern machine_mode vector_type_mode (const_tree);
#define DECL_INITIAL(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.initial)
/* Holds the size of the datum, in bits, as a tree expression.
- Need not be constant. */
+ Need not be constant and may be null. */
#define DECL_SIZE(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.size)
/* Likewise for the size in bytes. */
#define DECL_SIZE_UNIT(NODE) (DECL_COMMON_CHECK (NODE)->decl_common.size_unit)
@@ -2514,10 +2521,10 @@ extern machine_mode vector_type_mode (const_tree);
(DECL_COMMON_CHECK (NODE)->decl_common.mode = (MODE))
/* For FUNCTION_DECL, if it is built-in, this identifies which built-in
- operation it is. Note, however, that this field is overloaded, with
- DECL_BUILT_IN_CLASS as the discriminant, so the latter must always be
- checked before any access to the former. */
-#define DECL_FUNCTION_CODE(NODE) \
+ operation it is. This is only intended for low-level accesses;
+ normally DECL_FUNCTION_CODE, DECL_FE_FUNCTION_CODE or DECL_MD_FUNCTION
+ should be used instead. */
+#define DECL_UNCHECKED_FUNCTION_CODE(NODE) \
(FUNCTION_DECL_CHECK (NODE)->function_decl.function_code)
/* Test if FCODE is a function code for an alloca operation. */
@@ -2994,11 +3001,45 @@ extern void decl_fini_priority_insert (tree, priority_type);
#define DECL_IS_MALLOC(NODE) \
(FUNCTION_DECL_CHECK (NODE)->function_decl.malloc_flag)
+/* Macro for direct set and get of function_decl.decl_type. */
+#define FUNCTION_DECL_DECL_TYPE(NODE) \
+ (NODE->function_decl.decl_type)
+
+/* Set decl_type of a DECL. Set it to T when SET is true, or reset
+ it to NONE. */
+
+static inline void
+set_function_decl_type (tree decl, function_decl_type t, bool set)
+{
+ if (set)
+ {
+ gcc_assert (FUNCTION_DECL_DECL_TYPE (decl) == NONE
+ || FUNCTION_DECL_DECL_TYPE (decl) == t);
+ decl->function_decl.decl_type = t;
+ }
+ else if (FUNCTION_DECL_DECL_TYPE (decl) == t)
+ FUNCTION_DECL_DECL_TYPE (decl) = NONE;
+}
+
/* Nonzero in a FUNCTION_DECL means this function should be treated as
C++ operator new, meaning that it returns a pointer for which we
should not use type based aliasing. */
-#define DECL_IS_OPERATOR_NEW(NODE) \
- (FUNCTION_DECL_CHECK (NODE)->function_decl.operator_new_flag)
+#define DECL_IS_OPERATOR_NEW_P(NODE) \
+ (FUNCTION_DECL_CHECK (NODE)->function_decl.decl_type == OPERATOR_NEW)
+
+#define DECL_IS_REPLACEABLE_OPERATOR_NEW_P(NODE) \
+ (DECL_IS_OPERATOR_NEW_P (NODE) && DECL_IS_MALLOC (NODE))
+
+#define DECL_SET_IS_OPERATOR_NEW(NODE, VAL) \
+ set_function_decl_type (FUNCTION_DECL_CHECK (NODE), OPERATOR_NEW, VAL)
+
+/* Nonzero in a FUNCTION_DECL means this function should be treated as
+ C++ operator delete. */
+#define DECL_IS_OPERATOR_DELETE_P(NODE) \
+ (FUNCTION_DECL_CHECK (NODE)->function_decl.decl_type == OPERATOR_DELETE)
+
+#define DECL_SET_IS_OPERATOR_DELETE(NODE, VAL) \
+ set_function_decl_type (FUNCTION_DECL_CHECK (NODE), OPERATOR_DELETE, VAL)
/* Nonzero in a FUNCTION_DECL means this function may return more
than once. */
@@ -3105,10 +3146,9 @@ extern vec<tree, va_gc> **decl_debug_args_insert (tree);
#define DECL_STRUCT_FUNCTION(NODE) \
(FUNCTION_DECL_CHECK (NODE)->function_decl.f)
-
/* For a builtin function, identify which part of the compiler defined it. */
#define DECL_BUILT_IN_CLASS(NODE) \
- (FUNCTION_DECL_CHECK (NODE)->function_decl.built_in_class)
+ ((built_in_class) FUNCTION_DECL_CHECK (NODE)->function_decl.built_in_class)
/* In FUNCTION_DECL, a chain of ..._DECL nodes. */
#define DECL_ARGUMENTS(NODE) \
@@ -3143,8 +3183,11 @@ extern vec<tree, va_gc> **decl_debug_args_insert (tree);
(FUNCTION_DECL_CHECK (NODE)->decl_with_vis.cxx_destructor)
/* In FUNCTION_DECL, this is set if this function is a lambda function. */
-#define DECL_LAMBDA_FUNCTION(NODE) \
- (FUNCTION_DECL_CHECK (NODE)->function_decl.lambda_function)
+#define DECL_LAMBDA_FUNCTION_P(NODE) \
+ (FUNCTION_DECL_CHECK (NODE)->function_decl.decl_type == LAMBDA_FUNCTION)
+
+#define DECL_SET_LAMBDA_FUNCTION(NODE, VAL) \
+ set_function_decl_type (FUNCTION_DECL_CHECK (NODE), LAMBDA_FUNCTION, VAL)
/* In FUNCTION_DECL that represent an virtual method this is set when
the method is final. */
@@ -3844,6 +3887,61 @@ valid_vector_subparts_p (poly_uint64 subparts)
return true;
}
+/* Return the built-in function that DECL represents, given that it is known
+ to be a FUNCTION_DECL with built-in class BUILT_IN_NORMAL. */
+inline built_in_function
+DECL_FUNCTION_CODE (const_tree decl)
+{
+ const tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl;
+ gcc_checking_assert (fndecl.built_in_class == BUILT_IN_NORMAL);
+ return (built_in_function) fndecl.function_code;
+}
+
+/* Return the target-specific built-in function that DECL represents,
+ given that it is known to be a FUNCTION_DECL with built-in class
+ BUILT_IN_MD. */
+inline int
+DECL_MD_FUNCTION_CODE (const_tree decl)
+{
+ const tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl;
+ gcc_checking_assert (fndecl.built_in_class == BUILT_IN_MD);
+ return fndecl.function_code;
+}
+
+/* Return the frontend-specific built-in function that DECL represents,
+ given that it is known to be a FUNCTION_DECL with built-in class
+ BUILT_IN_FRONTEND. */
+inline int
+DECL_FE_FUNCTION_CODE (const_tree decl)
+{
+ const tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl;
+ gcc_checking_assert (fndecl.built_in_class == BUILT_IN_FRONTEND);
+ return fndecl.function_code;
+}
+
+/* Record that FUNCTION_DECL DECL represents built-in function FCODE of
+ class FCLASS. */
+inline void
+set_decl_built_in_function (tree decl, built_in_class fclass,
+ unsigned int fcode)
+{
+ tree_function_decl &fndecl = FUNCTION_DECL_CHECK (decl)->function_decl;
+ fndecl.built_in_class = fclass;
+ fndecl.function_code = fcode;
+}
+
+/* Record that FUNCTION_DECL NEWDECL represents the same built-in function
+ as OLDDECL (or none, if OLDDECL doesn't represent a built-in function). */
+inline void
+copy_decl_built_in_function (tree newdecl, const_tree olddecl)
+{
+ tree_function_decl &newfndecl = FUNCTION_DECL_CHECK (newdecl)->function_decl;
+ const tree_function_decl &oldfndecl
+ = FUNCTION_DECL_CHECK (olddecl)->function_decl;
+ newfndecl.built_in_class = oldfndecl.built_in_class;
+ newfndecl.function_code = oldfndecl.function_code;
+}
+
/* In NON_LVALUE_EXPR and VIEW_CONVERT_EXPR, set when this node is merely a
wrapper added to express a location_t on behalf of the node's child
(e.g. by maybe_wrap_with_location). */
@@ -4273,6 +4371,7 @@ extern tree build_vector_from_val (tree, tree);
extern tree build_uniform_cst (tree, tree);
extern tree build_vec_series (tree, tree, tree);
extern tree build_index_vector (tree, poly_uint64, poly_uint64);
+extern tree build_vector_a_then_b (tree, unsigned int, tree, tree);
extern void recompute_constructor_flags (tree);
extern void verify_constructor_flags (tree);
extern tree build_constructor (tree, vec<constructor_elt, va_gc> * CXX_MEM_STAT_INFO);
@@ -4586,6 +4685,12 @@ extern tree first_field (const_tree);
extern bool initializer_zerop (const_tree, bool * = NULL);
extern bool initializer_each_zero_or_onep (const_tree);
+/* Analogous to initializer_zerop but also examines the type for
+ which the initializer is being used. Unlike initializer_zerop,
+ considers empty strings to be zero initializers for arrays and
+ non-zero for pointers. */
+extern bool type_initializer_zero_p (tree, tree);
+
extern wide_int vector_cst_int_elt (const_tree, unsigned int);
extern tree vector_cst_elt (const_tree, unsigned int);
@@ -6029,9 +6134,10 @@ fndecl_built_in_p (const_tree node, built_in_class klass)
of class KLASS with name equal to NAME. */
inline bool
-fndecl_built_in_p (const_tree node, int name, built_in_class klass)
+fndecl_built_in_p (const_tree node, unsigned int name, built_in_class klass)
{
- return (fndecl_built_in_p (node, klass) && DECL_FUNCTION_CODE (node) == name);
+ return (fndecl_built_in_p (node, klass)
+ && DECL_UNCHECKED_FUNCTION_CODE (node) == name);
}
/* Return true if a FUNCTION_DECL NODE is a GCC built-in function
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 32e6ddd..00ede8d 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -713,45 +713,38 @@ gimple_divmod_fixed_value (gassign *stmt, tree value, profile_probability prob,
return tmp2;
}
-/* Return most common value of TOPN_VALUE histogram. If
- there's a unique value, return true and set VALUE and COUNT
+/* Return the n-th value count of TOPN_VALUE histogram. If
+ there's a value, return true and set VALUE and COUNT
arguments. */
bool
-get_most_common_single_value (gimple *stmt, const char *counter_type,
- histogram_value hist,
- gcov_type *value, gcov_type *count,
- gcov_type *all)
+get_nth_most_common_value (gimple *stmt, const char *counter_type,
+ histogram_value hist, gcov_type *value,
+ gcov_type *count, gcov_type *all, unsigned n)
{
if (hist->hvalue.counters[2] == -1)
return false;
+ gcc_assert (n < GCOV_TOPN_VALUES);
+
*count = 0;
*value = 0;
gcov_type read_all = hist->hvalue.counters[0];
- for (unsigned i = 0; i < GCOV_TOPN_VALUES; i++)
- {
- gcov_type v = hist->hvalue.counters[2 * i + 1];
- gcov_type c = hist->hvalue.counters[2 * i + 2];
-
- /* Indirect calls can't be vereified. */
- if (stmt && check_counter (stmt, counter_type, &c, &read_all,
- gimple_bb (stmt)->count))
- return false;
+ gcov_type v = hist->hvalue.counters[2 * n + 1];
+ gcov_type c = hist->hvalue.counters[2 * n + 2];
- *all = read_all;
+ /* Indirect calls can't be verified. */
+ if (stmt
+ && check_counter (stmt, counter_type, &c, &read_all,
+ gimple_bb (stmt)->count))
+ return false;
- if (c > *count)
- {
- *value = v;
- *count = c;
- }
- else if (c == *count && v > *value)
- *value = v;
- }
+ *all = read_all;
+ *value = v;
+ *count = c;
return true;
}
@@ -784,8 +777,8 @@ gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si)
if (!histogram)
return false;
- if (!get_most_common_single_value (stmt, "divmod", histogram, &val, &count,
- &all))
+ if (!get_nth_most_common_value (stmt, "divmod", histogram, &val, &count,
+ &all))
return false;
value = histogram->hvalue.value;
@@ -816,12 +809,9 @@ gimple_divmod_fixed_value_transform (gimple_stmt_iterator *si)
}
result = gimple_divmod_fixed_value (stmt, tree_val, prob, count, all);
- if (dump_file)
- {
- fprintf (dump_file, "Transformation done: div/mod by constant ");
- print_generic_expr (dump_file, tree_val, TDF_SLIM);
- fprintf (dump_file, "\n");
- }
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
+ "Transformation done: div/mod by constant %T\n", tree_val);
gimple_assign_set_rhs_from_tree (si, result);
update_stmt (gsi_stmt (*si));
@@ -956,8 +946,9 @@ gimple_mod_pow2_value_transform (gimple_stmt_iterator *si)
if (check_counter (stmt, "pow2", &count, &all, gimple_bb (stmt)->count))
return false;
- if (dump_file)
- fprintf (dump_file, "Transformation done: mod power of 2\n");
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
+ "Transformation done: mod power of 2\n");
if (all > 0)
prob = profile_probability::probability_in_gcov_type (count, all);
@@ -1140,8 +1131,9 @@ gimple_mod_subtract_transform (gimple_stmt_iterator *si)
return false;
gimple_remove_histogram_value (cfun, stmt, histogram);
- if (dump_file)
- fprintf (dump_file, "Transformation done: mod subtract\n");
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
+ "Transformation done: mod subtract\n");
/* Compute probability of taking the optimal path(s). */
if (all > 0)
@@ -1192,37 +1184,40 @@ init_node_map (bool local)
if (n->has_gimple_body_p () || n->thunk.thunk_p)
{
cgraph_node **val;
+ dump_user_location_t loc
+ = dump_user_location_t::from_function_decl (n->decl);
if (local)
{
n->profile_id = coverage_compute_profile_id (n);
while ((val = cgraph_node_map->get (n->profile_id))
|| !n->profile_id)
{
- if (dump_file)
- fprintf (dump_file, "Local profile-id %i conflict"
- " with nodes %s %s\n",
- n->profile_id,
- n->dump_name (),
- (*val)->dump_name ());
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
+ "Local profile-id %i conflict"
+ " with nodes %s %s\n",
+ n->profile_id,
+ n->dump_name (),
+ (*val)->dump_name ());
n->profile_id = (n->profile_id + 1) & 0x7fffffff;
}
}
else if (!n->profile_id)
{
- if (dump_file)
- fprintf (dump_file,
- "Node %s has no profile-id"
- " (profile feedback missing?)\n",
- n->dump_name ());
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
+ "Node %s has no profile-id"
+ " (profile feedback missing?)\n",
+ n->dump_name ());
continue;
}
else if ((val = cgraph_node_map->get (n->profile_id)))
{
- if (dump_file)
- fprintf (dump_file,
- "Node %s has IP profile-id %i conflict. "
- "Giving up.\n",
- n->dump_name (), n->profile_id);
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, loc,
+ "Node %s has IP profile-id %i conflict. "
+ "Giving up.\n",
+ n->dump_name (), n->profile_id);
*val = NULL;
continue;
}
@@ -1439,8 +1434,8 @@ gimple_ic_transform (gimple_stmt_iterator *gsi)
if (!histogram)
return false;
- if (!get_most_common_single_value (NULL, "indirect call", histogram, &val,
- &count, &all))
+ if (!get_nth_most_common_value (NULL, "indirect call", histogram, &val,
+ &count, &all))
return false;
if (4 * count <= 3 * all)
@@ -1452,41 +1447,35 @@ gimple_ic_transform (gimple_stmt_iterator *gsi)
{
if (val)
{
- if (dump_file)
- {
- fprintf (dump_file, "Indirect call -> direct call from other module");
- print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
- fprintf (dump_file, "=> %i (will resolve only with LTO)\n", (int)val);
- }
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, stmt,
+ "Indirect call -> direct call from other "
+ "module %T=> %i (will resolve only with LTO)\n",
+ gimple_call_fn (stmt), (int)val);
}
return false;
}
if (!check_ic_target (stmt, direct_call))
{
- if (dump_file)
- {
- fprintf (dump_file, "Indirect call -> direct call ");
- print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
- fprintf (dump_file, "=> ");
- print_generic_expr (dump_file, direct_call->decl, TDF_SLIM);
- fprintf (dump_file, " transformation skipped because of type mismatch");
- print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
- }
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, stmt,
+ "Indirect call -> direct call %T => %T "
+ "transformation skipped because of type mismatch: %G",
+ gimple_call_fn (stmt), direct_call->decl, stmt);
gimple_remove_histogram_value (cfun, stmt, histogram);
return false;
}
- if (dump_file)
+ if (dump_enabled_p ())
{
- fprintf (dump_file, "Indirect call -> direct call ");
- print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
- fprintf (dump_file, "=> ");
- print_generic_expr (dump_file, direct_call->decl, TDF_SLIM);
- fprintf (dump_file, " transformation on insn postponned to ipa-profile");
- print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
- fprintf (dump_file, "hist->count %" PRId64
- " hist->all %" PRId64"\n", count, all);
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
+ "Indirect call -> direct call "
+ "%T => %T transformation on insn postponed\n",
+ gimple_call_fn (stmt), direct_call->decl);
+ dump_printf_loc (MSG_NOTE, stmt,
+ "hist->count %" PRId64
+ " hist->all %" PRId64"\n", count, all);
}
return true;
@@ -1658,8 +1647,8 @@ gimple_stringops_transform (gimple_stmt_iterator *gsi)
if (!histogram)
return false;
- if (!get_most_common_single_value (stmt, "stringops", histogram, &val,
- &count, &all))
+ if (!get_nth_most_common_value (stmt, "stringops", histogram, &val, &count,
+ &all))
return false;
gimple_remove_histogram_value (cfun, stmt, histogram);
@@ -1715,10 +1704,10 @@ gimple_stringops_transform (gimple_stmt_iterator *gsi)
TYPE_PRECISION (get_gcov_type ()), false));
}
- if (dump_file)
- fprintf (dump_file,
- "Transformation done: single value %i stringop for %s\n",
- (int)val, built_in_names[(int)fcode]);
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
+ "Transformation done: single value %i stringop for %s\n",
+ (int)val, built_in_names[(int)fcode]);
gimple_stringop_fixed_value (stmt, tree_val, prob, count, all);
diff --git a/gcc/value-prof.h b/gcc/value-prof.h
index ca846d0..1078722 100644
--- a/gcc/value-prof.h
+++ b/gcc/value-prof.h
@@ -89,11 +89,10 @@ void free_histograms (function *);
void stringop_block_profile (gimple *, unsigned int *, HOST_WIDE_INT *);
gcall *gimple_ic (gcall *, struct cgraph_node *, profile_probability);
bool check_ic_target (gcall *, struct cgraph_node *);
-bool get_most_common_single_value (gimple *stmt, const char *counter_type,
- histogram_value hist,
- gcov_type *value, gcov_type *count,
- gcov_type *all);
-
+bool get_nth_most_common_value (gimple *stmt, const char *counter_type,
+ histogram_value hist, gcov_type *value,
+ gcov_type *count, gcov_type *all,
+ unsigned n = 0);
/* In tree-profile.c. */
extern void gimple_init_gcov_profiler (void);
diff --git a/gcc/varasm.c b/gcc/varasm.c
index e886cdc..ae25f4d 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -6430,6 +6430,9 @@ default_section_type_flags (tree decl, const char *name, int reloc)
|| strncmp (name, ".gnu.linkonce.tb.", 17) == 0)
flags |= SECTION_TLS | SECTION_BSS;
+ if (strcmp (name, ".noinit") == 0)
+ flags |= SECTION_WRITE | SECTION_BSS | SECTION_NOTYPE;
+
/* Various sections have special ELF types that the assembler will
assign by default based on the name. They are neither SHT_PROGBITS
nor SHT_NOBITS, so when changing sections we don't want to print a
@@ -6755,6 +6758,7 @@ default_elf_select_section (tree decl, int reloc,
unsigned HOST_WIDE_INT align)
{
const char *sname;
+
switch (categorize_decl_for_section (decl, reloc))
{
case SECCAT_TEXT:
@@ -6792,6 +6796,13 @@ default_elf_select_section (tree decl, int reloc,
sname = ".tdata";
break;
case SECCAT_BSS:
+ if (DECL_P (decl)
+ && lookup_attribute ("noinit", DECL_ATTRIBUTES (decl)) != NULL_TREE)
+ {
+ sname = ".noinit";
+ break;
+ }
+
if (bss_section)
return bss_section;
sname = ".bss";
diff --git a/gcc/vec.c b/gcc/vec.c
index cbd2db0..bac5eb7 100644
--- a/gcc/vec.c
+++ b/gcc/vec.c
@@ -192,21 +192,23 @@ dump_vec_loc_statistics (void)
ATTRIBUTE_NORETURN ATTRIBUTE_COLD
static void
qsort_chk_error (const void *p1, const void *p2, const void *p3,
- int (*cmp) (const void *, const void *))
+ sort_r_cmp_fn *cmp, void *data)
{
if (!p3)
{
- int r1 = cmp (p1, p2), r2 = cmp (p2, p1);
- error ("qsort comparator not anti-commutative: %d, %d", r1, r2);
+ int r1 = cmp (p1, p2, data), r2 = cmp (p2, p1, data);
+ error ("qsort comparator not anti-symmetric: %d, %d", r1, r2);
}
else if (p1 == p2)
{
- int r = cmp (p1, p3);
+ int r = cmp (p1, p3, data);
error ("qsort comparator non-negative on sorted output: %d", r);
}
else
{
- int r1 = cmp (p1, p2), r2 = cmp (p2, p3), r3 = cmp (p1, p3);
+ int r1 = cmp (p1, p2, data);
+ int r2 = cmp (p2, p3, data);
+ int r3 = cmp (p1, p3, data);
error ("qsort comparator not transitive: %d, %d, %d", r1, r2, r3);
}
internal_error ("qsort checking failed");
@@ -215,8 +217,7 @@ qsort_chk_error (const void *p1, const void *p2, const void *p3,
/* Verify anti-symmetry and transitivity for comparator CMP on sorted array
of N SIZE-sized elements pointed to by BASE. */
void
-qsort_chk (void *base, size_t n, size_t size,
- int (*cmp)(const void *, const void *))
+qsort_chk (void *base, size_t n, size_t size, sort_r_cmp_fn *cmp, void *data)
{
#if 0
#define LIM(n) (n)
@@ -225,9 +226,9 @@ qsort_chk (void *base, size_t n, size_t size,
#define LIM(n) ((n) <= 16 ? (n) : 12 + floor_log2 (n))
#endif
#define ELT(i) ((const char *) base + (i) * size)
-#define CMP(i, j) cmp (ELT (i), ELT (j))
-#define ERR2(i, j) qsort_chk_error (ELT (i), ELT (j), NULL, cmp)
-#define ERR3(i, j, k) qsort_chk_error (ELT (i), ELT (j), ELT (k), cmp)
+#define CMP(i, j) cmp (ELT (i), ELT (j), data)
+#define ERR2(i, j) qsort_chk_error (ELT (i), ELT (j), NULL, cmp, data)
+#define ERR3(i, j, k) qsort_chk_error (ELT (i), ELT (j), ELT (k), cmp, data)
size_t i1, i2, i, j;
/* This outer loop iterates over maximum spans [i1, i2) such that
elements within each span compare equal to each other. */
diff --git a/gcc/vec.h b/gcc/vec.h
index 2dbf307..091056b 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -593,7 +593,10 @@ public:
void unordered_remove (unsigned);
void block_remove (unsigned, unsigned);
void qsort (int (*) (const void *, const void *));
+ void sort (int (*) (const void *, const void *, void *), void *);
T *bsearch (const void *key, int (*compar)(const void *, const void *));
+ T *bsearch (const void *key,
+ int (*compar)(const void *, const void *, void *), void *);
unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
bool contains (const T &search) const;
static size_t embedded_size (unsigned);
@@ -1111,7 +1114,19 @@ inline void
vec<T, A, vl_embed>::qsort (int (*cmp) (const void *, const void *))
{
if (length () > 1)
- ::qsort (address (), length (), sizeof (T), cmp);
+ gcc_qsort (address (), length (), sizeof (T), cmp);
+}
+
+/* Sort the contents of this vector with qsort. CMP is the comparison
+ function to pass to qsort. */
+
+template<typename T, typename A>
+inline void
+vec<T, A, vl_embed>::sort (int (*cmp) (const void *, const void *, void *),
+ void *data)
+{
+ if (length () > 1)
+ gcc_sort_r (address (), length (), sizeof (T), cmp, data);
}
@@ -1149,6 +1164,41 @@ vec<T, A, vl_embed>::bsearch (const void *key,
return NULL;
}
+/* Search the contents of the sorted vector with a binary search.
+ CMP is the comparison function to pass to bsearch. */
+
+template<typename T, typename A>
+inline T *
+vec<T, A, vl_embed>::bsearch (const void *key,
+ int (*compar) (const void *, const void *,
+ void *), void *data)
+{
+ const void *base = this->address ();
+ size_t nmemb = this->length ();
+ size_t size = sizeof (T);
+ /* The following is a copy of glibc stdlib-bsearch.h. */
+ size_t l, u, idx;
+ const void *p;
+ int comparison;
+
+ l = 0;
+ u = nmemb;
+ while (l < u)
+ {
+ idx = (l + u) / 2;
+ p = (const void *) (((const char *) base) + (idx * size));
+ comparison = (*compar) (key, p, data);
+ if (comparison < 0)
+ u = idx;
+ else if (comparison > 0)
+ l = idx + 1;
+ else
+ return (T *)const_cast<void *>(p);
+ }
+
+ return NULL;
+}
+
/* Return true if SEARCH is an element of V. Note that this is O(N) in the
size of the vector and so should be used with care. */
@@ -1401,7 +1451,10 @@ public:
void unordered_remove (unsigned);
void block_remove (unsigned, unsigned);
void qsort (int (*) (const void *, const void *));
+ void sort (int (*) (const void *, const void *, void *), void *);
T *bsearch (const void *key, int (*compar)(const void *, const void *));
+ T *bsearch (const void *key,
+ int (*compar)(const void *, const void *, void *), void *);
unsigned lower_bound (T, bool (*)(const T &, const T &)) const;
bool contains (const T &search) const;
void reverse (void);
@@ -1898,6 +1951,18 @@ vec<T, va_heap, vl_ptr>::qsort (int (*cmp) (const void *, const void *))
m_vec->qsort (cmp);
}
+/* Sort the contents of this vector with qsort. CMP is the comparison
+ function to pass to qsort. */
+
+template<typename T>
+inline void
+vec<T, va_heap, vl_ptr>::sort (int (*cmp) (const void *, const void *,
+ void *), void *data)
+{
+ if (m_vec)
+ m_vec->sort (cmp, data);
+}
+
/* Search the contents of the sorted vector with a binary search.
CMP is the comparison function to pass to bsearch. */
@@ -1912,6 +1977,20 @@ vec<T, va_heap, vl_ptr>::bsearch (const void *key,
return NULL;
}
+/* Search the contents of the sorted vector with a binary search.
+ CMP is the comparison function to pass to bsearch. */
+
+template<typename T>
+inline T *
+vec<T, va_heap, vl_ptr>::bsearch (const void *key,
+ int (*cmp) (const void *, const void *,
+ void *), void *data)
+{
+ if (m_vec)
+ return m_vec->bsearch (key, cmp, data);
+ return NULL;
+}
+
/* Find and return the first position in which OBJ could be inserted
without changing the ordering of this vector. LESSTHAN is a
diff --git a/gcc/vector-builder.h b/gcc/vector-builder.h
index aac8a87..37911ac 100644
--- a/gcc/vector-builder.h
+++ b/gcc/vector-builder.h
@@ -45,8 +45,11 @@ along with GCC; see the file COPYING3. If not see
variable-length vectors. finalize () then canonicalizes the encoding
to a simpler form if possible.
- The derived class Derived provides this functionality for specific Ts.
- Derived needs to provide the following interface:
+ Shape is the type that specifies the number of elements in the vector
+ and (where relevant) the type of each element.
+
+ The derived class Derived provides the functionality of this class
+ for specific Ts. Derived needs to provide the following interface:
bool equal_p (T elt1, T elt2) const;
@@ -82,9 +85,30 @@ along with GCC; see the file COPYING3. If not see
Record that ELT2 is being elided, given that ELT1_PTR points to
the last encoded element for the containing pattern. This is
- again provided for TREE_OVERFLOW handling. */
+ again provided for TREE_OVERFLOW handling.
+
+ static poly_uint64 shape_nelts (Shape shape);
+
+ Return the number of elements in SHAPE.
+
+ The class provides additional functionality for the case in which
+ T can describe a vector constant as well as an individual element.
+ This functionality requires:
+
+ static poly_uint64 nelts_of (T x);
+
+ Return the number of elements in vector constant X.
-template<typename T, typename Derived>
+ static unsigned int npatterns_of (T x);
+
+ Return the number of patterns used to encode vector constant X.
+
+ static unsigned int nelts_per_pattern_of (T x);
+
+ Return the number of elements used to encode each pattern
+ in vector constant X. */
+
+template<typename T, typename Shape, typename Derived>
class vector_builder : public auto_vec<T, 32>
{
public:
@@ -101,8 +125,13 @@ public:
bool operator == (const Derived &) const;
bool operator != (const Derived &x) const { return !operator == (x); }
+ bool new_unary_operation (Shape, T, bool);
+ bool new_binary_operation (Shape, T, T, bool);
+
void finalize ();
+ static unsigned int binary_encoded_nelts (T, T);
+
protected:
void new_vector (poly_uint64, unsigned int, unsigned int);
void reshape (unsigned int, unsigned int);
@@ -121,16 +150,16 @@ private:
unsigned int m_nelts_per_pattern;
};
-template<typename T, typename Derived>
+template<typename T, typename Shape, typename Derived>
inline const Derived *
-vector_builder<T, Derived>::derived () const
+vector_builder<T, Shape, Derived>::derived () const
{
return static_cast<const Derived *> (this);
}
-template<typename T, typename Derived>
+template<typename T, typename Shape, typename Derived>
inline
-vector_builder<T, Derived>::vector_builder ()
+vector_builder<T, Shape, Derived>::vector_builder ()
: m_full_nelts (0),
m_npatterns (0),
m_nelts_per_pattern (0)
@@ -140,18 +169,18 @@ vector_builder<T, Derived>::vector_builder ()
starts with these explicitly-encoded elements and may contain additional
elided elements. */
-template<typename T, typename Derived>
+template<typename T, typename Shape, typename Derived>
inline unsigned int
-vector_builder<T, Derived>::encoded_nelts () const
+vector_builder<T, Shape, Derived>::encoded_nelts () const
{
return m_npatterns * m_nelts_per_pattern;
}
/* Return true if every element of the vector is explicitly encoded. */
-template<typename T, typename Derived>
+template<typename T, typename Shape, typename Derived>
inline bool
-vector_builder<T, Derived>::encoded_full_vector_p () const
+vector_builder<T, Shape, Derived>::encoded_full_vector_p () const
{
return known_eq (m_npatterns * m_nelts_per_pattern, m_full_nelts);
}
@@ -159,11 +188,11 @@ vector_builder<T, Derived>::encoded_full_vector_p () const
/* Start building a vector that has FULL_NELTS elements. Initially
encode it using NPATTERNS patterns with NELTS_PER_PATTERN each. */
-template<typename T, typename Derived>
+template<typename T, typename Shape, typename Derived>
void
-vector_builder<T, Derived>::new_vector (poly_uint64 full_nelts,
- unsigned int npatterns,
- unsigned int nelts_per_pattern)
+vector_builder<T, Shape, Derived>::new_vector (poly_uint64 full_nelts,
+ unsigned int npatterns,
+ unsigned int nelts_per_pattern)
{
m_full_nelts = full_nelts;
m_npatterns = npatterns;
@@ -175,9 +204,9 @@ vector_builder<T, Derived>::new_vector (poly_uint64 full_nelts,
/* Return true if this vector and OTHER have the same elements and
are encoded in the same way. */
-template<typename T, typename Derived>
+template<typename T, typename Shape, typename Derived>
bool
-vector_builder<T, Derived>::operator == (const Derived &other) const
+vector_builder<T, Shape, Derived>::operator == (const Derived &other) const
{
if (maybe_ne (m_full_nelts, other.m_full_nelts)
|| m_npatterns != other.m_npatterns
@@ -195,9 +224,9 @@ vector_builder<T, Derived>::operator == (const Derived &other) const
/* Return the value of vector element I, which might or might not be
encoded explicitly. */
-template<typename T, typename Derived>
+template<typename T, typename Shape, typename Derived>
T
-vector_builder<T, Derived>::elt (unsigned int i) const
+vector_builder<T, Shape, Derived>::elt (unsigned int i) const
{
/* First handle elements that are already present in the underlying
vector, regardless of whether they're part of the encoding or not. */
@@ -225,12 +254,118 @@ vector_builder<T, Derived>::elt (unsigned int i) const
derived ()->step (prev, final));
}
+/* Try to start building a new vector of shape SHAPE that holds the result of
+ a unary operation on vector constant VEC. ALLOW_STEPPED_P is true if the
+ operation can handle stepped encodings directly, without having to expand
+ the full sequence.
+
+ Return true if the operation is possible, which it always is when
+ ALLOW_STEPPED_P is true. Leave the builder unchanged otherwise. */
+
+template<typename T, typename Shape, typename Derived>
+bool
+vector_builder<T, Shape, Derived>::new_unary_operation (Shape shape, T vec,
+ bool allow_stepped_p)
+{
+ poly_uint64 full_nelts = Derived::shape_nelts (shape);
+ gcc_assert (known_eq (full_nelts, Derived::nelts_of (vec)));
+ unsigned int npatterns = Derived::npatterns_of (vec);
+ unsigned int nelts_per_pattern = Derived::nelts_per_pattern_of (vec);
+ if (!allow_stepped_p && nelts_per_pattern > 2)
+ {
+ if (!full_nelts.is_constant ())
+ return false;
+ npatterns = full_nelts.to_constant ();
+ nelts_per_pattern = 1;
+ }
+ derived ()->new_vector (shape, npatterns, nelts_per_pattern);
+ return true;
+}
+
+/* Try to start building a new vector of shape SHAPE that holds the result of
+ a binary operation on vector constants VEC1 and VEC2. ALLOW_STEPPED_P is
+ true if the operation can handle stepped encodings directly, without
+ having to expand the full sequence.
+
+ Return true if the operation is possible. Leave the builder unchanged
+ otherwise. */
+
+template<typename T, typename Shape, typename Derived>
+bool
+vector_builder<T, Shape, Derived>::new_binary_operation (Shape shape,
+ T vec1, T vec2,
+ bool allow_stepped_p)
+{
+ poly_uint64 full_nelts = Derived::shape_nelts (shape);
+ gcc_assert (known_eq (full_nelts, Derived::nelts_of (vec1))
+ && known_eq (full_nelts, Derived::nelts_of (vec2)));
+ /* Conceptually we split the patterns in VEC1 and VEC2 until we have
+ an equal number for both. Each split pattern requires the same
+ number of elements per pattern as the original. E.g. splitting:
+
+ { 1, 2, 3, ... }
+
+ into two gives:
+
+ { 1, 3, 5, ... }
+ { 2, 4, 6, ... }
+
+ while splitting:
+
+ { 1, 0, ... }
+
+ into two gives:
+
+ { 1, 0, ... }
+ { 0, 0, ... }. */
+ unsigned int npatterns
+ = least_common_multiple (Derived::npatterns_of (vec1),
+ Derived::npatterns_of (vec2));
+ unsigned int nelts_per_pattern
+ = MAX (Derived::nelts_per_pattern_of (vec1),
+ Derived::nelts_per_pattern_of (vec2));
+ if (!allow_stepped_p && nelts_per_pattern > 2)
+ {
+ if (!full_nelts.is_constant ())
+ return false;
+ npatterns = full_nelts.to_constant ();
+ nelts_per_pattern = 1;
+ }
+ derived ()->new_vector (shape, npatterns, nelts_per_pattern);
+ return true;
+}
+
+/* Return the number of elements that the caller needs to operate on in
+ order to handle a binary operation on vector constants VEC1 and VEC2.
+ This static function is used instead of new_binary_operation if the
+ result of the operation is not a constant vector. */
+
+template<typename T, typename Shape, typename Derived>
+unsigned int
+vector_builder<T, Shape, Derived>::binary_encoded_nelts (T vec1, T vec2)
+{
+ poly_uint64 nelts = Derived::nelts_of (vec1);
+ gcc_assert (known_eq (nelts, Derived::nelts_of (vec2)));
+ /* See new_binary_operation for details. */
+ unsigned int npatterns
+ = least_common_multiple (Derived::npatterns_of (vec1),
+ Derived::npatterns_of (vec2));
+ unsigned int nelts_per_pattern
+ = MAX (Derived::nelts_per_pattern_of (vec1),
+ Derived::nelts_per_pattern_of (vec2));
+ unsigned HOST_WIDE_INT const_nelts;
+ if (nelts.is_constant (&const_nelts))
+ return MIN (npatterns * nelts_per_pattern, const_nelts);
+ return npatterns * nelts_per_pattern;
+}
+
/* Return the number of leading duplicate elements in the range
[START:END:STEP]. The value is always at least 1. */
-template<typename T, typename Derived>
+template<typename T, typename Shape, typename Derived>
unsigned int
-vector_builder<T, Derived>::count_dups (int start, int end, int step) const
+vector_builder<T, Shape, Derived>::count_dups (int start, int end,
+ int step) const
{
gcc_assert ((end - start) % step == 0);
@@ -245,10 +380,10 @@ vector_builder<T, Derived>::count_dups (int start, int end, int step) const
/* Change the encoding to NPATTERNS patterns of NELTS_PER_PATTERN each,
but without changing the underlying vector. */
-template<typename T, typename Derived>
+template<typename T, typename Shape, typename Derived>
void
-vector_builder<T, Derived>::reshape (unsigned int npatterns,
- unsigned int nelts_per_pattern)
+vector_builder<T, Shape, Derived>::reshape (unsigned int npatterns,
+ unsigned int nelts_per_pattern)
{
unsigned int old_encoded_nelts = encoded_nelts ();
unsigned int new_encoded_nelts = npatterns * nelts_per_pattern;
@@ -268,11 +403,11 @@ vector_builder<T, Derived>::reshape (unsigned int npatterns,
/* Return true if elements [START, END) contain a repeating sequence of
STEP elements. */
-template<typename T, typename Derived>
+template<typename T, typename Shape, typename Derived>
bool
-vector_builder<T, Derived>::repeating_sequence_p (unsigned int start,
- unsigned int end,
- unsigned int step)
+vector_builder<T, Shape, Derived>::repeating_sequence_p (unsigned int start,
+ unsigned int end,
+ unsigned int step)
{
for (unsigned int i = start; i < end - step; ++i)
if (!derived ()->equal_p ((*this)[i], (*this)[i + step]))
@@ -283,11 +418,11 @@ vector_builder<T, Derived>::repeating_sequence_p (unsigned int start,
/* Return true if elements [START, END) contain STEP interleaved linear
series. */
-template<typename T, typename Derived>
+template<typename T, typename Shape, typename Derived>
bool
-vector_builder<T, Derived>::stepped_sequence_p (unsigned int start,
- unsigned int end,
- unsigned int step)
+vector_builder<T, Shape, Derived>::stepped_sequence_p (unsigned int start,
+ unsigned int end,
+ unsigned int step)
{
if (!derived ()->allow_steps_p ())
return false;
@@ -316,9 +451,9 @@ vector_builder<T, Derived>::stepped_sequence_p (unsigned int start,
/* Try to change the number of encoded patterns to NPATTERNS, returning
true on success. */
-template<typename T, typename Derived>
+template<typename T, typename Shape, typename Derived>
bool
-vector_builder<T, Derived>::try_npatterns (unsigned int npatterns)
+vector_builder<T, Shape, Derived>::try_npatterns (unsigned int npatterns)
{
if (m_nelts_per_pattern == 1)
{
@@ -369,9 +504,9 @@ vector_builder<T, Derived>::try_npatterns (unsigned int npatterns)
/* Replace the current encoding with the canonical form. */
-template<typename T, typename Derived>
+template<typename T, typename Shape, typename Derived>
void
-vector_builder<T, Derived>::finalize ()
+vector_builder<T, Shape, Derived>::finalize ()
{
/* The encoding requires the same number of elements to come from each
pattern. */
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 9a4aea0..6f9a361 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -64,45 +64,41 @@ static inline void
set_value_range_to_truthvalue (value_range *vr, tree type)
{
if (TYPE_PRECISION (type) == 1)
- vr->set_varying ();
+ vr->set_varying (type);
else
vr->update (VR_RANGE, build_int_cst (type, 0), build_int_cst (type, 1));
}
-
-/* Return value range information for VAR.
-
- If we have no values ranges recorded (ie, VRP is not running), then
- return NULL. Otherwise create an empty range if none existed for VAR. */
+/* Return the lattice entry for VAR or NULL if it doesn't exist or cannot
+ be initialized. */
value_range *
-vr_values::get_value_range (const_tree var)
+vr_values::get_lattice_entry (const_tree var)
{
- static const value_range vr_const_varying (VR_VARYING, NULL, NULL);
value_range *vr;
tree sym;
unsigned ver = SSA_NAME_VERSION (var);
- /* If we have no recorded ranges, then return NULL. */
- if (! vr_value)
- return NULL;
-
- /* If we query the range for a new SSA name return an unmodifiable VARYING.
- We should get here at most from the substitute-and-fold stage which
+ /* If we query the entry for a new SSA name avoid reallocating the lattice
+ since we should get here at most from the substitute-and-fold stage which
will never try to change values. */
if (ver >= num_vr_values)
- return CONST_CAST (value_range *, &vr_const_varying);
+ return NULL;
vr = vr_value[ver];
if (vr)
return vr;
- /* After propagation finished do not allocate new value-ranges. */
- if (values_propagated)
- return CONST_CAST (value_range *, &vr_const_varying);
-
/* Create a default value range. */
vr_value[ver] = vr = vrp_value_range_pool.allocate ();
+
+ /* After propagation finished return varying. */
+ if (values_propagated)
+ {
+ vr->set_varying (TREE_TYPE (var));
+ return vr;
+ }
+
vr->set_undefined ();
/* If VAR is a default definition of a parameter, the variable can
@@ -126,10 +122,10 @@ vr_values::get_value_range (const_tree var)
{
get_range_info (var, *vr);
if (vr->undefined_p ())
- vr->set_varying ();
+ vr->set_varying (TREE_TYPE (sym));
}
else
- vr->set_varying ();
+ vr->set_varying (TREE_TYPE (sym));
}
else if (TREE_CODE (sym) == RESULT_DECL
&& DECL_BY_REFERENCE (sym))
@@ -142,6 +138,47 @@ vr_values::get_value_range (const_tree var)
return vr;
}
+/* Return value range information for VAR.
+
+ If we have no values ranges recorded (ie, VRP is not running), then
+ return NULL. Otherwise create an empty range if none existed for VAR. */
+
+const value_range *
+vr_values::get_value_range (const_tree var)
+{
+ /* If we have no recorded ranges, then return NULL. */
+ if (!vr_value)
+ return NULL;
+
+ value_range *vr = get_lattice_entry (var);
+
+ /* Reallocate the lattice if needed. */
+ if (!vr)
+ {
+ unsigned int old_sz = num_vr_values;
+ num_vr_values = num_ssa_names + num_ssa_names / 10;
+ vr_value = XRESIZEVEC (value_range *, vr_value, num_vr_values);
+ for ( ; old_sz < num_vr_values; old_sz++)
+ vr_value [old_sz] = NULL;
+
+ /* Now that the lattice has been resized, we should never fail. */
+ vr = get_lattice_entry (var);
+ gcc_assert (vr);
+ }
+
+ return vr;
+}
+
+/* Set the lattice entry for DEF to VARYING. */
+
+void
+vr_values::set_def_to_varying (const_tree def)
+{
+ value_range *vr = get_lattice_entry (def);
+ if (vr)
+ vr->set_varying (TREE_TYPE (def));
+}
+
/* Set value-ranges of all SSA names defined by STMT to varying. */
void
@@ -150,12 +187,7 @@ vr_values::set_defs_to_varying (gimple *stmt)
ssa_op_iter i;
tree def;
FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
- {
- value_range *vr = get_value_range (def);
- /* Avoid writing to vr_const_varying get_value_range may return. */
- if (!vr->varying_p ())
- vr->set_varying ();
- }
+ set_def_to_varying (def);
}
/* Update the value range and equivalence set for variable VAR to
@@ -184,8 +216,12 @@ vr_values::update_value_range (const_tree var, value_range *new_vr)
new_vr->intersect (&nr);
}
- /* Update the value range, if necessary. */
- old_vr = get_value_range (var);
+ /* Update the value range, if necessary. If we cannot allocate a lattice
+ entry for VAR keep it at VARYING. This happens when DOM feeds us stmts
+ with SSA names allocated after setting up the lattice. */
+ old_vr = get_lattice_entry (var);
+ if (!old_vr)
+ return false;
is_new = !old_vr->equal_p (*new_vr, /*ignore_equivs=*/false);
if (is_new)
@@ -198,13 +234,13 @@ vr_values::update_value_range (const_tree var, value_range *new_vr)
called, if we are anyway, keep it VARYING. */
if (old_vr->varying_p ())
{
- new_vr->set_varying ();
+ new_vr->set_varying (new_vr->type ());
is_new = false;
}
else if (new_vr->undefined_p ())
{
- old_vr->set_varying ();
- new_vr->set_varying ();
+ old_vr->set_varying (TREE_TYPE (var));
+ new_vr->set_varying (TREE_TYPE (var));
return true;
}
else
@@ -339,7 +375,7 @@ vr_values::vrp_stmt_computes_nonzero (gimple *stmt)
|| (flag_delete_null_pointer_checks
&& !TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr))))
{
- value_range *vr = get_value_range (TREE_OPERAND (base, 0));
+ const value_range *vr = get_value_range (TREE_OPERAND (base, 0));
if (!range_includes_zero_p (vr))
return true;
}
@@ -398,7 +434,7 @@ vr_values::op_with_constant_singleton_value_range (tree op)
bool
vr_values::op_with_boolean_value_range_p (tree op)
{
- value_range *vr;
+ const value_range *vr;
if (TYPE_PRECISION (TREE_TYPE (op)) == 1)
return true;
@@ -426,7 +462,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
value_range *vr_p)
{
tree min, max, type;
- value_range *limit_vr;
+ const value_range *limit_vr;
type = TREE_TYPE (var);
/* For pointer arithmetic, we only keep track of pointer equality
@@ -435,7 +471,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
if ((POINTER_TYPE_P (type) && cond_code != NE_EXPR && cond_code != EQ_EXPR)
|| limit == var)
{
- vr_p->set_varying ();
+ vr_p->set_varying (type);
return;
}
@@ -500,9 +536,9 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
vice-versa. Use set_and_canonicalize which does this for
us. */
if (cond_code == LE_EXPR)
- vr_p->set_and_canonicalize (VR_RANGE, min, max, vr_p->equiv ());
+ vr_p->set (VR_RANGE, min, max, vr_p->equiv ());
else if (cond_code == GT_EXPR)
- vr_p->set_and_canonicalize (VR_ANTI_RANGE, min, max, vr_p->equiv ());
+ vr_p->set (VR_ANTI_RANGE, min, max, vr_p->equiv ());
else
gcc_unreachable ();
}
@@ -574,7 +610,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
&& vrp_val_is_max (max))
min = max = limit;
- vr_p->set_and_canonicalize (VR_ANTI_RANGE, min, max, vr_p->equiv ());
+ vr_p->set (VR_ANTI_RANGE, min, max, vr_p->equiv ());
}
else if (cond_code == LE_EXPR || cond_code == LT_EXPR)
{
@@ -595,7 +631,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
all should be optimized away above us. */
if (cond_code == LT_EXPR
&& compare_values (max, min) == 0)
- vr_p->set_varying ();
+ vr_p->set_varying (TREE_TYPE (min));
else
{
/* For LT_EXPR, we create the range [MIN, MAX - 1]. */
@@ -635,7 +671,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
all should be optimized away above us. */
if (cond_code == GT_EXPR
&& compare_values (min, max) == 0)
- vr_p->set_varying ();
+ vr_p->set_varying (TREE_TYPE (min));
else
{
/* For GT_EXPR, we create the range [MIN + 1, MAX]. */
@@ -715,7 +751,7 @@ vr_values::extract_range_from_assert (value_range *vr_p, tree expr)
void
vr_values::extract_range_from_ssa_name (value_range *vr, tree var)
{
- value_range *var_vr = get_value_range (var);
+ const value_range *var_vr = get_value_range (var);
if (!var_vr->varying_p ())
vr->deep_copy (var_vr);
@@ -743,14 +779,14 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
else if (is_gimple_min_invariant (op0))
vr0.set (op0);
else
- vr0.set_varying ();
+ vr0.set_varying (TREE_TYPE (op0));
if (TREE_CODE (op1) == SSA_NAME)
vr1 = *(get_value_range (op1));
else if (is_gimple_min_invariant (op1))
vr1.set (op1);
else
- vr1.set_varying ();
+ vr1.set_varying (TREE_TYPE (op1));
/* If one argument is varying, we can sometimes still deduce a
range for the output: any + [3, +INF] is in [MIN+3, +INF]. */
@@ -891,7 +927,7 @@ vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code,
else if (is_gimple_min_invariant (op0))
vr0.set (op0);
else
- vr0.set_varying ();
+ vr0.set_varying (type);
::extract_range_from_unary_expr (vr, code, type, &vr0, TREE_TYPE (op0));
}
@@ -907,23 +943,23 @@ vr_values::extract_range_from_cond_expr (value_range *vr, gassign *stmt)
a new value range with the operand to simplify processing. */
tree op0 = gimple_assign_rhs2 (stmt);
value_range tem0;
- value_range *vr0 = &tem0;
+ const value_range *vr0 = &tem0;
if (TREE_CODE (op0) == SSA_NAME)
vr0 = get_value_range (op0);
else if (is_gimple_min_invariant (op0))
tem0.set (op0);
else
- tem0.set_varying ();
+ tem0.set_varying (TREE_TYPE (op0));
tree op1 = gimple_assign_rhs3 (stmt);
value_range tem1;
- value_range *vr1 = &tem1;
+ const value_range *vr1 = &tem1;
if (TREE_CODE (op1) == SSA_NAME)
vr1 = get_value_range (op1);
else if (is_gimple_min_invariant (op1))
tem1.set (op1);
else
- tem1.set_varying ();
+ tem1.set_varying (TREE_TYPE (op1));
/* The resulting value range is the union of the operand ranges */
vr->deep_copy (vr0);
@@ -975,14 +1011,14 @@ vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type,
else if (TREE_CODE (op0) == INTEGER_CST)
vr0.set (op0);
else
- vr0.set_varying ();
+ vr0.set_varying (TREE_TYPE (op0));
if (TREE_CODE (op1) == SSA_NAME)
vr1 = *get_value_range (op1);
else if (TREE_CODE (op1) == INTEGER_CST)
vr1.set (op1);
else
- vr1.set_varying ();
+ vr1.set_varying (TREE_TYPE (op1));
tree vr0min = vr0.min (), vr0max = vr0.max ();
tree vr1min = vr1.min (), vr1max = vr1.max ();
@@ -1113,7 +1149,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
maxi = prec;
if (TREE_CODE (arg) == SSA_NAME)
{
- value_range *vr0 = get_value_range (arg);
+ const value_range *vr0 = get_value_range (arg);
/* If arg is non-zero, then ffs or popcount are non-zero. */
if (range_includes_zero_p (vr0) == 0)
mini = 1;
@@ -1151,7 +1187,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
mini = -2;
if (TREE_CODE (arg) == SSA_NAME)
{
- value_range *vr0 = get_value_range (arg);
+ const value_range *vr0 = get_value_range (arg);
/* From clz of VR_RANGE minimum we can compute
result maximum. */
if (vr0->kind () == VR_RANGE
@@ -1208,7 +1244,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
}
if (TREE_CODE (arg) == SSA_NAME)
{
- value_range *vr0 = get_value_range (arg);
+ const value_range *vr0 = get_value_range (arg);
/* If arg is non-zero, then use [0, prec - 1]. */
if ((vr0->kind () == VR_RANGE
&& integer_nonzerop (vr0->min ()))
@@ -1310,7 +1346,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
if (vr->kind () == VR_RANGE
&& (vr->min () == vr->max ()
|| operand_equal_p (vr->min (), vr->max (), 0)))
- vr->set_varying ();
+ vr->set_varying (vr->type ());
return;
}
}
@@ -1366,7 +1402,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
vr->set (build_int_cst (type, ovf));
else if (TYPE_PRECISION (type) == 1
&& !TYPE_UNSIGNED (type))
- vr->set_varying ();
+ vr->set_varying (type);
else
vr->set (VR_RANGE, build_int_cst (type, 0),
build_int_cst (type, 1));
@@ -1411,7 +1447,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
vr->equiv_clear ();
}
else
- vr->set_varying ();
+ vr->set_varying (type);
}
@@ -1447,7 +1483,7 @@ vr_values::extract_range_from_assignment (value_range *vr, gassign *stmt)
&& is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
vr->set (gimple_assign_rhs1 (stmt));
else
- vr->set_varying ();
+ vr->set_varying (TREE_TYPE (gimple_assign_lhs (stmt)));
if (vr->varying_p ())
extract_range_basic (vr, stmt);
@@ -1468,8 +1504,8 @@ vr_values::extract_range_from_assignment (value_range *vr, gassign *stmt)
static tree
-compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
- bool *strict_overflow_p)
+compare_ranges (enum tree_code comp, const value_range *vr0,
+ const value_range *vr1, bool *strict_overflow_p)
{
/* VARYING or UNDEFINED ranges cannot be compared. */
if (vr0->varying_p ()
@@ -1496,12 +1532,8 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
/* Equality can be computed only between a range and an
anti-range. ~[VAL1, VAL2] == [VAL1, VAL2] is always false. */
if (vr0->kind () == VR_RANGE)
- {
- /* To simplify processing, make VR0 the anti-range. */
- value_range *tmp = vr0;
- vr0 = vr1;
- vr1 = tmp;
- }
+ /* To simplify processing, make VR0 the anti-range. */
+ std::swap (vr0, vr1);
gcc_assert (comp == NE_EXPR || comp == EQ_EXPR);
@@ -1607,7 +1639,7 @@ compare_ranges (enum tree_code comp, value_range *vr0, value_range *vr1,
assumed signed overflow is undefined. */
static tree
-compare_range_with_value (enum tree_code comp, value_range *vr, tree val,
+compare_range_with_value (enum tree_code comp, const value_range *vr, tree val,
bool *strict_overflow_p)
{
if (vr->varying_p () || vr->undefined_p ())
@@ -1920,7 +1952,7 @@ vr_values::dump_all_value_ranges (FILE *file)
vr_values::vr_values () : vrp_value_range_pool ("Tree VRP value ranges")
{
values_propagated = false;
- num_vr_values = num_ssa_names;
+ num_vr_values = num_ssa_names * 2;
vr_value = XCNEWVEC (value_range *, num_vr_values);
vr_phi_edge_counts = XCNEWVEC (int, num_ssa_names);
bitmap_obstack_initialize (&vrp_equiv_obstack);
@@ -1961,7 +1993,7 @@ vrp_valueize (tree name)
{
if (TREE_CODE (name) == SSA_NAME)
{
- value_range *vr = x_vr_values->get_value_range (name);
+ const value_range *vr = x_vr_values->get_value_range (name);
if (vr->kind () == VR_RANGE
&& (TREE_CODE (vr->min ()) == SSA_NAME
|| is_gimple_min_invariant (vr->min ()))
@@ -1986,7 +2018,7 @@ vrp_valueize_1 (tree name)
if (!gimple_nop_p (def_stmt)
&& prop_simulate_again_p (def_stmt))
return NULL_TREE;
- value_range *vr = x_vr_values->get_value_range (name);
+ const value_range *vr = x_vr_values->get_value_range (name);
tree singleton;
if (vr->singleton_p (&singleton))
return singleton;
@@ -2064,11 +2096,11 @@ vr_values::vrp_visit_assignment_or_call (gimple *stmt, tree *output_p,
or a symbolic range containing the SSA_NAME only if the value range
is varying or undefined. Uses TEM as storage for the alternate range. */
-value_range *
+const value_range *
vr_values::get_vr_for_comparison (int i, value_range *tem)
{
/* Shallow-copy equiv bitmap. */
- value_range *vr = get_value_range (ssa_name (i));
+ const value_range *vr = get_value_range (ssa_name (i));
/* If name N_i does not have a valid range, use N_i as its own
range. This allows us to compare against names that may
@@ -2097,7 +2129,8 @@ vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val,
tree retval, t;
int used_strict_overflow;
bool sop;
- value_range *equiv_vr, tem_vr;
+ const value_range *equiv_vr;
+ value_range tem_vr;
/* Get the set of equivalences for VAR. */
e = get_value_range (var)->equiv ();
@@ -2233,7 +2266,7 @@ vr_values::compare_names (enum tree_code comp, tree n1, tree n2,
continue;
value_range tem_vr1;
- value_range *vr1 = get_vr_for_comparison (i1, &tem_vr1);
+ const value_range *vr1 = get_vr_for_comparison (i1, &tem_vr1);
t = retval = NULL_TREE;
EXECUTE_IF_SET_IN_BITMAP (e2, 0, i2, bi2)
@@ -2244,7 +2277,7 @@ vr_values::compare_names (enum tree_code comp, tree n1, tree n2,
bool sop = false;
value_range tem_vr2;
- value_range *vr2 = get_vr_for_comparison (i2, &tem_vr2);
+ const value_range *vr2 = get_vr_for_comparison (i2, &tem_vr2);
t = compare_ranges (comp, vr1, vr2, &sop);
if (t)
@@ -2293,7 +2326,7 @@ tree
vr_values::vrp_evaluate_conditional_warnv_with_ops_using_ranges
(enum tree_code code, tree op0, tree op1, bool * strict_overflow_p)
{
- value_range *vr0, *vr1;
+ const value_range *vr0, *vr1;
vr0 = (TREE_CODE (op0) == SSA_NAME) ? get_value_range (op0) : NULL;
vr1 = (TREE_CODE (op1) == SSA_NAME) ? get_value_range (op1) : NULL;
@@ -2373,7 +2406,7 @@ vr_values::vrp_evaluate_conditional_warnv_with_ops (enum tree_code code,
}
else
gcc_unreachable ();
- value_range *vr0 = get_value_range (op0);
+ const value_range *vr0 = get_value_range (op0);
/* If vro, the range for OP0 to pass the overflow test, has
no intersection with *vr0, OP0's known range, then the
overflow test can't pass, so return the node for false.
@@ -2479,7 +2512,7 @@ vr_values::vrp_evaluate_conditional (tree_code code, tree op0,
always fold regardless of the value of OP0. If -Wtype-limits
was specified, emit a warning. */
tree type = TREE_TYPE (op0);
- value_range *vr0 = get_value_range (op0);
+ const value_range *vr0 = get_value_range (op0);
if (vr0->kind () == VR_RANGE
&& INTEGRAL_TYPE_P (type)
@@ -2605,7 +2638,7 @@ vr_values::vrp_visit_cond_stmt (gcond *stmt, edge *taken_edge_p)
Returns true if the default label is not needed. */
static bool
-find_case_label_ranges (gswitch *stmt, value_range *vr, size_t *min_idx1,
+find_case_label_ranges (gswitch *stmt, const value_range *vr, size_t *min_idx1,
size_t *max_idx1, size_t *min_idx2,
size_t *max_idx2)
{
@@ -2685,7 +2718,7 @@ void
vr_values::vrp_visit_switch_stmt (gswitch *stmt, edge *taken_edge_p)
{
tree op, val;
- value_range *vr;
+ const value_range *vr;
size_t i = 0, j = 0, k, l;
bool take_default;
@@ -2803,7 +2836,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
{
size_t i;
tree lhs = PHI_RESULT (phi);
- value_range *lhs_vr = get_value_range (lhs);
+ const value_range *lhs_vr = get_value_range (lhs);
bool first = true;
int edges, old_edges;
class loop *l;
@@ -2832,7 +2865,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
{
tree arg = PHI_ARG_DEF (phi, i);
value_range vr_arg_tem;
- value_range *vr_arg = &vr_arg_tem;
+ const value_range *vr_arg = &vr_arg_tem;
++edges;
@@ -2845,7 +2878,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
&& e->flags & EDGE_DFS_BACK)
may_simulate_backedge_again = true;
- value_range *vr_arg_ = get_value_range (arg);
+ const value_range *vr_arg_ = get_value_range (arg);
/* Do not allow equivalences or symbolic ranges to leak in from
backedges. That creates invalid equivalencies.
See PR53465 and PR54767. */
@@ -2856,7 +2889,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
vr_arg_tem.set (vr_arg_->kind (), vr_arg_->min (),
vr_arg_->max (), NULL);
if (vr_arg_tem.symbolic_p ())
- vr_arg_tem.set_varying ();
+ vr_arg_tem.set_varying (TREE_TYPE (arg));
}
else
vr_arg = vr_arg_;
@@ -2978,7 +3011,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
goto update_range;
varying:
- vr_result->set_varying ();
+ vr_result->set_varying (TREE_TYPE (lhs));
scev_check:
/* If this is a loop PHI node SCEV may known more about its value-range.
@@ -2999,7 +3032,7 @@ infinite_check:
|| compare_values (vr_result->min (), vr_result->max ()) > 0))
;
else
- vr_result->set_varying ();
+ vr_result->set_varying (TREE_TYPE (lhs));
/* If the new range is different than the previous value, keep
iterating. */
@@ -3096,7 +3129,7 @@ vr_values::simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi,
tree op1 = gimple_assign_rhs2 (stmt);
tree op0min = NULL_TREE, op0max = NULL_TREE;
tree op1min = op1;
- value_range *vr = NULL;
+ const value_range *vr = NULL;
if (TREE_CODE (op0) == INTEGER_CST)
{
@@ -3116,7 +3149,7 @@ vr_values::simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi,
if (rhs_code == TRUNC_MOD_EXPR
&& TREE_CODE (op1) == SSA_NAME)
{
- value_range *vr1 = get_value_range (op1);
+ const value_range *vr1 = get_value_range (op1);
if (range_int_cst_p (vr1))
op1min = vr1->min ();
}
@@ -3263,7 +3296,7 @@ bool
vr_values::simplify_abs_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
{
tree op = gimple_assign_rhs1 (stmt);
- value_range *vr = get_value_range (op);
+ const value_range *vr = get_value_range (op);
if (vr)
{
@@ -3401,7 +3434,7 @@ vr_values::simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi,
static tree
test_for_singularity (enum tree_code cond_code, tree op0,
- tree op1, value_range *vr)
+ tree op1, const value_range *vr)
{
tree min = NULL;
tree max = NULL;
@@ -3459,7 +3492,8 @@ test_for_singularity (enum tree_code cond_code, tree op0,
by PRECISION and UNSIGNED_P. */
static bool
-range_fits_type_p (value_range *vr, unsigned dest_precision, signop dest_sgn)
+range_fits_type_p (const value_range *vr,
+ unsigned dest_precision, signop dest_sgn)
{
tree src_type;
unsigned src_precision;
@@ -3523,7 +3557,7 @@ vr_values::simplify_cond_using_ranges_1 (gcond *stmt)
&& INTEGRAL_TYPE_P (TREE_TYPE (op0))
&& is_gimple_min_invariant (op1))
{
- value_range *vr = get_value_range (op0);
+ const value_range *vr = get_value_range (op0);
/* If we have range information for OP0, then we might be
able to simplify this conditional. */
@@ -3626,7 +3660,7 @@ vr_values::simplify_cond_using_ranges_2 (gcond *stmt)
&& !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)
&& desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0)))
{
- value_range *vr = get_value_range (innerop);
+ const value_range *vr = get_value_range (innerop);
if (range_int_cst_p (vr)
&& range_fits_type_p (vr,
@@ -3656,7 +3690,7 @@ bool
vr_values::simplify_switch_using_ranges (gswitch *stmt)
{
tree op = gimple_switch_index (stmt);
- value_range *vr = NULL;
+ const value_range *vr = NULL;
bool take_default;
edge e;
edge_iterator ei;
@@ -3956,7 +3990,7 @@ vr_values::simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi,
gimple *stmt)
{
tree rhs1 = gimple_assign_rhs1 (stmt);
- value_range *vr = get_value_range (rhs1);
+ const value_range *vr = get_value_range (rhs1);
scalar_float_mode fltmode
= SCALAR_FLOAT_TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt)));
scalar_int_mode mode;
@@ -4119,7 +4153,7 @@ vr_values::simplify_internal_call_using_ranges (gimple_stmt_iterator *gsi,
bool
vr_values::two_valued_val_range_p (tree var, tree *a, tree *b)
{
- value_range *vr = get_value_range (var);
+ const value_range *vr = get_value_range (var);
if (vr->varying_p ()
|| vr->undefined_p ()
|| TREE_CODE (vr->min ()) != INTEGER_CST
@@ -4295,6 +4329,8 @@ vr_values::simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
return false;
}
+/* Set the lattice entry for VAR to VR. */
+
void
vr_values::set_vr_value (tree var, value_range *vr)
{
@@ -4303,3 +4339,13 @@ vr_values::set_vr_value (tree var, value_range *vr)
vr_value[SSA_NAME_VERSION (var)] = vr;
}
+/* Swap the lattice entry for VAR with VR and return the old entry. */
+
+value_range *
+vr_values::swap_vr_value (tree var, value_range *vr)
+{
+ if (SSA_NAME_VERSION (var) >= num_vr_values)
+ return NULL;
+ std::swap (vr_value[SSA_NAME_VERSION (var)], vr);
+ return vr;
+}
diff --git a/gcc/vr-values.h b/gcc/vr-values.h
index 3856da1..ec65de3 100644
--- a/gcc/vr-values.h
+++ b/gcc/vr-values.h
@@ -40,9 +40,11 @@ class vr_values
vr_values (void);
~vr_values (void);
- value_range *get_value_range (const_tree);
-
+ const value_range *get_value_range (const_tree);
void set_vr_value (tree, value_range *);
+ value_range *swap_vr_value (tree, value_range *);
+
+ void set_def_to_varying (const_tree);
void set_defs_to_varying (gimple *);
bool update_value_range (const_tree, value_range *);
tree op_with_constant_singleton_value_range (tree);
@@ -67,15 +69,18 @@ class vr_values
/* Allocate a new value_range object. */
value_range *allocate_value_range (void)
{ return vrp_value_range_pool.allocate (); }
+ void free_value_range (value_range *vr)
+ { vrp_value_range_pool.remove (vr); }
/* */
void cleanup_edges_and_switches (void);
private:
+ value_range *get_lattice_entry (const_tree);
bool vrp_stmt_computes_nonzero (gimple *);
bool op_with_boolean_value_range_p (tree);
bool check_for_binary_op_overflow (enum tree_code, tree, tree, tree, bool *);
- value_range *get_vr_for_comparison (int, value_range *);
+ const value_range *get_vr_for_comparison (int, value_range *);
tree compare_name_with_value (enum tree_code, tree, tree, bool *, bool);
tree compare_names (enum tree_code, tree, tree, bool *);
bool two_valued_val_range_p (tree, tree *, tree *);
diff --git a/gcc/wide-int.h b/gcc/wide-int.h
index 6c816cc..862079a 100644
--- a/gcc/wide-int.h
+++ b/gcc/wide-int.h
@@ -730,6 +730,7 @@ public:
/* Public accessors for the interior of a wide int. */
HOST_WIDE_INT sign_mask () const;
HOST_WIDE_INT elt (unsigned int) const;
+ HOST_WIDE_INT sext_elt (unsigned int) const;
unsigned HOST_WIDE_INT ulow () const;
unsigned HOST_WIDE_INT uhigh () const;
HOST_WIDE_INT slow () const;
@@ -909,6 +910,23 @@ generic_wide_int <storage>::elt (unsigned int i) const
return this->get_val ()[i];
}
+/* Like elt, but sign-extend beyond the upper bit, instead of returning
+ the raw encoding. */
+template <typename storage>
+inline HOST_WIDE_INT
+generic_wide_int <storage>::sext_elt (unsigned int i) const
+{
+ HOST_WIDE_INT elt_i = elt (i);
+ if (!is_sign_extended)
+ {
+ unsigned int precision = this->get_precision ();
+ unsigned int lsb = i * HOST_BITS_PER_WIDE_INT;
+ if (precision - lsb < HOST_BITS_PER_WIDE_INT)
+ elt_i = sext_hwi (elt_i, precision - lsb);
+ }
+ return elt_i;
+}
+
template <typename storage>
template <typename T>
inline generic_wide_int <storage> &
diff --git a/include/ChangeLog b/include/ChangeLog
index a4f3fe5..83bd789 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2019-08-08 Martin Liska <mliska@suse.cz>
+
+ PR bootstrap/91352
+ * libiberty.h (is_valid_fd): New function.
+
2019-07-18 Eduard-Mihai Burtescu <eddyb@lyken.rs>
* demangle.h (rust_is_mangled): Move to libiberty/rust-demangle.h.
diff --git a/include/libiberty.h b/include/libiberty.h
index 635519e..71192a2 100644
--- a/include/libiberty.h
+++ b/include/libiberty.h
@@ -137,6 +137,10 @@ extern const char *unix_lbasename (const char *) ATTRIBUTE_RETURNS_NONNULL ATTRI
extern char *lrealpath (const char *);
+/* Return true when FD file descriptor exists. */
+
+extern int is_valid_fd (int fd);
+
/* Concatenate an arbitrary number of strings. You must pass NULL as
the last argument of this function, to terminate the list of
strings. Allocates memory using xmalloc. */
diff --git a/libcpp/po/ChangeLog b/libcpp/po/ChangeLog
index 96afffc..7dea118 100644
--- a/libcpp/po/ChangeLog
+++ b/libcpp/po/ChangeLog
@@ -1,3 +1,7 @@
+2019-08-09 Joseph Myers <joseph@codesourcery.com>
+
+ * zh_TW.po: Update.
+
2019-03-08 Joseph Myers <joseph@codesourcery.com>
* sv.po: Update.
diff --git a/libcpp/po/zh_TW.po b/libcpp/po/zh_TW.po
index e6dc626..ad7decc 100644
--- a/libcpp/po/zh_TW.po
+++ b/libcpp/po/zh_TW.po
@@ -6,11 +6,11 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: cpplib 5.2.0\n"
+"Project-Id-Version: cpplib 9.1-b20190203\n"
"Report-Msgid-Bugs-To: https://gcc.gnu.org/bugs/\n"
"POT-Creation-Date: 2019-02-01 23:01+0000\n"
-"PO-Revision-Date: 2015-10-08 13:27+0800\n"
-"Last-Translator: Wei-Lun Chao <bluebat@member.fsf.org>\n"
+"PO-Revision-Date: 2019-07-10 19:02+0800\n"
+"Last-Translator: pan93412 <pan93412@gmail.com>\n"
"Language-Team: Chinese (traditional) <zh-l10n@linux.org.tw>\n"
"Language: zh_TW\n"
"MIME-Version: 1.0\n"
@@ -18,6 +18,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"X-Bugs: Report translation errors to the Language-Team address.\n"
"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Poedit 2.2.1\n"
#: charset.c:674
#, c-format
@@ -137,7 +138,7 @@ msgstr "將逸出序列轉換到執行字元集"
#: charset.c:1614
msgid "missing open quote"
-msgstr ""
+msgstr "遺失左引號"
#: charset.c:1829 charset.c:1893
msgid "character constant too long for its type"
@@ -278,7 +279,7 @@ msgstr "# 後的「%s」不是一個正整數"
#: directives.c:1087
#, c-format
msgid "file \"%s\" linemarker ignored due to incorrect nesting"
-msgstr ""
+msgstr "因為巢狀項目不正確,因此忽略了「%s」檔案的行標記 (linemarker)"
#: directives.c:1147 directives.c:1149 directives.c:1151 directives.c:1737
#, c-format
@@ -439,10 +440,8 @@ msgid "invalid prefix \"0b\" for floating constant"
msgstr "無效的浮點常數前綴「0b」"
#: expr.c:666
-#, fuzzy
-#| msgid "use of C++11 hexadecimal floating constant"
msgid "use of C++17 hexadecimal floating constant"
-msgstr "使用 C++11 式的十六進位浮點常數"
+msgstr "使用 C++17 式的十六進位浮點常數"
#: expr.c:669
msgid "use of C99 hexadecimal floating constant"
@@ -534,10 +533,9 @@ msgid "imaginary number in preprocessor expression"
msgstr "預先處理運算式中出現虛數"
#: expr.c:1173
-#, fuzzy, c-format
-#| msgid "\"%s\" is not defined"
+#, c-format
msgid "\"%s\" is not defined, evaluates to 0"
-msgstr "「%s」未定義"
+msgstr "「%s」未定義,判斷值為 0"
#: expr.c:1186
msgid "assertions are a GCC extension"
@@ -697,13 +695,11 @@ msgstr "「%.*s」不在 NFC 中"
#: lex.c:1365
msgid "__VA_OPT__ is not available until C++2a"
-msgstr ""
+msgstr "__VA_OPT__ 在 C++2a 之前皆不支援"
#: lex.c:1372
-#, fuzzy
-#| msgid "__VA_ARGS__ can only appear in the expansion of a C++11 variadic macro"
msgid "__VA_OPT__ can only appear in the expansion of a C++2a variadic macro"
-msgstr "__VA_ARGS__ 只能出現在 C++11 可變參數巨集的展開中"
+msgstr "__VA_OPT__ 只能出現在 C++2a 可變參數巨集的展開中"
#: lex.c:1403 lex.c:1495
#, c-format
@@ -754,10 +750,8 @@ msgid "missing terminating %c character"
msgstr "缺少終止 %c 字元"
#: lex.c:2072
-#, fuzzy
-#| msgid "invalid suffix on literal; C++11 requires a space between literal and string macro"
msgid "C++11 requires a space between string literal and macro"
-msgstr "無效的實字後綴;C++11 要求一個空白位於實字和字串巨集之間"
+msgstr "C++11 在字串常數和巨集中間需要一個空白"
#: lex.c:2876 lex.c:2910
msgid "C++ style comments are not allowed in ISO C90"
@@ -781,10 +775,8 @@ msgid "unspellable token %s"
msgstr "無法拼出的識別字 %s"
#: macro.c:94
-#, fuzzy
-#| msgid "'##' cannot appear at either end of a macro expansion"
msgid "'##' cannot appear at either end of __VA_OPT__"
-msgstr "「##」不能出現在巨集展開的兩端"
+msgstr "「##」不能出現在 __VA_OPT__ 的尾端"
#: macro.c:354
#, c-format
@@ -868,26 +860,24 @@ msgstr "重複的巨集參數「%s」"
#: macro.c:3141
#, c-format
msgid "expected parameter name, found \"%s\""
-msgstr ""
+msgstr "原先期望參數名稱,卻找到「%s」"
#: macro.c:3142
#, c-format
msgid "expected ',' or ')', found \"%s\""
-msgstr ""
+msgstr "原先期望「,」或「)」,卻找到「%s」"
#: macro.c:3143
msgid "expected parameter name before end of line"
-msgstr ""
+msgstr "原先期望在行尾前有參數名稱"
#: macro.c:3144
-#, fuzzy
-#| msgid "unexpected end of file after #line"
msgid "expected ')' before end of line"
-msgstr "#line 之後未預期的檔案結束"
+msgstr "原先期望在行尾前有「)」"
#: macro.c:3145
msgid "expected ')' after \"...\""
-msgstr ""
+msgstr "原先期望「...」後有「)」"
#: macro.c:3202
msgid "anonymous variadic macros were introduced in C++11"
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 7997ad8..33b6fa8 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,16 @@
+2019-07-31 Matt Thomas <matt@3am-software.com>
+ Nick Hudson <nick@nthcliff.demon.co.uk>
+ Matthew Green <mrg@eterna.com.au>
+ Maya Rashish <coypu@sdf.org>
+
+ * config.host (hppa*-*-netbsd*): New case.
+ * config/pa/t-netbsd: New file.
+
+2019-07-31 Joel Hutton <Joel.Hutton@arm.com>
+
+ * config/arm/cmse.c (cmse_check_address_range): Add
+ warn_unused_result attribute.
+
2019-07-22 Martin Liska <mliska@suse.cz>
* config/pa/stublib.c: Remove stub symbol __gnu_lto_v1.
diff --git a/libgcc/config.host b/libgcc/config.host
index f5ca779..503ebb6 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -634,6 +634,9 @@ hppa[12]*-*-hpux11*)
hppa*-*-openbsd*)
tmake_file="$tmake_file pa/t-openbsd"
;;
+hppa*-*-netbsd*)
+ tmake_file="$tmake_file pa/t-netbsd"
+ ;;
i[34567]86-*-darwin*)
tmake_file="$tmake_file i386/t-crtpc t-crtfm i386/t-msabi"
tm_file="$tm_file i386/darwin-lib.h"
diff --git a/libgcc/config/arm/cmse.c b/libgcc/config/arm/cmse.c
index 34a46fd..0c5a3ea 100644
--- a/libgcc/config/arm/cmse.c
+++ b/libgcc/config/arm/cmse.c
@@ -30,6 +30,7 @@
address range. See ACLE changes for ARMv8-M. */
void *
+__attribute__ ((warn_unused_result))
cmse_check_address_range (void *p, size_t size, int flags)
{
cmse_address_info_t permb, perme;
diff --git a/libgcc/config/pa/t-netbsd b/libgcc/config/pa/t-netbsd
new file mode 100644
index 0000000..8b99068
--- /dev/null
+++ b/libgcc/config/pa/t-netbsd
@@ -0,0 +1,9 @@
+#Plug millicode routines into libgcc.a We want these on both native and
+#cross compiles. We use the "64-bit" routines because the "32-bit" code
+#is broken for certain corner cases.
+LIB1ASMSRC = pa/milli64.S
+LIB1ASMFUNCS = _divI _divU _remI _remU _div_const _mulI _dyncall
+
+HOST_LIBGCC2_CFLAGS += -DELF=1 -DLINUX=1
+
+LIB2ADD = $(srcdir)/config/pa/fptr.c
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index b4e3fe7..23a4c57 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,45 @@
+2019-08-17 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR fortran/68401
+ * gfortran.map: Add GFORTRAN_10 node, add _gfortran_os_error_at
+ symbol.
+ * libgfortran.h (os_error_at): New prototype.
+ * runtime/error.c (os_error_at): New function.
+
+2019-08-13 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR fortran/91414
+ * intrinsics/random.c (prng_state): Update state struct.
+ (master_state): Update to match new size.
+ (get_rand_state): Update to match new PRNG.
+ (rotl): New function.
+ (xorshift1024star): Replace with prng_next.
+ (prng_next): New function.
+ (jump): Update for new PRNG.
+ (lcg_parkmiller): Replace with splitmix64.
+ (splitmix64): New function.
+ (getosrandom): Fix return value, simplify.
+ (init_rand_state): Use getosrandom only to get 8 bytes, splitmix64
+ to fill rest of state.
+ (random_r4): Update to new function and struct names.
+ (random_r8): Likewise.
+ (random_r10): Likewise.
+ (random_r16): Likewise.
+ (arandom_r4): Liekwise.
+ (arandom_r8): Likewise.
+ (arandom_r10): Likwewise.
+ (arandom_r16): Likewise.
+ (xor_keys): Reduce size to match new PRNG.
+ (random_seed_i4): Update to new function and struct names, remove
+ special handling of variable p used in previous PRNG.
+ (random_seed_i8): Likewise.
+
+2019-08-07 Janne Blomqvist <jb@gcc.gnu.org>
+
+ PR fortran/53796
+ * io/inquire.c (inquire_via_filename): Set recl to -1 for
+ unconnected units.
+
2019-07-21 Thomas König <tkoenig@gcc.gnu.org>
PR libfortran/91030
diff --git a/libgfortran/gfortran.map b/libgfortran/gfortran.map
index 2b2243b..3601bc2 100644
--- a/libgfortran/gfortran.map
+++ b/libgfortran/gfortran.map
@@ -1602,3 +1602,8 @@ GFORTRAN_9.2 {
_gfortran_mfindloc1_r10;
_gfortran_sfindloc1_r10;
} GFORTRAN_9;
+
+GFORTRAN_10 {
+ global:
+ _gfortran_os_error_at;
+} GFORTRAN_9.2;
diff --git a/libgfortran/intrinsics/random.c b/libgfortran/intrinsics/random.c
index 7476439..dd2c46e 100644
--- a/libgfortran/intrinsics/random.c
+++ b/libgfortran/intrinsics/random.c
@@ -164,7 +164,7 @@ rnumber_16 (GFC_REAL_16 *f, GFC_UINTEGER_8 v1, GFC_UINTEGER_8 v2)
/*
- We use the xorshift1024* generator, a fast high-quality generator
+ We use the xoshiro256** generator, a fast high-quality generator
that:
- passes TestU1 without any failures
@@ -172,15 +172,15 @@ rnumber_16 (GFC_REAL_16 *f, GFC_UINTEGER_8 v1, GFC_UINTEGER_8 v2)
- provides a "jump" function making it easy to provide many
independent parallel streams.
- - Long period of 2**1024 - 1
+ - Long period of 2**256 - 1
A description can be found at
- http://vigna.di.unimi.it/ftp/papers/xorshift.pdf
+ http://prng.di.unimi.it/
or
- http://arxiv.org/abs/1402.6246
+ https://arxiv.org/abs/1805.01407
The paper includes public domain source code which is the basis for
the implementation below.
@@ -189,10 +189,9 @@ rnumber_16 (GFC_REAL_16 *f, GFC_UINTEGER_8 v1, GFC_UINTEGER_8 v2)
typedef struct
{
bool init;
- int p;
- uint64_t s[16];
+ uint64_t s[4];
}
-xorshift1024star_state;
+prng_state;
/* master_init, njumps, and master_state are the only variables
@@ -201,28 +200,24 @@ static bool master_init;
static unsigned njumps; /* How many times we have jumped. */
static uint64_t master_state[] = {
0xad63fa1ed3b55f36ULL, 0xd94473e78978b497ULL, 0xbc60592a98172477ULL,
- 0xa3de7c6e81265301ULL, 0x586640c5e785af27ULL, 0x7a2a3f63b67ce5eaULL,
- 0x9fde969f922d9b82ULL, 0xe6fe34379b3f3822ULL, 0x6c277eac3e99b6c2ULL,
- 0x9197290ab0d3f069ULL, 0xdb227302f6c25576ULL, 0xee0209aee527fae9ULL,
- 0x675666a793cd05b9ULL, 0xd048c99fbc70c20fULL, 0x775f8c3dba385ef5ULL,
- 0x625288bc262faf33ULL
+ 0xa3de7c6e81265301ULL
};
static __gthread_key_t rand_state_key;
-static xorshift1024star_state*
+static prng_state*
get_rand_state (void)
{
/* For single threaded apps. */
- static xorshift1024star_state rand_state;
+ static prng_state rand_state;
if (__gthread_active_p ())
{
void* p = __gthread_getspecific (rand_state_key);
if (!p)
{
- p = xcalloc (1, sizeof (xorshift1024star_state));
+ p = xcalloc (1, sizeof (prng_state));
__gthread_setspecific (rand_state_key, p);
}
return p;
@@ -231,76 +226,79 @@ get_rand_state (void)
return &rand_state;
}
+static inline uint64_t
+rotl (const uint64_t x, int k)
+{
+ return (x << k) | (x >> (64 - k));
+}
+
static uint64_t
-xorshift1024star (xorshift1024star_state* rs)
+prng_next (prng_state* rs)
{
- int p = rs->p;
- const uint64_t s0 = rs->s[p];
- uint64_t s1 = rs->s[p = (p + 1) & 15];
- s1 ^= s1 << 31;
- rs->s[p] = s1 ^ s0 ^ (s1 >> 11) ^ (s0 >> 30);
- rs->p = p;
- return rs->s[p] * UINT64_C(1181783497276652981);
+ const uint64_t result = rotl(rs->s[1] * 5, 7) * 9;
+
+ const uint64_t t = rs->s[1] << 17;
+
+ rs->s[2] ^= rs->s[0];
+ rs->s[3] ^= rs->s[1];
+ rs->s[1] ^= rs->s[2];
+ rs->s[0] ^= rs->s[3];
+
+ rs->s[2] ^= t;
+
+ rs->s[3] = rotl(rs->s[3], 45);
+
+ return result;
}
/* This is the jump function for the generator. It is equivalent to
- 2^512 calls to xorshift1024star(); it can be used to generate 2^512
+ 2^128 calls to prng_next(); it can be used to generate 2^128
non-overlapping subsequences for parallel computations. */
static void
-jump (xorshift1024star_state* rs)
+jump (prng_state* rs)
{
- static const uint64_t JUMP[] = {
- 0x84242f96eca9c41dULL, 0xa3c65b8776f96855ULL, 0x5b34a39f070b5837ULL,
- 0x4489affce4f31a1eULL, 0x2ffeeb0a48316f40ULL, 0xdc2d9891fe68c022ULL,
- 0x3659132bb12fea70ULL, 0xaac17d8efa43cab8ULL, 0xc4cb815590989b13ULL,
- 0x5ee975283d71c93bULL, 0x691548c86c1bd540ULL, 0x7910c41d10a1e6a5ULL,
- 0x0b5fc64563b3e2a8ULL, 0x047f7684e9fc949dULL, 0xb99181f2d8f685caULL,
- 0x284600e3f30e38c3ULL
- };
-
- uint64_t t[16] = { 0 };
+ static const uint64_t JUMP[] = { 0x180ec6d33cfd0aba, 0xd5a61266f0c9392c, 0xa9582618e03fc9aa, 0x39abdc4529b1661c };
+
+ uint64_t s0 = 0;
+ uint64_t s1 = 0;
+ uint64_t s2 = 0;
+ uint64_t s3 = 0;
for(size_t i = 0; i < sizeof JUMP / sizeof *JUMP; i++)
- for(int b = 0; b < 64; b++)
- {
- if (JUMP[i] & 1ULL << b)
- for(int j = 0; j < 16; j++)
- t[j] ^= rs->s[(j + rs->p) & 15];
- xorshift1024star (rs);
+ for(int b = 0; b < 64; b++) {
+ if (JUMP[i] & UINT64_C(1) << b) {
+ s0 ^= rs->s[0];
+ s1 ^= rs->s[1];
+ s2 ^= rs->s[2];
+ s3 ^= rs->s[3];
}
- for(int j = 0; j < 16; j++)
- rs->s[(j + rs->p) & 15] = t[j];
-}
+ prng_next (rs);
+ }
+ rs->s[0] = s0;
+ rs->s[1] = s1;
+ rs->s[2] = s2;
+ rs->s[3] = s3;
+}
-/* Super-simple LCG generator used in getosrandom () if /dev/urandom
- doesn't exist. */
-#define M 2147483647 /* 2^31 - 1 (A large prime number) */
-#define A 16807 /* Prime root of M, passes statistical tests and produces a full cycle */
-#define Q 127773 /* M / A (To avoid overflow on A * seed) */
-#define R 2836 /* M % A (To avoid overflow on A * seed) */
+/* Splitmix64 recommended by xoshiro author for initializing. After
+ getting one uint64_t value from the OS, this is used to fill in the
+ rest of the xoshiro state. */
-__attribute__((unused)) static uint32_t
-lcg_parkmiller(uint32_t seed)
+static uint64_t
+splitmix64 (uint64_t x)
{
- uint32_t hi = seed / Q;
- uint32_t lo = seed % Q;
- int32_t test = A * lo - R * hi;
- if (test <= 0)
- test += M;
- return test;
+ uint64_t z = (x += 0x9e3779b97f4a7c15);
+ z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
+ z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
+ return z ^ (z >> 31);
}
-#undef M
-#undef A
-#undef Q
-#undef R
-
-/* Get some random bytes from the operating system in order to seed
+/* Get some bytes from the operating system in order to seed
the PRNG. */
static int
@@ -315,7 +313,7 @@ getosrandom (void *buf, size_t buflen)
#else
#ifdef HAVE_GETENTROPY
if (getentropy (buf, buflen) == 0)
- return 0;
+ return buflen;
#endif
int flags = O_RDONLY;
#ifdef O_CLOEXEC
@@ -328,7 +326,7 @@ getosrandom (void *buf, size_t buflen)
close (fd);
return res;
}
- uint32_t seed = 1234567890;
+ uint64_t seed = 0x047f7684e9fc949dULL;
time_t secs;
long usecs;
if (gf_gettime (&secs, &usecs) == 0)
@@ -340,13 +338,9 @@ getosrandom (void *buf, size_t buflen)
pid_t pid = getpid();
seed ^= pid;
#endif
- uint32_t* ub = buf;
- for (size_t i = 0; i < buflen / sizeof (uint32_t); i++)
- {
- ub[i] = seed;
- seed = lcg_parkmiller (seed);
- }
- return buflen;
+ size_t size = buflen < sizeof (uint64_t) ? buflen : sizeof (uint64_t);
+ memcpy (buf, &seed, size);
+ return size;
#endif /* __MINGW64_VERSION_MAJOR */
}
@@ -355,13 +349,19 @@ getosrandom (void *buf, size_t buflen)
using the master state and the number of times we must jump. */
static void
-init_rand_state (xorshift1024star_state* rs, const bool locked)
+init_rand_state (prng_state* rs, const bool locked)
{
if (!locked)
__gthread_mutex_lock (&random_lock);
if (!master_init)
{
- getosrandom (master_state, sizeof (master_state));
+ uint64_t os_seed;
+ getosrandom (&os_seed, sizeof (os_seed));
+ for (uint64_t i = 0; i < sizeof (master_state) / sizeof (uint64_t); i++)
+ {
+ os_seed = splitmix64 (os_seed);
+ master_state[i] = os_seed;
+ }
njumps = 0;
master_init = true;
}
@@ -381,11 +381,11 @@ init_rand_state (xorshift1024star_state* rs, const bool locked)
void
random_r4 (GFC_REAL_4 *x)
{
- xorshift1024star_state* rs = get_rand_state();
+ prng_state* rs = get_rand_state();
if (unlikely (!rs->init))
init_rand_state (rs, false);
- uint64_t r = xorshift1024star (rs);
+ uint64_t r = prng_next (rs);
/* Take the higher bits, ensuring that a stream of real(4), real(8),
and real(10) will be identical (except for precision). */
uint32_t high = (uint32_t) (r >> 32);
@@ -400,11 +400,11 @@ void
random_r8 (GFC_REAL_8 *x)
{
GFC_UINTEGER_8 r;
- xorshift1024star_state* rs = get_rand_state();
+ prng_state* rs = get_rand_state();
if (unlikely (!rs->init))
init_rand_state (rs, false);
- r = xorshift1024star (rs);
+ r = prng_next (rs);
rnumber_8 (x, r);
}
iexport(random_r8);
@@ -418,11 +418,11 @@ void
random_r10 (GFC_REAL_10 *x)
{
GFC_UINTEGER_8 r;
- xorshift1024star_state* rs = get_rand_state();
+ prng_state* rs = get_rand_state();
if (unlikely (!rs->init))
init_rand_state (rs, false);
- r = xorshift1024star (rs);
+ r = prng_next (rs);
rnumber_10 (x, r);
}
iexport(random_r10);
@@ -438,12 +438,12 @@ void
random_r16 (GFC_REAL_16 *x)
{
GFC_UINTEGER_8 r1, r2;
- xorshift1024star_state* rs = get_rand_state();
+ prng_state* rs = get_rand_state();
if (unlikely (!rs->init))
init_rand_state (rs, false);
- r1 = xorshift1024star (rs);
- r2 = xorshift1024star (rs);
+ r1 = prng_next (rs);
+ r2 = prng_next (rs);
rnumber_16 (x, r1, r2);
}
iexport(random_r16);
@@ -463,7 +463,7 @@ arandom_r4 (gfc_array_r4 *x)
index_type stride0;
index_type dim;
GFC_REAL_4 *dest;
- xorshift1024star_state* rs = get_rand_state();
+ prng_state* rs = get_rand_state();
dest = x->base_addr;
@@ -486,7 +486,7 @@ arandom_r4 (gfc_array_r4 *x)
while (dest)
{
/* random_r4 (dest); */
- uint64_t r = xorshift1024star (rs);
+ uint64_t r = prng_next (rs);
uint32_t high = (uint32_t) (r >> 32);
rnumber_4 (dest, high);
@@ -530,7 +530,7 @@ arandom_r8 (gfc_array_r8 *x)
index_type stride0;
index_type dim;
GFC_REAL_8 *dest;
- xorshift1024star_state* rs = get_rand_state();
+ prng_state* rs = get_rand_state();
dest = x->base_addr;
@@ -553,7 +553,7 @@ arandom_r8 (gfc_array_r8 *x)
while (dest)
{
/* random_r8 (dest); */
- uint64_t r = xorshift1024star (rs);
+ uint64_t r = prng_next (rs);
rnumber_8 (dest, r);
/* Advance to the next element. */
@@ -598,7 +598,7 @@ arandom_r10 (gfc_array_r10 *x)
index_type stride0;
index_type dim;
GFC_REAL_10 *dest;
- xorshift1024star_state* rs = get_rand_state();
+ prng_state* rs = get_rand_state();
dest = x->base_addr;
@@ -621,7 +621,7 @@ arandom_r10 (gfc_array_r10 *x)
while (dest)
{
/* random_r10 (dest); */
- uint64_t r = xorshift1024star (rs);
+ uint64_t r = prng_next (rs);
rnumber_10 (dest, r);
/* Advance to the next element. */
@@ -668,7 +668,7 @@ arandom_r16 (gfc_array_r16 *x)
index_type stride0;
index_type dim;
GFC_REAL_16 *dest;
- xorshift1024star_state* rs = get_rand_state();
+ prng_state* rs = get_rand_state();
dest = x->base_addr;
@@ -691,8 +691,8 @@ arandom_r16 (gfc_array_r16 *x)
while (dest)
{
/* random_r16 (dest); */
- uint64_t r1 = xorshift1024star (rs);
- uint64_t r2 = xorshift1024star (rs);
+ uint64_t r1 = prng_next (rs);
+ uint64_t r2 = prng_next (rs);
rnumber_16 (dest, r1, r2);
/* Advance to the next element. */
@@ -734,11 +734,7 @@ arandom_r16 (gfc_array_r16 *x)
static const uint64_t xor_keys[] = {
0xbd0c5b6e50c2df49ULL, 0xd46061cd46e1df38ULL, 0xbb4f4d4ed6103544ULL,
- 0x114a583d0756ad39ULL, 0x4b5ad8623d0aaab6ULL, 0x3f2ed7afbe0c0f21ULL,
- 0xdec83fd65f113445ULL, 0x3824f8fbc4f10d24ULL, 0x5d9025af05878911ULL,
- 0x500bc46b540340e9ULL, 0x8bd53298e0d00530ULL, 0x57886e40a952e06aULL,
- 0x926e76c88e31cdb6ULL, 0xbd0724dac0a3a5f9ULL, 0xc5c8981b858ab796ULL,
- 0xbb12ab2694c2b32cULL
+ 0x114a583d0756ad39ULL
};
@@ -768,9 +764,9 @@ random_seed_i4 (GFC_INTEGER_4 *size, gfc_array_i4 *put, gfc_array_i4 *get)
runtime_error ("RANDOM_SEED should have at most one argument present.");
if (size != NULL)
- *size = SZ + 1;
+ *size = SZ;
- xorshift1024star_state* rs = get_rand_state();
+ prng_state* rs = get_rand_state();
/* Return the seed to GET data. */
if (get != NULL)
@@ -780,7 +776,7 @@ random_seed_i4 (GFC_INTEGER_4 *size, gfc_array_i4 *put, gfc_array_i4 *get)
runtime_error ("Array rank of GET is not 1.");
/* If the array is too small, abort. */
- if (GFC_DESCRIPTOR_EXTENT(get,0) < (index_type) SZ + 1)
+ if (GFC_DESCRIPTOR_EXTENT(get,0) < (index_type) SZ)
runtime_error ("Array size of GET is too small.");
if (!rs->init)
@@ -794,9 +790,6 @@ random_seed_i4 (GFC_INTEGER_4 *size, gfc_array_i4 *put, gfc_array_i4 *get)
memcpy (&(get->base_addr[(SZ - 1 - i) * GFC_DESCRIPTOR_STRIDE(get,0)]),
(unsigned char*) seed + i * sizeof(GFC_UINTEGER_4),
sizeof(GFC_UINTEGER_4));
-
- /* Finally copy the value of p after the seed. */
- get->base_addr[SZ * GFC_DESCRIPTOR_STRIDE(get, 0)] = rs->p;
}
else
@@ -818,7 +811,7 @@ random_seed_i4 (GFC_INTEGER_4 *size, gfc_array_i4 *put, gfc_array_i4 *get)
runtime_error ("Array rank of PUT is not 1.");
/* If the array is too small, abort. */
- if (GFC_DESCRIPTOR_EXTENT(put,0) < (index_type) SZ + 1)
+ if (GFC_DESCRIPTOR_EXTENT(put,0) < (index_type) SZ)
runtime_error ("Array size of PUT is too small.");
/* We copy the seed given by the user. */
@@ -833,8 +826,6 @@ random_seed_i4 (GFC_INTEGER_4 *size, gfc_array_i4 *put, gfc_array_i4 *get)
njumps = 0;
master_init = true;
init_rand_state (rs, true);
-
- rs->p = put->base_addr[SZ * GFC_DESCRIPTOR_STRIDE(put, 0)] & 15;
}
__gthread_mutex_unlock (&random_lock);
@@ -855,9 +846,9 @@ random_seed_i8 (GFC_INTEGER_8 *size, gfc_array_i8 *put, gfc_array_i8 *get)
#define SZ (sizeof (master_state) / sizeof (GFC_INTEGER_8))
if (size != NULL)
- *size = SZ + 1;
+ *size = SZ;
- xorshift1024star_state* rs = get_rand_state();
+ prng_state* rs = get_rand_state();
/* Return the seed to GET data. */
if (get != NULL)
@@ -867,7 +858,7 @@ random_seed_i8 (GFC_INTEGER_8 *size, gfc_array_i8 *put, gfc_array_i8 *get)
runtime_error ("Array rank of GET is not 1.");
/* If the array is too small, abort. */
- if (GFC_DESCRIPTOR_EXTENT(get,0) < (index_type) SZ + 1)
+ if (GFC_DESCRIPTOR_EXTENT(get,0) < (index_type) SZ)
runtime_error ("Array size of GET is too small.");
if (!rs->init)
@@ -880,8 +871,6 @@ random_seed_i8 (GFC_INTEGER_8 *size, gfc_array_i8 *put, gfc_array_i8 *get)
for (size_t i = 0; i < SZ; i++)
memcpy (&(get->base_addr[i * GFC_DESCRIPTOR_STRIDE(get,0)]), &seed[i],
sizeof (GFC_UINTEGER_8));
-
- get->base_addr[SZ * GFC_DESCRIPTOR_STRIDE(get, 0)] = rs->p;
}
else
@@ -903,7 +892,7 @@ random_seed_i8 (GFC_INTEGER_8 *size, gfc_array_i8 *put, gfc_array_i8 *get)
runtime_error ("Array rank of PUT is not 1.");
/* If the array is too small, abort. */
- if (GFC_DESCRIPTOR_EXTENT(put,0) < (index_type) SZ + 1)
+ if (GFC_DESCRIPTOR_EXTENT(put,0) < (index_type) SZ)
runtime_error ("Array size of PUT is too small.");
/* This code now should do correct strides. */
@@ -915,7 +904,6 @@ random_seed_i8 (GFC_INTEGER_8 *size, gfc_array_i8 *put, gfc_array_i8 *get)
njumps = 0;
master_init = true;
init_rand_state (rs, true);
- rs->p = put->base_addr[SZ * GFC_DESCRIPTOR_STRIDE(put, 0)] & 15;
}
diff --git a/libgfortran/io/inquire.c b/libgfortran/io/inquire.c
index 05cfc14..c2174d0 100644
--- a/libgfortran/io/inquire.c
+++ b/libgfortran/io/inquire.c
@@ -706,7 +706,9 @@ inquire_via_filename (st_parameter_inquire *iqp)
}
if ((cf & IOPARM_INQUIRE_HAS_RECL_OUT) != 0)
- *iqp->recl_out = 0;
+ /* F2018 (N2137) 12.10.2.26: If there is no connection, recl is
+ assigned the value -1. */
+ *iqp->recl_out = -1;
if ((cf & IOPARM_INQUIRE_HAS_NEXTREC) != 0)
*iqp->nextrec = 0;
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index c0db96f..9f535b1 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -728,6 +728,10 @@ internal_proto(gfc_xtoa);
extern _Noreturn void os_error (const char *);
iexport_proto(os_error);
+extern _Noreturn void os_error_at (const char *, const char *, ...)
+ __attribute__ ((format (gfc_printf, 2, 3)));
+iexport_proto(os_error_at);
+
extern void show_locus (st_parameter_common *);
internal_proto(show_locus);
diff --git a/libgfortran/runtime/error.c b/libgfortran/runtime/error.c
index 0335a16..cbe0642 100644
--- a/libgfortran/runtime/error.c
+++ b/libgfortran/runtime/error.c
@@ -403,7 +403,51 @@ os_error (const char *message)
estr_writev (iov, 5);
exit_error (1);
}
-iexport(os_error);
+iexport(os_error); /* TODO, DEPRECATED, ABI: Should not be exported
+ anymore when bumping so version. */
+
+
+/* Improved version of os_error with a printf style format string and
+ a locus. */
+
+void
+os_error_at (const char *where, const char *message, ...)
+{
+ char errmsg[STRERR_MAXSZ];
+ char buffer[STRERR_MAXSZ];
+ struct iovec iov[6];
+ va_list ap;
+ recursion_check ();
+ int written;
+
+ iov[0].iov_base = (char*) where;
+ iov[0].iov_len = strlen (where);
+
+ iov[1].iov_base = (char*) ": ";
+ iov[1].iov_len = strlen (iov[1].iov_base);
+
+ va_start (ap, message);
+ written = vsnprintf (buffer, STRERR_MAXSZ, message, ap);
+ va_end (ap);
+ iov[2].iov_base = buffer;
+ if (written >= 0)
+ iov[2].iov_len = written;
+ else
+ iov[2].iov_len = 0;
+
+ iov[3].iov_base = (char*) ": ";
+ iov[3].iov_len = strlen (iov[3].iov_base);
+
+ iov[4].iov_base = gf_strerror (errno, errmsg, STRERR_MAXSZ);
+ iov[4].iov_len = strlen (iov[4].iov_base);
+
+ iov[5].iov_base = (char*) "\n";
+ iov[5].iov_len = 1;
+
+ estr_writev (iov, 6);
+ exit_error (1);
+}
+iexport(os_error_at);
/* void runtime_error()-- These are errors associated with an
diff --git a/libgo/go/runtime/mcentral.go b/libgo/go/runtime/mcentral.go
index 0196ba4..a60eb9f 100644
--- a/libgo/go/runtime/mcentral.go
+++ b/libgo/go/runtime/mcentral.go
@@ -56,15 +56,6 @@ retry:
c.empty.insertBack(s)
unlock(&c.lock)
s.sweep(true)
-
- // With gccgo's conservative GC, the returned span may
- // now be full. See the comments in mspan.sweep.
- if uintptr(s.allocCount) == s.nelems {
- s.freeindex = s.nelems
- lock(&c.lock)
- goto retry
- }
-
goto havespan
}
if s.sweepgen == sg-1 {
diff --git a/libgo/go/runtime/mgcmark.go b/libgo/go/runtime/mgcmark.go
index 1b8a7a3..2463a48 100644
--- a/libgo/go/runtime/mgcmark.go
+++ b/libgo/go/runtime/mgcmark.go
@@ -657,6 +657,11 @@ func scanstack(gp *g, gcw *gcWork) {
scanstackblock(uintptr(unsafe.Pointer(&gp.context)), unsafe.Sizeof(gp.context), gcw)
}
+ // Note: in the gc runtime scanstack also scans defer records.
+ // This is necessary as it uses stack objects (a.k.a. stack tracing).
+ // We don't (yet) do stack objects, and regular stack/heap scan
+ // will take care of defer records just fine.
+
gp.gcscanvalid = true
}
diff --git a/libgo/go/runtime/mgcsweep.go b/libgo/go/runtime/mgcsweep.go
index bc53de4..539a982 100644
--- a/libgo/go/runtime/mgcsweep.go
+++ b/libgo/go/runtime/mgcsweep.go
@@ -326,39 +326,16 @@ func (s *mspan) sweep(preserve bool) bool {
freeToHeap = true
}
nfreed := s.allocCount - nalloc
-
- // This check is not reliable with gccgo, because of
- // conservative stack scanning. The test boils down to
- // checking that no new bits have been set in gcmarkBits since
- // the span was added to the sweep count. New bits are set by
- // greyobject. Seeing a new bit means that a live pointer has
- // appeared that was not found during the mark phase. That can
- // not happen when pointers are followed strictly. However,
- // with conservative checking, it is possible for a pointer
- // that will never be used to appear live and to cause a mark
- // to be added. That is unfortunate in that it causes this
- // check to be inaccurate, and it will keep an object live
- // unnecessarily, but provided the pointer is not really live
- // it is not otherwise a problem. So we disable the test for gccgo.
- nfreedSigned := int(nfreed)
if nalloc > s.allocCount {
- if usestackmaps {
- print("runtime: nelems=", s.nelems, " nalloc=", nalloc, " previous allocCount=", s.allocCount, " nfreed=", nfreed, "\n")
- throw("sweep increased allocation count")
- }
-
- // For gccgo, adjust the freed count as a signed number.
- nfreedSigned = int(s.allocCount) - int(nalloc)
- if uintptr(nalloc) == s.nelems {
- s.freeindex = s.nelems
- }
+ print("runtime: nelems=", s.nelems, " nalloc=", nalloc, " previous allocCount=", s.allocCount, " nfreed=", nfreed, "\n")
+ throw("sweep increased allocation count")
}
s.allocCount = nalloc
wasempty := s.nextFreeIndex() == s.nelems
s.freeindex = 0 // reset allocation index to start of span.
if trace.enabled {
- getg().m.p.ptr().traceReclaimed += uintptr(nfreedSigned) * s.elemsize
+ getg().m.p.ptr().traceReclaimed += uintptr(nfreed) * s.elemsize
}
// gcmarkBits becomes the allocBits.
@@ -374,7 +351,7 @@ func (s *mspan) sweep(preserve bool) bool {
// But we need to set it before we make the span available for allocation
// (return it to heap or mcentral), because allocation code assumes that a
// span is already swept if available for allocation.
- if freeToHeap || nfreedSigned <= 0 {
+ if freeToHeap || nfreed == 0 {
// The span must be in our exclusive ownership until we update sweepgen,
// check for potential races.
if s.state != mSpanInUse || s.sweepgen != sweepgen-1 {
@@ -387,11 +364,8 @@ func (s *mspan) sweep(preserve bool) bool {
atomic.Store(&s.sweepgen, sweepgen)
}
- if spc.sizeclass() != 0 {
- c.local_nsmallfree[spc.sizeclass()] += uintptr(nfreedSigned)
- }
-
- if nfreedSigned > 0 && spc.sizeclass() != 0 {
+ if nfreed > 0 && spc.sizeclass() != 0 {
+ c.local_nsmallfree[spc.sizeclass()] += uintptr(nfreed)
res = mheap_.central[spc].mcentral.freeSpan(s, preserve, wasempty)
// mcentral.freeSpan updates sweepgen
} else if freeToHeap {
diff --git a/libgo/go/runtime/mwbbuf.go b/libgo/go/runtime/mwbbuf.go
index 4c875ff..a27406e 100644
--- a/libgo/go/runtime/mwbbuf.go
+++ b/libgo/go/runtime/mwbbuf.go
@@ -285,10 +285,17 @@ func wbBufFlush1(_p_ *p) {
// path to reduce the rate of flushes?
continue
}
- obj, span, objIndex := findObject(ptr, 0, 0, false)
+ obj, span, objIndex := findObject(ptr, 0, 0, !usestackmaps)
if obj == 0 {
continue
}
+ if span.isFree(objIndex) {
+ // For gccgo, it is possible that we have a write barrier
+ // writing to unintialized stack memory. So we could see
+ // a bad pointer in the write barrier buffer. Don't mark
+ // it in this case.
+ continue
+ }
// TODO: Consider making two passes where the first
// just prefetches the mark bits.
mbits := span.markBitsForIndex(objIndex)
diff --git a/libgo/go/runtime/panic.go b/libgo/go/runtime/panic.go
index 264ad38..88c0a4d 100644
--- a/libgo/go/runtime/panic.go
+++ b/libgo/go/runtime/panic.go
@@ -13,6 +13,7 @@ import (
// themselves, so that the compiler will export them.
//
//go:linkname deferproc runtime.deferproc
+//go:linkname deferprocStack runtime.deferprocStack
//go:linkname deferreturn runtime.deferreturn
//go:linkname setdeferretaddr runtime.setdeferretaddr
//go:linkname checkdefer runtime.checkdefer
@@ -124,6 +125,38 @@ func deferproc(frame *bool, pfn uintptr, arg unsafe.Pointer) {
d.makefunccanrecover = false
}
+// deferprocStack queues a new deferred function with a defer record on the stack.
+// The defer record, d, does not need to be initialized.
+// Other arguments are the same as in deferproc.
+//go:nosplit
+func deferprocStack(d *_defer, frame *bool, pfn uintptr, arg unsafe.Pointer) {
+ gp := getg()
+ if gp.m.curg != gp {
+ // go code on the system stack can't defer
+ throw("defer on system stack")
+ }
+ d.pfn = pfn
+ d.retaddr = 0
+ d.makefunccanrecover = false
+ d.heap = false
+ // The lines below implement:
+ // d.frame = frame
+ // d.arg = arg
+ // d._panic = nil
+ // d.panicStack = gp._panic
+ // d.link = gp._defer
+ // But without write barriers. They are writes to the stack so they
+ // don't need a write barrier, and furthermore are to uninitialized
+ // memory, so they must not use a write barrier.
+ *(*uintptr)(unsafe.Pointer(&d.frame)) = uintptr(unsafe.Pointer(frame))
+ *(*uintptr)(unsafe.Pointer(&d.arg)) = uintptr(unsafe.Pointer(arg))
+ *(*uintptr)(unsafe.Pointer(&d._panic)) = 0
+ *(*uintptr)(unsafe.Pointer(&d.panicStack)) = uintptr(unsafe.Pointer(gp._panic))
+ *(*uintptr)(unsafe.Pointer(&d.link)) = uintptr(unsafe.Pointer(gp._defer))
+
+ gp._defer = d
+}
+
// Allocate a Defer, usually using per-P pool.
// Each defer must be released with freedefer.
func newdefer() *_defer {
@@ -155,11 +188,13 @@ func newdefer() *_defer {
// Duplicate the tail below so if there's a
// crash in checkPut we can tell if d was just
// allocated or came from the pool.
+ d.heap = true
d.link = gp._defer
gp._defer = d
return d
}
}
+ d.heap = true
d.link = gp._defer
gp._defer = d
return d
@@ -179,6 +214,9 @@ func freedefer(d *_defer) {
if d.pfn != 0 {
freedeferfn()
}
+ if !d.heap {
+ return
+ }
pp := getg().m.p.ptr()
if len(pp.deferpool) == cap(pp.deferpool) {
// Transfer half of local cache to the central cache.
diff --git a/libgo/go/runtime/runtime1.go b/libgo/go/runtime/runtime1.go
index e2567b3..2424f20 100644
--- a/libgo/go/runtime/runtime1.go
+++ b/libgo/go/runtime/runtime1.go
@@ -352,19 +352,12 @@ func parsedebugvars() {
// defaults
debug.cgocheck = 1
- // Unfortunately, because gccgo uses conservative stack scanning,
- // we can not enable invalid pointer checking. It is possible for
- // memory block M1 to point to M2, and for both to be dead.
- // We release M2, causing the entire span to be released.
- // Before we release M1, a stack pointer appears that point into it.
- // This stack pointer is presumably dead, but causes M1 to be marked.
- // We scan M1 and see the pointer to M2 on a released span.
- // At that point, if debug.invalidptr is set, we crash.
- // This is not a problem, assuming that M1 really is dead and
- // the pointer we discovered to it will not be used.
- if usestackmaps {
- debug.invalidptr = 1
- }
+ // Gccgo uses conservative stack scanning, so we cannot check
+ // invalid pointers on stack. But we can still enable invalid
+ // pointer check on heap scanning. When scanning the heap, we
+ // ensure that we only trace allocated heap objects, which should
+ // not contain invalid pointers.
+ debug.invalidptr = 1
for p := gogetenv("GODEBUG"); p != ""; {
field := ""
diff --git a/libgo/go/runtime/runtime2.go b/libgo/go/runtime/runtime2.go
index 4f823e0..e4dfbdf 100644
--- a/libgo/go/runtime/runtime2.go
+++ b/libgo/go/runtime/runtime2.go
@@ -746,6 +746,12 @@ func extendRandom(r []byte, n int) {
// A _defer holds an entry on the list of deferred calls.
// If you add a field here, add code to clear it in freedefer.
+// This struct must match the code in Defer_statement::defer_struct_type
+// in the compiler.
+// Some defers will be allocated on the stack and some on the heap.
+// All defers are logically part of the stack, so write barriers to
+// initialize them are not required. All defers must be manually scanned,
+// and for heap defers, marked.
type _defer struct {
// The next entry in the stack.
link *_defer
@@ -781,6 +787,9 @@ type _defer struct {
// function function will be somewhere in libffi, so __retaddr
// is not useful.
makefunccanrecover bool
+
+ // Whether the _defer is heap allocated.
+ heap bool
}
// panics
diff --git a/libgo/go/runtime/stack_test.go b/libgo/go/runtime/stack_test.go
new file mode 100644
index 0000000..b696253
--- /dev/null
+++ b/libgo/go/runtime/stack_test.go
@@ -0,0 +1,62 @@
+// Copyright 2019 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 runtime_test
+
+import "testing"
+
+func TestDeferHeapAndStack(t *testing.T) {
+ P := 4 // processors
+ N := 10000 // iterations
+ D := 200 // stack depth
+
+ if testing.Short() {
+ P /= 2
+ N /= 10
+ D /= 10
+ }
+ c := make(chan bool)
+ for p := 0; p < P; p++ {
+ go func() {
+ for i := 0; i < N; i++ {
+ if deferHeapAndStack(D) != 2*D {
+ panic("bad result")
+ }
+ }
+ c <- true
+ }()
+ }
+ for p := 0; p < P; p++ {
+ <-c
+ }
+}
+
+// deferHeapAndStack(n) computes 2*n
+func deferHeapAndStack(n int) (r int) {
+ if n == 0 {
+ return 0
+ }
+ if n%2 == 0 {
+ // heap-allocated defers
+ for i := 0; i < 2; i++ {
+ defer func() {
+ r++
+ }()
+ }
+ } else {
+ // stack-allocated defers
+ defer func() {
+ r++
+ }()
+ defer func() {
+ r++
+ }()
+ }
+ r = deferHeapAndStack(n - 1)
+ escapeMe(new([1024]byte)) // force some GCs
+ return
+}
+
+// Pass a value to escapeMe to force it to escape.
+var escapeMe = func(x interface{}) {}
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 547ce4e..1332e42 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,52 @@
+2019-08-17 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/91473
+ * testsuite/libgomp.fortran/appendix-a/a.28.5.f90: Add
+ -std=legacy so invalid code in the test case is accepted.
+
+2019-08-12 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/91422
+ * testsuite/libgomp.oacc-fortran/routine-7.f90: Correct array
+ dimension.
+
+2019-08-08 Jakub Jelinek <jakub@redhat.com>
+
+ * target.c (gomp_map_vars_internal): For GOMP_MAP_USE_DEVICE_PTR
+ perform the lookup in the first loop only if !not_found_cnt, otherwise
+ perform lookups for it in the second loop guarded with
+ if (not_found_cnt || has_firstprivate).
+ * testsuite/libgomp.c/target-37.c: New test.
+ * testsuite/libgomp.c++/target-22.C: New test.
+
+2019-08-07 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c/target-18.c (struct S): New type.
+ (foo): Use use_device_addr clause instead of use_device_ptr clause
+ where required by OpenMP 5.0, add further tests for both use_device_ptr
+ and use_device_addr clauses.
+ * testsuite/libgomp.c++/target-9.C (struct S): New type.
+ (foo): Use use_device_addr clause instead of use_device_ptr clause
+ where required by OpenMP 5.0, add further tests for both use_device_ptr
+ and use_device_addr clauses. Add t and u arguments.
+ (main): Adjust caller.
+
+2019-08-06 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c++/loop-13.C: New test.
+ * testsuite/libgomp.c++/loop-14.C: New test.
+ * testsuite/libgomp.c++/loop-15.C: New test.
+
+2019-07-31 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/91301
+ * testsuite/libgomp.c++/for-27.C: New test.
+
+2019-07-23 Steven G. Kargl <kargl@gcc.gnu.org>
+
+ * testsuite/libgomp.fortran/reduction4.f90: Update BOZ usage.
+ * testsuite/libgomp.fortran/reduction5.f90: Ditto.
+
2019-07-20 Jakub Jelinek <jakub@redhat.com>
* testsuite/libgomp.c-c++-common/loop-1.c: New test.
diff --git a/libgomp/target.c b/libgomp/target.c
index 9416401..1c9ca68 100644
--- a/libgomp/target.c
+++ b/libgomp/target.c
@@ -580,20 +580,12 @@ gomp_map_vars_internal (struct gomp_device_descr *devicep,
}
else if ((kind & typemask) == GOMP_MAP_USE_DEVICE_PTR)
{
- cur_node.host_start = (uintptr_t) hostaddrs[i];
- cur_node.host_end = cur_node.host_start;
- splay_tree_key n = gomp_map_lookup (mem_map, &cur_node);
- if (n == NULL)
+ tgt->list[i].key = NULL;
+ if (!not_found_cnt)
{
- gomp_mutex_unlock (&devicep->lock);
- gomp_fatal ("use_device_ptr pointer wasn't mapped");
}
- cur_node.host_start -= n->host_start;
- hostaddrs[i]
- = (void *) (n->tgt->tgt_start + n->tgt_offset
- + cur_node.host_start);
- tgt->list[i].key = NULL;
- tgt->list[i].offset = ~(uintptr_t) 0;
+ else
+ tgt->list[i].offset = 0;
continue;
}
else if ((kind & typemask) == GOMP_MAP_STRUCT)
@@ -791,9 +783,26 @@ gomp_map_vars_internal (struct gomp_device_descr *devicep,
tgt_size += len;
continue;
case GOMP_MAP_FIRSTPRIVATE_INT:
- case GOMP_MAP_USE_DEVICE_PTR:
case GOMP_MAP_ZERO_LEN_ARRAY_SECTION:
continue;
+ case GOMP_MAP_USE_DEVICE_PTR:
+ if (tgt->list[i].offset == 0)
+ {
+ cur_node.host_start = (uintptr_t) hostaddrs[i];
+ cur_node.host_end = cur_node.host_start;
+ n = gomp_map_lookup (mem_map, &cur_node);
+ if (n == NULL)
+ {
+ gomp_mutex_unlock (&devicep->lock);
+ gomp_fatal ("use_device_ptr pointer wasn't mapped");
+ }
+ cur_node.host_start -= n->host_start;
+ hostaddrs[i]
+ = (void *) (n->tgt->tgt_start + n->tgt_offset
+ + cur_node.host_start);
+ tgt->list[i].offset = ~(uintptr_t) 0;
+ }
+ continue;
case GOMP_MAP_STRUCT:
first = i + 1;
last = i + sizes[i];
diff --git a/libgomp/testsuite/libgomp.c++/for-27.C b/libgomp/testsuite/libgomp.c++/for-27.C
new file mode 100644
index 0000000..7dca430
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/for-27.C
@@ -0,0 +1,169 @@
+// { dg-do run }
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+extern "C" void abort ();
+
+int a[2000];
+
+template <typename T>
+class I
+{
+public:
+ typedef ptrdiff_t difference_type;
+ I ();
+ ~I ();
+ I (T *);
+ I (const I &);
+ T &operator * ();
+ T *operator -> ();
+ T &operator [] (const difference_type &) const;
+ I &operator = (const I &);
+ I &operator ++ ();
+ I operator ++ (int);
+ I &operator -- ();
+ I operator -- (int);
+ I &operator += (const difference_type &);
+ I &operator -= (const difference_type &);
+ I operator + (const difference_type &) const;
+ I operator - (const difference_type &) const;
+ template <typename S> friend bool operator == (I<S> &, I<S> &);
+ template <typename S> friend bool operator == (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator < (I<S> &, I<S> &);
+ template <typename S> friend bool operator < (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator <= (I<S> &, I<S> &);
+ template <typename S> friend bool operator <= (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator > (I<S> &, I<S> &);
+ template <typename S> friend bool operator > (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator >= (I<S> &, I<S> &);
+ template <typename S> friend bool operator >= (const I<S> &, const I<S> &);
+ template <typename S> friend typename I<S>::difference_type operator - (I<S> &, I<S> &);
+ template <typename S> friend typename I<S>::difference_type operator - (const I<S> &, const I<S> &);
+ template <typename S> friend I<S> operator + (typename I<S>::difference_type , const I<S> &);
+private:
+ T *p;
+};
+template <typename T> I<T>::I () : p (0) {}
+template <typename T> I<T>::~I () {}
+template <typename T> I<T>::I (T *x) : p (x) {}
+template <typename T> I<T>::I (const I &x) : p (x.p) {}
+template <typename T> T &I<T>::operator * () { return *p; }
+template <typename T> T *I<T>::operator -> () { return p; }
+template <typename T> T &I<T>::operator [] (const difference_type &x) const { return p[x]; }
+template <typename T> I<T> &I<T>::operator = (const I &x) { p = x.p; return *this; }
+template <typename T> I<T> &I<T>::operator ++ () { ++p; return *this; }
+template <typename T> I<T> I<T>::operator ++ (int) { return I (p++); }
+template <typename T> I<T> &I<T>::operator -- () { --p; return *this; }
+template <typename T> I<T> I<T>::operator -- (int) { return I (p--); }
+template <typename T> I<T> &I<T>::operator += (const difference_type &x) { p += x; return *this; }
+template <typename T> I<T> &I<T>::operator -= (const difference_type &x) { p -= x; return *this; }
+template <typename T> I<T> I<T>::operator + (const difference_type &x) const { return I (p + x); }
+template <typename T> I<T> I<T>::operator - (const difference_type &x) const { return I (p - x); }
+template <typename T> bool operator == (I<T> &x, I<T> &y) { return x.p == y.p; }
+template <typename T> bool operator == (const I<T> &x, const I<T> &y) { return x.p == y.p; }
+template <typename T> bool operator != (I<T> &x, I<T> &y) { return !(x == y); }
+template <typename T> bool operator != (const I<T> &x, const I<T> &y) { return !(x == y); }
+template <typename T> bool operator < (I<T> &x, I<T> &y) { return x.p < y.p; }
+template <typename T> bool operator < (const I<T> &x, const I<T> &y) { return x.p < y.p; }
+template <typename T> bool operator <= (I<T> &x, I<T> &y) { return x.p <= y.p; }
+template <typename T> bool operator <= (const I<T> &x, const I<T> &y) { return x.p <= y.p; }
+template <typename T> bool operator > (I<T> &x, I<T> &y) { return x.p > y.p; }
+template <typename T> bool operator > (const I<T> &x, const I<T> &y) { return x.p > y.p; }
+template <typename T> bool operator >= (I<T> &x, I<T> &y) { return x.p >= y.p; }
+template <typename T> bool operator >= (const I<T> &x, const I<T> &y) { return x.p >= y.p; }
+template <typename T> typename I<T>::difference_type operator - (I<T> &x, I<T> &y) { return x.p - y.p; }
+template <typename T> typename I<T>::difference_type operator - (const I<T> &x, const I<T> &y) { return x.p - y.p; }
+template <typename T> I<T> operator + (typename I<T>::difference_type x, const I<T> &y) { return I<T> (x + y.p); }
+
+template <typename T>
+class J
+{
+public:
+ J(const I<T> &x, const I<T> &y) : b (x), e (y) {}
+ const I<T> &begin ();
+ const I<T> &end ();
+private:
+ I<T> b, e;
+};
+
+template <typename T> const I<T> &J<T>::begin () { return b; }
+template <typename T> const I<T> &J<T>::end () { return e; }
+
+int results[2000];
+
+template <typename T>
+void
+baz (I<T> &i)
+{
+ if (*i < 0 || *i >= 2000)
+ abort ();
+ results[*i]++;
+}
+
+static inline void
+baz (int i)
+{
+ results[i]++;
+}
+
+void
+f1 ()
+{
+#pragma omp simd
+ for (auto i : a)
+ baz (i);
+}
+
+void
+f2 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp distribute parallel for
+ for (i = x; i <= y; i += 6)
+ baz (*i);
+}
+
+void
+f3 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp distribute parallel for private (i)
+ for (i = x; i < y - 1; i = 1 - 6 + 7 + i)
+ baz (*i);
+}
+
+void
+f4 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp teams distribute parallel for lastprivate (i)
+ for (i = x + 2000 - 64; i > y + 10; --i)
+ baz (*i);
+}
+
+#define check(expr) \
+ for (int i = 0; i < 2000; i++) \
+ if (expr) \
+ { \
+ if (results[i] != 1) \
+ abort (); \
+ results[i] = 0; \
+ } \
+ else if (results[i]) \
+ abort ()
+
+int
+main ()
+{
+ for (int i = 0; i < 2000; i++)
+ a[i] = i;
+ f1 ();
+ check (1);
+ #pragma omp teams
+ f2 (&a[10], &a[1990]);
+ check (i >= 10 && i <= 1990 && (i - 10) % 6 == 0);
+ #pragma omp teams
+ f3 (&a[0], &a[1999]);
+ check (i < 1998 && (i & 1) == 0);
+ f4 (&a[0], &a[30]);
+ check (i > 40 && i <= 2000 - 64);
+}
diff --git a/libgomp/testsuite/libgomp.c++/loop-13.C b/libgomp/testsuite/libgomp.c++/loop-13.C
new file mode 100644
index 0000000..663212c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/loop-13.C
@@ -0,0 +1,298 @@
+// { dg-do run }
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+extern "C" void abort ();
+
+template <typename T>
+class I
+{
+public:
+ typedef ptrdiff_t difference_type;
+ I ();
+ ~I ();
+ I (T *);
+ I (const I &);
+ T &operator * ();
+ T *operator -> ();
+ T &operator [] (const difference_type &) const;
+ I &operator = (const I &);
+ I &operator ++ ();
+ I operator ++ (int);
+ I &operator -- ();
+ I operator -- (int);
+ I &operator += (const difference_type &);
+ I &operator -= (const difference_type &);
+ I operator + (const difference_type &) const;
+ I operator - (const difference_type &) const;
+ template <typename S> friend bool operator == (I<S> &, I<S> &);
+ template <typename S> friend bool operator == (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator < (I<S> &, I<S> &);
+ template <typename S> friend bool operator < (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator <= (I<S> &, I<S> &);
+ template <typename S> friend bool operator <= (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator > (I<S> &, I<S> &);
+ template <typename S> friend bool operator > (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator >= (I<S> &, I<S> &);
+ template <typename S> friend bool operator >= (const I<S> &, const I<S> &);
+ template <typename S> friend typename I<S>::difference_type operator - (I<S> &, I<S> &);
+ template <typename S> friend typename I<S>::difference_type operator - (const I<S> &, const I<S> &);
+ template <typename S> friend I<S> operator + (typename I<S>::difference_type , const I<S> &);
+private:
+ T *p;
+};
+template <typename T> I<T>::I () : p (0) {}
+template <typename T> I<T>::~I () {}
+template <typename T> I<T>::I (T *x) : p (x) {}
+template <typename T> I<T>::I (const I &x) : p (x.p) {}
+template <typename T> T &I<T>::operator * () { return *p; }
+template <typename T> T *I<T>::operator -> () { return p; }
+template <typename T> T &I<T>::operator [] (const difference_type &x) const { return p[x]; }
+template <typename T> I<T> &I<T>::operator = (const I &x) { p = x.p; return *this; }
+template <typename T> I<T> &I<T>::operator ++ () { ++p; return *this; }
+template <typename T> I<T> I<T>::operator ++ (int) { return I (p++); }
+template <typename T> I<T> &I<T>::operator -- () { --p; return *this; }
+template <typename T> I<T> I<T>::operator -- (int) { return I (p--); }
+template <typename T> I<T> &I<T>::operator += (const difference_type &x) { p += x; return *this; }
+template <typename T> I<T> &I<T>::operator -= (const difference_type &x) { p -= x; return *this; }
+template <typename T> I<T> I<T>::operator + (const difference_type &x) const { return I (p + x); }
+template <typename T> I<T> I<T>::operator - (const difference_type &x) const { return I (p - x); }
+template <typename T> bool operator == (I<T> &x, I<T> &y) { return x.p == y.p; }
+template <typename T> bool operator == (const I<T> &x, const I<T> &y) { return x.p == y.p; }
+template <typename T> bool operator != (I<T> &x, I<T> &y) { return !(x == y); }
+template <typename T> bool operator != (const I<T> &x, const I<T> &y) { return !(x == y); }
+template <typename T> bool operator < (I<T> &x, I<T> &y) { return x.p < y.p; }
+template <typename T> bool operator < (const I<T> &x, const I<T> &y) { return x.p < y.p; }
+template <typename T> bool operator <= (I<T> &x, I<T> &y) { return x.p <= y.p; }
+template <typename T> bool operator <= (const I<T> &x, const I<T> &y) { return x.p <= y.p; }
+template <typename T> bool operator > (I<T> &x, I<T> &y) { return x.p > y.p; }
+template <typename T> bool operator > (const I<T> &x, const I<T> &y) { return x.p > y.p; }
+template <typename T> bool operator >= (I<T> &x, I<T> &y) { return x.p >= y.p; }
+template <typename T> bool operator >= (const I<T> &x, const I<T> &y) { return x.p >= y.p; }
+template <typename T> typename I<T>::difference_type operator - (I<T> &x, I<T> &y) { return x.p - y.p; }
+template <typename T> typename I<T>::difference_type operator - (const I<T> &x, const I<T> &y) { return x.p - y.p; }
+template <typename T> I<T> operator + (typename I<T>::difference_type x, const I<T> &y) { return I<T> (x + y.p); }
+
+template <typename T>
+class J
+{
+public:
+ J(const I<T> &x, const I<T> &y) : b (x), e (y) {}
+ const I<T> &begin ();
+ const I<T> &end ();
+private:
+ I<T> b, e;
+};
+
+template <typename T> const I<T> &J<T>::begin () { return b; }
+template <typename T> const I<T> &J<T>::end () { return e; }
+
+int results[2000];
+
+template <typename T>
+static inline void
+baz (I<T> &i)
+{
+ results[*i]++;
+}
+
+void
+f1 (const I<int> &x, const I<int> &y)
+{
+#pragma omp parallel loop order(concurrent)
+ for (I<int> i = x; i <= y; i += 6)
+ baz (i);
+}
+
+void
+f2 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp loop private(i) bind(parallel)
+ for (i = x; i < y - 1; i = 1 - 6 + 7 + i)
+ baz (i);
+}
+
+template <typename T>
+void
+f3 (const I<int> &x, const I<int> &y)
+{
+#pragma omp loop bind(thread) order(concurrent)
+ for (I<int> i = x; i <= y; i = i + 9 - 8)
+ baz (i);
+}
+
+template <typename T>
+void
+f4 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp parallel loop lastprivate(i)
+ for (i = x + 2000 - 64; i > y + 10; --i)
+ baz (i);
+}
+
+void
+f5 (const I<int> &x, const I<int> &y)
+{
+#pragma omp loop bind(teams)
+ for (I<int> i = x + 2000 - 64; i > y + 10; i -= 10)
+ baz (i);
+}
+
+template <int N>
+void
+f6 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp teams loop order(concurrent)
+ for (i = x + 2000 - 64; i > y + 10; i = i - 12 + 2)
+ {
+ I<int> j = i + N;
+ baz (j);
+ }
+}
+
+template <int N>
+void
+f7 (I<int> i, const I<int> &x, const I<int> &y)
+{
+#pragma omp master
+#pragma omp loop
+ for (i = x - 10; i <= y + 10; i += N)
+ baz (i);
+}
+
+template <int N>
+void
+f8 (J<int> j)
+{
+ I<int> i;
+#pragma omp parallel loop
+ for (i = j.begin (); i <= j.end () + N; i += 2)
+ baz (i);
+}
+
+template <typename T, int N>
+void
+f9 (const I<T> &x, const I<T> &y)
+{
+ I<T> i;
+#pragma omp loop bind(teams) private(i)
+ for (i = x; i <= y; i = i + N)
+ baz (i);
+}
+
+template <typename T, int N>
+void
+f10 (const I<T> &x, const I<T> &y)
+{
+ I<T> i;
+#pragma omp loop bind(thread) private(i)
+ for (i = x; i > y; i = i + N)
+ baz (i);
+}
+
+template <typename T>
+void
+f11 (const T &x, const T &y)
+{
+#pragma omp parallel
+ {
+#pragma omp loop
+ for (T i = x; i <= y; i += 3)
+ baz (i);
+#pragma omp single
+ {
+ T j = y + 3;
+ baz (j);
+ }
+ }
+}
+
+template <typename T>
+void
+f12 (const T &x, const T &y)
+{
+ T i;
+#pragma omp loop lastprivate(i) bind(thread)
+ for (i = x; i > y; --i)
+ baz (i);
+}
+
+template <int N>
+struct K
+{
+ template <typename T>
+ static void
+ f13 (const T &x, const T &y)
+ {
+ T i;
+#pragma omp teams loop order(concurrent) bind(teams) lastprivate (i)
+ for (i = x; i <= y + N; i += N)
+ baz (i);
+ }
+};
+
+#define check(expr) \
+ for (int i = 0; i < 2000; i++) \
+ if (expr) \
+ { \
+ if (results[i] != 1) \
+ abort (); \
+ results[i] = 0; \
+ } \
+ else if (results[i]) \
+ abort ()
+
+int
+main ()
+{
+ int a[2000];
+ long b[2000];
+ for (int i = 0; i < 2000; i++)
+ {
+ a[i] = i;
+ b[i] = i;
+ }
+ f1 (&a[10], &a[1990]);
+ check (i >= 10 && i <= 1990 && (i - 10) % 6 == 0);
+ #pragma omp parallel
+ f2 (&a[0], &a[1999]);
+ check (i < 1998 && (i & 1) == 0);
+ f3<char> (&a[20], &a[1837]);
+ check (i >= 20 && i <= 1837);
+ f4<int> (&a[0], &a[30]);
+ check (i > 40 && i <= 2000 - 64);
+ #pragma omp teams
+ f5 (&a[0], &a[100]);
+ check (i >= 116 && i <= 2000 - 64 && (i - 116) % 10 == 0);
+ f6<-10> (&a[10], &a[110]);
+ check (i >= 116 && i <= 2000 - 64 && (i - 116) % 10 == 0);
+ #pragma omp parallel num_threads(2)
+ f7<6> (I<int> (), &a[12], &a[1800]);
+ check (i >= 2 && i <= 1808 && (i - 2) % 6 == 0);
+ f8<121> (J<int> (&a[14], &a[1803]));
+ check (i >= 14 && i <= 1924 && (i & 1) == 0);
+ #pragma omp teams
+ f9<int, 7> (&a[33], &a[1967]);
+ check (i >= 33 && i <= 1967 && (i - 33) % 7 == 0);
+ f10<int, -7> (&a[1939], &a[17]);
+ check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0);
+ f11<I<int> > (&a[16], &a[1981]);
+ check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0);
+ f12<I<int> > (&a[1761], &a[37]);
+ check (i > 37 && i <= 1761);
+ K<5>::f13<I<int> > (&a[1], &a[1935]);
+ check (i >= 1 && i <= 1936 && (i - 1) % 5 == 0);
+ #pragma omp teams
+ f9<long, 7> (&b[33], &b[1967]);
+ check (i >= 33 && i <= 1967 && (i - 33) % 7 == 0);
+ f10<long, -7> (&b[1939], &b[17]);
+ check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0);
+ f11<I<long> > (&b[16], &b[1981]);
+ check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0);
+ f12<I<long> > (&b[1761], &b[37]);
+ check (i > 37 && i <= 1761);
+ K<5>::f13<I<long> > (&b[1], &b[1935]);
+ check (i >= 1 && i <= 1936 && (i - 1) % 5 == 0);
+}
diff --git a/libgomp/testsuite/libgomp.c++/loop-14.C b/libgomp/testsuite/libgomp.c++/loop-14.C
new file mode 100644
index 0000000..191ab68
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/loop-14.C
@@ -0,0 +1,301 @@
+// { dg-do run }
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+extern "C" void abort ();
+
+template <typename T>
+class I
+{
+public:
+ typedef ptrdiff_t difference_type;
+ I ();
+ ~I ();
+ I (T *);
+ I (const I &);
+ T &operator * ();
+ T *operator -> ();
+ T &operator [] (const difference_type &) const;
+ I &operator = (const I &);
+ I &operator ++ ();
+ I operator ++ (int);
+ I &operator -- ();
+ I operator -- (int);
+ I &operator += (const difference_type &);
+ I &operator -= (const difference_type &);
+ I operator + (const difference_type &) const;
+ I operator - (const difference_type &) const;
+ template <typename S> friend bool operator == (I<S> &, I<S> &);
+ template <typename S> friend bool operator == (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator < (I<S> &, I<S> &);
+ template <typename S> friend bool operator < (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator <= (I<S> &, I<S> &);
+ template <typename S> friend bool operator <= (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator > (I<S> &, I<S> &);
+ template <typename S> friend bool operator > (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator >= (I<S> &, I<S> &);
+ template <typename S> friend bool operator >= (const I<S> &, const I<S> &);
+ template <typename S> friend typename I<S>::difference_type operator - (I<S> &, I<S> &);
+ template <typename S> friend typename I<S>::difference_type operator - (const I<S> &, const I<S> &);
+ template <typename S> friend I<S> operator + (typename I<S>::difference_type , const I<S> &);
+private:
+ T *p;
+};
+template <typename T> I<T>::I () : p (0) {}
+template <typename T> I<T>::~I () { p = (T *) 0; }
+template <typename T> I<T>::I (T *x) : p (x) {}
+template <typename T> I<T>::I (const I &x) : p (x.p) {}
+template <typename T> T &I<T>::operator * () { return *p; }
+template <typename T> T *I<T>::operator -> () { return p; }
+template <typename T> T &I<T>::operator [] (const difference_type &x) const { return p[x]; }
+template <typename T> I<T> &I<T>::operator = (const I &x) { p = x.p; return *this; }
+template <typename T> I<T> &I<T>::operator ++ () { ++p; return *this; }
+template <typename T> I<T> I<T>::operator ++ (int) { return I (p++); }
+template <typename T> I<T> &I<T>::operator -- () { --p; return *this; }
+template <typename T> I<T> I<T>::operator -- (int) { return I (p--); }
+template <typename T> I<T> &I<T>::operator += (const difference_type &x) { p += x; return *this; }
+template <typename T> I<T> &I<T>::operator -= (const difference_type &x) { p -= x; return *this; }
+template <typename T> I<T> I<T>::operator + (const difference_type &x) const { return I (p + x); }
+template <typename T> I<T> I<T>::operator - (const difference_type &x) const { return I (p - x); }
+template <typename T> bool operator == (I<T> &x, I<T> &y) { return x.p == y.p; }
+template <typename T> bool operator == (const I<T> &x, const I<T> &y) { return x.p == y.p; }
+template <typename T> bool operator != (I<T> &x, I<T> &y) { return !(x == y); }
+template <typename T> bool operator != (const I<T> &x, const I<T> &y) { return !(x == y); }
+template <typename T> bool operator < (I<T> &x, I<T> &y) { return x.p < y.p; }
+template <typename T> bool operator < (const I<T> &x, const I<T> &y) { return x.p < y.p; }
+template <typename T> bool operator <= (I<T> &x, I<T> &y) { return x.p <= y.p; }
+template <typename T> bool operator <= (const I<T> &x, const I<T> &y) { return x.p <= y.p; }
+template <typename T> bool operator > (I<T> &x, I<T> &y) { return x.p > y.p; }
+template <typename T> bool operator > (const I<T> &x, const I<T> &y) { return x.p > y.p; }
+template <typename T> bool operator >= (I<T> &x, I<T> &y) { return x.p >= y.p; }
+template <typename T> bool operator >= (const I<T> &x, const I<T> &y) { return x.p >= y.p; }
+template <typename T> typename I<T>::difference_type operator - (I<T> &x, I<T> &y) { return x.p - y.p; }
+template <typename T> typename I<T>::difference_type operator - (const I<T> &x, const I<T> &y) { return x.p - y.p; }
+template <typename T> I<T> operator + (typename I<T>::difference_type x, const I<T> &y) { return I<T> (x + y.p); }
+
+template <typename T>
+class J
+{
+public:
+ J(const I<T> &x, const I<T> &y) : b (x), e (y) {}
+ const I<T> &begin ();
+ const I<T> &end ();
+private:
+ I<T> b, e;
+};
+
+template <typename T> const I<T> &J<T>::begin () { return b; }
+template <typename T> const I<T> &J<T>::end () { return e; }
+
+int results[2000];
+
+template <typename T>
+static inline void
+baz (I<T> &i)
+{
+ results[*i]++;
+}
+
+I<int>
+f1 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp parallel shared (i)
+ {
+ #pragma omp loop lastprivate (i) order(concurrent)
+ for (i = x; i < y - 1; ++i)
+ baz (i);
+ #pragma omp single
+ i += 3;
+ }
+ return I<int> (i);
+}
+
+I<int>
+f2 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp parallel loop bind(parallel)
+ for (i = x; i < y - 1; i = 1 - 6 + 7 + i)
+ baz (i);
+ return I<int> (i);
+}
+
+template <typename T>
+I<int>
+f3 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp teams
+ #pragma omp loop order(concurrent)
+ for (i = x + 1000 - 64; i <= y - 10; i++)
+ baz (i);
+ return i;
+}
+
+template <typename T>
+I<int>
+f4 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp teams loop lastprivate (i)
+ for (i = x + 2000 - 64; i > y + 10; --i)
+ baz (i);
+ return I<int> (i);
+}
+
+template <typename T>
+I<int>
+f5 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp loop lastprivate (i) bind(thread)
+ for (i = x; i > y + T (6); i--)
+ baz (i);
+ return i;
+}
+
+template <typename T>
+I<int>
+f6 (const I<int> &x, const I<int> &y)
+{
+ I<int> i;
+#pragma omp loop bind(thread)
+ for (i = x - T (7); i > y; i -= T (2))
+ baz (i);
+ return I<int> (i);
+}
+
+template <int N>
+I<int>
+f7 (I<int> i, const I<int> &x, const I<int> &y)
+{
+#pragma omp parallel for lastprivate (i)
+ for (i = x - 10; i <= y + 10; i += N)
+ baz (i);
+ return I<int> (i);
+}
+
+template <int N>
+I<int>
+f8 (J<int> j)
+{
+ I<int> i;
+#pragma omp parallel shared (i)
+ #pragma omp loop lastprivate (i)
+ for (i = j.begin (); i <= j.end () + N; i += 2)
+ baz (i);
+ return i;
+}
+
+I<int> i9;
+
+template <long N>
+I<int> &
+f9 (J<int> j)
+{
+#pragma omp loop bind(parallel)
+ for (i9 = j.begin () + N; i9 <= j.end () - N; i9 = i9 - N)
+ baz (i9);
+ return i9;
+}
+
+template <typename T, int N>
+I<T>
+f10 (const I<T> &x, const I<T> &y)
+{
+ I<T> i;
+#pragma omp parallel loop lastprivate (i)
+ for (i = x; i > y; i = i + N)
+ baz (i);
+ return i;
+}
+
+template <typename T, typename U>
+T
+f11 (T i, const T &x, const T &y)
+{
+ #pragma omp loop bind(thread)
+ for (i = x + U (2); i <= y + U (1); i = U (2) + U (3) + i)
+ baz (i);
+ return T (i);
+}
+
+template <typename T>
+T
+f12 (const T &x, const T &y)
+{
+ T i;
+#pragma omp teams loop
+ for (i = x; i > y; --i)
+ baz (i);
+ return i;
+}
+
+#define check(expr) \
+ for (int i = 0; i < 2000; i++) \
+ if (expr) \
+ { \
+ if (results[i] != 1) \
+ abort (); \
+ results[i] = 0; \
+ } \
+ else if (results[i]) \
+ abort ()
+
+int
+main ()
+{
+ int a[2000];
+ long b[2000];
+ for (int i = 0; i < 2000; i++)
+ {
+ a[i] = i;
+ b[i] = i;
+ }
+ if (*f1 (&a[10], &a[1873]) != 1875)
+ abort ();
+ check (i >= 10 && i < 1872);
+ if (*f2 (&a[0], &a[1998]) != 1998)
+ abort ();
+ check (i < 1997 && (i & 1) == 0);
+ if (*f3<int> (&a[10], &a[1971]) != 1962)
+ abort ();
+ check (i >= 946 && i <= 1961);
+ if (*f4<int> (&a[0], &a[30]) != 40)
+ abort ();
+ check (i > 40 && i <= 2000 - 64);
+ if (*f5<short> (&a[1931], &a[17]) != 23)
+ abort ();
+ check (i > 23 && i <= 1931);
+ if (*f6<long> (&a[1931], &a[17]) != 16)
+ abort ();
+ check (i > 17 && i <= 1924 && (i & 1) == 0);
+ if (*f7<6> (I<int> (), &a[12], &a[1800]) != 1814)
+ abort ();
+ check (i >= 2 && i <= 1808 && (i - 2) % 6 == 0);
+ if (*f8<121> (J<int> (&a[14], &a[1803])) != 1926)
+ abort ();
+ check (i >= 14 && i <= 1924 && (i & 1) == 0);
+ #pragma omp parallel
+ if (*f9<-3L> (J<int> (&a[27], &a[1761])) != 1767)
+ abort ();
+ check (i >= 24 && i <= 1764 && (i % 3) == 0);
+ if (*f10<int, -7> (&a[1939], &a[17]) != 14)
+ abort ();
+ check (i >= 21 && i <= 1939 && i % 7 == 0);
+ if (*f11<I<int>, short> (I<int> (), &a[71], &a[1941]) != 1943)
+ abort ();
+ check (i >= 73 && i <= 1938 && (i - 73) % 5 == 0);
+ if (*f12<I<int> > (&a[1761], &a[37]) != 37)
+ abort ();
+ check (i > 37 && i <= 1761);
+ if (*f10<long, -7> (&b[1939], &b[17]) != 14)
+ abort ();
+ check (i >= 21 && i <= 1939 && i % 7 == 0);
+ if (*f11<I<long>, short> (I<long> (), &b[71], &b[1941]) != 1943)
+ abort ();
+ check (i >= 73 && i <= 1938 && (i - 73) % 5 == 0);
+ if (*f12<I<long> > (&b[1761], &b[37]) != 37)
+ abort ();
+ check (i > 37 && i <= 1761);
+}
diff --git a/libgomp/testsuite/libgomp.c++/loop-15.C b/libgomp/testsuite/libgomp.c++/loop-15.C
new file mode 100644
index 0000000..b523b9b
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/loop-15.C
@@ -0,0 +1,417 @@
+// { dg-do run }
+// { dg-additional-options "-std=c++17" }
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+extern "C" void abort ();
+
+namespace std {
+ template<typename T> struct tuple_size;
+ template<int, typename> struct tuple_element;
+}
+
+template <typename T>
+class I
+{
+public:
+ typedef ptrdiff_t difference_type;
+ I ();
+ ~I ();
+ I (T *);
+ I (const I &);
+ T &operator * ();
+ T *operator -> ();
+ T &operator [] (const difference_type &) const;
+ I &operator = (const I &);
+ I &operator ++ ();
+ I operator ++ (int);
+ I &operator -- ();
+ I operator -- (int);
+ I &operator += (const difference_type &);
+ I &operator -= (const difference_type &);
+ I operator + (const difference_type &) const;
+ I operator - (const difference_type &) const;
+ template <typename S> friend bool operator == (I<S> &, I<S> &);
+ template <typename S> friend bool operator == (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator < (I<S> &, I<S> &);
+ template <typename S> friend bool operator < (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator <= (I<S> &, I<S> &);
+ template <typename S> friend bool operator <= (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator > (I<S> &, I<S> &);
+ template <typename S> friend bool operator > (const I<S> &, const I<S> &);
+ template <typename S> friend bool operator >= (I<S> &, I<S> &);
+ template <typename S> friend bool operator >= (const I<S> &, const I<S> &);
+ template <typename S> friend typename I<S>::difference_type operator - (I<S> &, I<S> &);
+ template <typename S> friend typename I<S>::difference_type operator - (const I<S> &, const I<S> &);
+ template <typename S> friend I<S> operator + (typename I<S>::difference_type , const I<S> &);
+private:
+ T *p;
+};
+template <typename T> I<T>::I () : p (0) {}
+template <typename T> I<T>::~I () {}
+template <typename T> I<T>::I (T *x) : p (x) {}
+template <typename T> I<T>::I (const I &x) : p (x.p) {}
+template <typename T> T &I<T>::operator * () { return *p; }
+template <typename T> T *I<T>::operator -> () { return p; }
+template <typename T> T &I<T>::operator [] (const difference_type &x) const { return p[x]; }
+template <typename T> I<T> &I<T>::operator = (const I &x) { p = x.p; return *this; }
+template <typename T> I<T> &I<T>::operator ++ () { ++p; return *this; }
+template <typename T> I<T> I<T>::operator ++ (int) { return I (p++); }
+template <typename T> I<T> &I<T>::operator -- () { --p; return *this; }
+template <typename T> I<T> I<T>::operator -- (int) { return I (p--); }
+template <typename T> I<T> &I<T>::operator += (const difference_type &x) { p += x; return *this; }
+template <typename T> I<T> &I<T>::operator -= (const difference_type &x) { p -= x; return *this; }
+template <typename T> I<T> I<T>::operator + (const difference_type &x) const { return I (p + x); }
+template <typename T> I<T> I<T>::operator - (const difference_type &x) const { return I (p - x); }
+template <typename T> bool operator == (I<T> &x, I<T> &y) { return x.p == y.p; }
+template <typename T> bool operator == (const I<T> &x, const I<T> &y) { return x.p == y.p; }
+template <typename T> bool operator != (I<T> &x, I<T> &y) { return !(x == y); }
+template <typename T> bool operator != (const I<T> &x, const I<T> &y) { return !(x == y); }
+template <typename T> bool operator < (I<T> &x, I<T> &y) { return x.p < y.p; }
+template <typename T> bool operator < (const I<T> &x, const I<T> &y) { return x.p < y.p; }
+template <typename T> bool operator <= (I<T> &x, I<T> &y) { return x.p <= y.p; }
+template <typename T> bool operator <= (const I<T> &x, const I<T> &y) { return x.p <= y.p; }
+template <typename T> bool operator > (I<T> &x, I<T> &y) { return x.p > y.p; }
+template <typename T> bool operator > (const I<T> &x, const I<T> &y) { return x.p > y.p; }
+template <typename T> bool operator >= (I<T> &x, I<T> &y) { return x.p >= y.p; }
+template <typename T> bool operator >= (const I<T> &x, const I<T> &y) { return x.p >= y.p; }
+template <typename T> typename I<T>::difference_type operator - (I<T> &x, I<T> &y) { return x.p - y.p; }
+template <typename T> typename I<T>::difference_type operator - (const I<T> &x, const I<T> &y) { return x.p - y.p; }
+template <typename T> I<T> operator + (typename I<T>::difference_type x, const I<T> &y) { return I<T> (x + y.p); }
+
+template <typename T>
+class J
+{
+public:
+ J(const I<T> &x, const I<T> &y) : b (x), e (y) {}
+ const I<T> &begin ();
+ const I<T> &end ();
+private:
+ I<T> b, e;
+};
+
+template <typename T> const I<T> &J<T>::begin () { return b; }
+template <typename T> const I<T> &J<T>::end () { return e; }
+
+template <typename T>
+class K
+{
+public:
+ K ();
+ ~K ();
+ template <int N> T &get () { if (N == 0) return c; else if (N == 1) return b; return a; }
+ T a, b, c;
+};
+
+template <typename T> K<T>::K () : a {}, b {}, c {} {}
+template <typename T> K<T>::~K () {}
+template <typename T> struct std::tuple_size<K<T>> { static constexpr int value = 3; };
+template <typename T, int N> struct std::tuple_element<N, K<T>> { using type = T; };
+
+template <typename T>
+class L
+{
+public:
+ L ();
+ ~L ();
+ T a, b, c;
+};
+
+template <typename T> L<T>::L () : a {}, b {}, c {} {}
+template <typename T> L<T>::~L () {}
+
+int a[2000];
+long b[40];
+short c[50];
+int d[1024];
+K<int> e[1089];
+L<int> f[1093];
+int results[2000];
+
+template <typename T>
+static inline void
+baz (I<T> &i)
+{
+ results[*i]++;
+}
+
+static inline void
+baz (int i)
+{
+ results[i]++;
+}
+
+void
+f1 ()
+{
+#pragma omp parallel loop shared(a) default(none)
+ for (auto i : a)
+ baz (i);
+}
+
+void
+f2 ()
+{
+#pragma omp loop order(concurrent) bind(parallel)
+ for (auto &i : a)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+void
+f3 ()
+{
+#pragma omp teams loop collapse(3) default(none) shared(b, c)
+ for (auto &i : b)
+ for (int j = 9; j < 10; j++)
+ for (auto k : c)
+ if (&i != &b[i] || i < 0 || i >= 40 || j != 9 || k < 0 || k >= 50)
+ abort ();
+ else
+ baz (i * 50 + k);
+}
+
+void
+f4 (J<int> j)
+{
+#pragma omp loop bind(teams)
+ for (auto &i : j)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+void
+f5 ()
+{
+#pragma omp loop bind(thread)
+ for (auto i : d)
+ results[i % 1024] += 2 * ((unsigned) i >> 10) + 1;
+}
+
+void
+f6 (J<K<int>> j)
+{
+#pragma omp loop bind(parallel)
+ for (auto & [k, l, m] : j)
+ if (&k != &e[m].c || &l != &e[m].b || &m != &e[m].a || k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+void
+f7 (J<L<int>> j)
+{
+#pragma omp parallel loop default(none) shared(j, f)
+ for (auto & [k, l, m] : j)
+ if (&k != &f[k].a || &l != &f[k].b || &m != &f[k].c || l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+void
+f8 (J<K<int>> j)
+{
+#pragma omp parallel loop default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+void
+f9 (J<L<int>> j)
+{
+#pragma omp teams loop default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+template <int N>
+void
+f10 ()
+{
+#pragma omp loop bind(teams)
+ for (auto i : a)
+ baz (i);
+}
+
+template <int N>
+void
+f11 ()
+{
+#pragma omp loop bind(thread)
+ for (auto &i : a)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+template <int N>
+void
+f12 ()
+{
+#pragma omp parallel loop collapse(3) default(none) shared(a, b, c) bind(parallel)
+ for (auto &i : b)
+ for (I<int> j = I<int> (&a[9]); j < I<int> (&a[10]); j++)
+ for (auto k : c)
+ if (&i != &b[i] || i < 0 || i >= 40 || *j != 9 || k < 0 || k >= 50)
+ abort ();
+ else
+ baz (i * 50 + k);
+}
+
+template <typename T>
+void
+f13 (J<T> j)
+{
+#pragma omp loop bind(thread)
+ for (auto &i : j)
+ if (&i != &a[i])
+ abort ();
+ else
+ baz (i);
+}
+
+template <int N>
+void
+f14 ()
+{
+#pragma omp parallel loop default(none) shared(d, results)
+ for (auto i : d)
+ results[i % N] += 2 * ((unsigned) i >> 10) + 1;
+}
+
+template <typename T>
+void
+f15 (J<K<T>> j)
+{
+#pragma omp parallel loop default(none) shared(j, e) bind(parallel)
+ for (auto & [k, l, m] : j)
+ if (&k != &e[m].c || &l != &e[m].b || &m != &e[m].a || k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+template <typename T>
+void
+f16 (J<L<T>> j)
+{
+#pragma omp loop bind(parallel)
+ for (auto & [k, l, m] : j)
+ if (&k != &f[k].a || &l != &f[k].b || &m != &f[k].c || l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+template <int N>
+void
+f17 (J<K<int>> j)
+{
+#pragma omp parallel loop default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (k != m * 3 || l != m * 2)
+ abort ();
+ else
+ baz (m);
+}
+
+template <int N>
+void
+f18 (J<L<int>> j)
+{
+#pragma omp teams loop default(none) shared(j)
+ for (auto [k, l, m] : j)
+ if (l != k * 4 || m != k * 5)
+ abort ();
+ else
+ baz (k);
+}
+
+#define check(expr) \
+ for (int i = 0; i < 2000; i++) \
+ if (expr) \
+ { \
+ if (results[i] != 1) \
+ abort (); \
+ results[i] = 0; \
+ } \
+ else if (results[i]) \
+ abort ()
+
+int
+main ()
+{
+ for (int i = 0; i < 2000; i++)
+ a[i] = i;
+ for (int i = 0; i < 40; i++)
+ b[i] = i;
+ for (int i = 0; i < 50; i++)
+ c[i] = i;
+ for (int i = 0; i < 1024; i++)
+ d[i] = i;
+ for (int i = 0; i < 1089; i++)
+ {
+ e[i].a = i;
+ e[i].b = 2 * i;
+ e[i].c = 3 * i;
+ }
+ for (int i = 0; i < 1093; i++)
+ {
+ f[i].a = i;
+ f[i].b = 4 * i;
+ f[i].c = 5 * i;
+ }
+ f1 ();
+ check (1);
+ #pragma omp parallel
+ f2 ();
+ check (1);
+ f3 ();
+ check (1);
+ #pragma omp teams
+ f4 (J<int> (&a[14], &a[1803]));
+ check (i >= 14 && i < 1803);
+ f5 ();
+ check (i >= 0 && i < 1024);
+ #pragma omp parallel
+ f6 (J<K<int>> (&e[19], &e[1029]));
+ check (i >= 19 && i < 1029);
+ f7 (J<L<int>> (&f[15], &f[1091]));
+ check (i >= 15 && i < 1091);
+ f8 (J<K<int>> (&e[27], &e[1037]));
+ check (i >= 27 && i < 1037);
+ f9 (J<L<int>> (&f[1], &f[1012]));
+ check (i >= 1 && i < 1012);
+ #pragma omp teams
+ f10 <0> ();
+ check (1);
+ f11 <1> ();
+ check (1);
+ f12 <2> ();
+ check (1);
+ f13 (J<int> (&a[24], &a[1703]));
+ check (i >= 24 && i < 1703);
+ f14 <1024> ();
+ check (i >= 0 && i < 1024);
+ f15 (J<K<int>> (&e[39], &e[929]));
+ check (i >= 39 && i < 929);
+ #pragma omp parallel
+ f16 (J<L<int>> (&f[17], &f[1071]));
+ check (i >= 17 && i < 1071);
+ f17 <3> (J<K<int>> (&e[7], &e[1017]));
+ check (i >= 7 && i < 1017);
+ f18 <5> (J<L<int>> (&f[121], &f[1010]));
+ check (i >= 121 && i < 1010);
+}
diff --git a/libgomp/testsuite/libgomp.c++/target-22.C b/libgomp/testsuite/libgomp.c++/target-22.C
new file mode 100644
index 0000000..9d9dea0
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c++/target-22.C
@@ -0,0 +1,99 @@
+extern "C" void abort (void);
+struct S { int e, f; };
+
+void
+foo (int *&p, int (&s)[5], int &t, S &u, int n)
+{
+ int a[4] = { 7, 8, 9, 10 }, b[n], c[3] = { 20, 21, 22 };
+ int *r = a + 1, *q = p - 1, i, err;
+ int v = 27;
+ S w = { 28, 29 };
+ for (i = 0; i < n; i++)
+ b[i] = 9 + i;
+ #pragma omp target data map(to:a) use_device_ptr(r) map(from:err)
+ #pragma omp target is_device_ptr(r) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < 4; i++)
+ if (r[i - 1] != 7 + i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ #pragma omp target data use_device_ptr(p) map(from:err) map(to:q[:4])
+ #pragma omp target is_device_ptr(p) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < 4; i++)
+ if (p[i - 1] != i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ #pragma omp target data map(to:b) use_device_addr(b) map(from:err)
+ #pragma omp target is_device_ptr(b) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < n; i++)
+ if (b[i] != 9 + i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ #pragma omp target data use_device_addr(c) map(to:c) map(from:err)
+ #pragma omp target is_device_ptr(c) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < 3; i++)
+ if (c[i] != 20 + i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ #pragma omp target data map(to:s[:5]) use_device_addr(s) map(from:err)
+ #pragma omp target is_device_ptr(s) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < 5; i++)
+ if (s[i] != 17 + i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ #pragma omp target data use_device_addr (v) map(to: v) map(to:u) use_device_addr (u) map(from:err)
+ {
+ int *z = &v;
+ S *x = &u;
+ #pragma omp target is_device_ptr (z, x) map(from:err)
+ {
+ err = 0;
+ if (*z != 27 || x->e != 25 || x->f != 26)
+ err = 1;
+ }
+ }
+ if (err)
+ abort ();
+ #pragma omp target data map(to: t) use_device_addr (t, w) map (to: w) map(from:err)
+ {
+ int *z = &t;
+ S *x = &w;
+ #pragma omp target is_device_ptr (z) is_device_ptr (x) map(from:err)
+ {
+ err = 0;
+ if (*z != 24 || x->e != 28 || x->f != 29)
+ err = 1;
+ }
+ }
+ if (err)
+ abort ();
+}
+
+int
+main ()
+{
+ int a[4] = { 0, 1, 2, 3 }, b[5] = { 17, 18, 19, 20, 21 };
+ int *p = a + 1;
+ int t = 24;
+ S u = { 25, 26 };
+ foo (p, b, t, u, 9);
+}
diff --git a/libgomp/testsuite/libgomp.c++/target-9.C b/libgomp/testsuite/libgomp.c++/target-9.C
index a5d171b..83a61cf 100644
--- a/libgomp/testsuite/libgomp.c++/target-9.C
+++ b/libgomp/testsuite/libgomp.c++/target-9.C
@@ -1,10 +1,13 @@
extern "C" void abort (void);
+struct S { int e, f; };
void
-foo (int *&p, int (&s)[5], int n)
+foo (int *&p, int (&s)[5], int &t, S &u, int n)
{
int a[4] = { 7, 8, 9, 10 }, b[n], c[3] = { 20, 21, 22 };
int *r = a + 1, *q = p - 1, i, err;
+ int v = 27;
+ S w = { 28, 29 };
for (i = 0; i < n; i++)
b[i] = 9 + i;
#pragma omp target data map(to:a)
@@ -30,7 +33,7 @@ foo (int *&p, int (&s)[5], int n)
if (err)
abort ();
#pragma omp target data map(to:b)
- #pragma omp target data use_device_ptr(b) map(from:err)
+ #pragma omp target data use_device_addr(b) map(from:err)
#pragma omp target is_device_ptr(b) private(i) map(from:err)
{
err = 0;
@@ -41,7 +44,7 @@ foo (int *&p, int (&s)[5], int n)
if (err)
abort ();
#pragma omp target data map(to:c)
- #pragma omp target data use_device_ptr(c) map(from:err)
+ #pragma omp target data use_device_addr(c) map(from:err)
#pragma omp target is_device_ptr(c) private(i) map(from:err)
{
err = 0;
@@ -52,7 +55,7 @@ foo (int *&p, int (&s)[5], int n)
if (err)
abort ();
#pragma omp target data map(to:s[:5])
- #pragma omp target data use_device_ptr(s) map(from:err)
+ #pragma omp target data use_device_addr(s) map(from:err)
#pragma omp target is_device_ptr(s) private(i) map(from:err)
{
err = 0;
@@ -62,6 +65,34 @@ foo (int *&p, int (&s)[5], int n)
}
if (err)
abort ();
+ #pragma omp target data map(to: v) map(to:u)
+ #pragma omp target data use_device_addr (v) use_device_addr (u) map(from:err)
+ {
+ int *z = &v;
+ S *x = &u;
+ #pragma omp target is_device_ptr (z, x) map(from:err)
+ {
+ err = 0;
+ if (*z != 27 || x->e != 25 || x->f != 26)
+ err = 1;
+ }
+ }
+ if (err)
+ abort ();
+ #pragma omp target data map(to: t, w)
+ #pragma omp target data use_device_addr (t, w) map(from:err)
+ {
+ int *z = &t;
+ S *x = &w;
+ #pragma omp target is_device_ptr (z) is_device_ptr (x) map(from:err)
+ {
+ err = 0;
+ if (*z != 24 || x->e != 28 || x->f != 29)
+ err = 1;
+ }
+ }
+ if (err)
+ abort ();
}
int
@@ -69,5 +100,7 @@ main ()
{
int a[4] = { 0, 1, 2, 3 }, b[5] = { 17, 18, 19, 20, 21 };
int *p = a + 1;
- foo (p, b, 9);
+ int t = 24;
+ S u = { 25, 26 };
+ foo (p, b, t, u, 9);
}
diff --git a/libgomp/testsuite/libgomp.c/target-18.c b/libgomp/testsuite/libgomp.c/target-18.c
index cbacaf6..dd511fb 100644
--- a/libgomp/testsuite/libgomp.c/target-18.c
+++ b/libgomp/testsuite/libgomp.c/target-18.c
@@ -1,9 +1,11 @@
extern void abort (void);
+struct S { int e, f; };
void
foo (int n)
{
- int a[4] = { 0, 1, 2, 3 }, b[n];
+ int a[4] = { 0, 1, 2, 3 }, b[n], c = 4;
+ struct S d = { 5, 6 };
int *p = a + 1, i, err;
for (i = 0; i < n; i++)
b[i] = 9 + i;
@@ -21,7 +23,7 @@ foo (int n)
for (i = 0; i < 4; i++)
a[i] = 23 + i;
#pragma omp target data map(to:a)
- #pragma omp target data use_device_ptr(a) map(from:err)
+ #pragma omp target data use_device_addr(a) map(from:err)
#pragma omp target is_device_ptr(a) private(i) map(from:err)
{
err = 0;
@@ -32,7 +34,7 @@ foo (int n)
if (err)
abort ();
#pragma omp target data map(to:b)
- #pragma omp target data use_device_ptr(b) map(from:err)
+ #pragma omp target data use_device_addr(b) map(from:err)
#pragma omp target is_device_ptr(b) private(i) map(from:err)
{
err = 0;
@@ -42,6 +44,28 @@ foo (int n)
}
if (err)
abort ();
+ #pragma omp target data map(to:c)
+ #pragma omp target data use_device_addr(c) map(from:err)
+ {
+ int *q = &c;
+ #pragma omp target is_device_ptr(q) map(from:err)
+ {
+ err = *q != 4;
+ }
+ }
+ if (err)
+ abort ();
+ #pragma omp target data map(to:d)
+ #pragma omp target data use_device_addr(d) map(from:err)
+ {
+ struct S *r = &d;
+ #pragma omp target is_device_ptr(r) map(from:err)
+ {
+ err = r->e != 5 || r->f != 6;
+ }
+ }
+ if (err)
+ abort ();
}
int
diff --git a/libgomp/testsuite/libgomp.c/target-37.c b/libgomp/testsuite/libgomp.c/target-37.c
new file mode 100644
index 0000000..b3cc6a2
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/target-37.c
@@ -0,0 +1,71 @@
+extern void abort (void);
+struct S { int e, f; };
+
+void
+foo (int n)
+{
+ int a[4] = { 0, 1, 2, 3 }, b[n], c = 4;
+ struct S d = { 5, 6 };
+ int *p = a + 1, i, err;
+ for (i = 0; i < n; i++)
+ b[i] = 9 + i;
+ #pragma omp target data use_device_ptr(p) map(from:err) map(to:a)
+ #pragma omp target is_device_ptr(p) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < 4; i++)
+ if (p[i - 1] != i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ for (i = 0; i < 4; i++)
+ a[i] = 23 + i;
+ #pragma omp target data map(to:a) use_device_addr(a) map(from:err)
+ #pragma omp target is_device_ptr(a) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < 4; i++)
+ if (a[i] != 23 + i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ #pragma omp target data use_device_addr(b) map(from:err) map(to:b)
+ #pragma omp target is_device_ptr(b) private(i) map(from:err)
+ {
+ err = 0;
+ for (i = 0; i < 4; i++)
+ if (b[i] != 9 + i)
+ err = 1;
+ }
+ if (err)
+ abort ();
+ #pragma omp target data map(to:c) use_device_addr(c) map(from:err)
+ {
+ int *q = &c;
+ #pragma omp target is_device_ptr(q) map(from:err)
+ {
+ err = *q != 4;
+ }
+ }
+ if (err)
+ abort ();
+ #pragma omp target data use_device_addr(d) map(to:d) map(from:err)
+ {
+ struct S *r = &d;
+ #pragma omp target is_device_ptr(r) map(from:err)
+ {
+ err = r->e != 5 || r->f != 6;
+ }
+ }
+ if (err)
+ abort ();
+}
+
+int
+main ()
+{
+ foo (9);
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.fortran/appendix-a/a.28.5.f90 b/libgomp/testsuite/libgomp.fortran/appendix-a/a.28.5.f90
index 08de997..a3f56dd4 100644
--- a/libgomp/testsuite/libgomp.fortran/appendix-a/a.28.5.f90
+++ b/libgomp/testsuite/libgomp.fortran/appendix-a/a.28.5.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
-! { dg-options "-w" }
+! { dg-options "-w -std=legacy" }
!
! "-w" added as libgomp/testsuite seemingly cannot parse with
! dg-warning Fortran's output. Fortran warns for "call sub1(a)"
diff --git a/libgomp/testsuite/libgomp.fortran/reduction4.f90 b/libgomp/testsuite/libgomp.fortran/reduction4.f90
index 91c7fc8..498d546 100644
--- a/libgomp/testsuite/libgomp.fortran/reduction4.f90
+++ b/libgomp/testsuite/libgomp.fortran/reduction4.f90
@@ -4,12 +4,12 @@
integer (kind = 4) :: i, ia (6), j, ja (6), k, ka (6), ta (6), n, cnt, x
logical :: v
- i = Z'ffff0f'
- ia = Z'f0ff0f'
- j = Z'0f0000'
- ja = Z'0f5a00'
- k = Z'055aa0'
- ka = Z'05a5a5'
+ i = int(Z'ffff0f')
+ ia = int(Z'f0ff0f')
+ j = int(Z'0f0000')
+ ja = int(Z'0f5a00')
+ k = int(Z'055aa0')
+ ka = int(Z'05a5a5')
v = .false.
cnt = -1
x = not(0)
@@ -22,35 +22,35 @@
n = omp_get_thread_num ()
if (n .eq. 0) then
cnt = omp_get_num_threads ()
- i = Z'ff7fff'
- ia(3:5) = Z'fffff1'
- j = Z'078000'
+ i = int(Z'ff7fff')
+ ia(3:5) = int(Z'fffff1')
+ j = int(Z'078000')
ja(1:3) = 1
- k = Z'78'
- ka(3:6) = Z'f0f'
+ k = int(Z'78')
+ ka(3:6) = int(Z'f0f')
else if (n .eq. 1) then
- i = Z'ffff77'
- ia(2:5) = Z'ffafff'
- j = Z'007800'
+ i = int(Z'ffff77')
+ ia(2:5) = int(Z'ffafff')
+ j = int(Z'007800')
ja(2:5) = 8
- k = Z'57'
- ka(3:4) = Z'f0108'
+ k = int(Z'57')
+ ka(3:4) = int(Z'f0108')
else
- i = Z'777fff'
- ia(1:2) = Z'fffff3'
- j = Z'000780'
- ja(5:6) = Z'f00'
- k = Z'1000'
- ka(6:6) = Z'777'
+ i = int(Z'777fff')
+ ia(1:2) = int(Z'fffff3')
+ j = int(Z'000780')
+ ja(5:6) = int(Z'f00')
+ k = int(Z'1000')
+ ka(6:6) = int(Z'777')
end if
!$omp end parallel
if (v) STOP 1
if (cnt .eq. 3) then
- ta = (/Z'f0ff03', Z'f0af03', Z'f0af01', Z'f0af01', Z'f0af01', Z'f0ff0f'/)
- if (i .ne. Z'777f07' .or. any (ia .ne. ta)) STOP 2
- ta = (/Z'f5a01', Z'f5a09', Z'f5a09', Z'f5a08', Z'f5f08', Z'f5f00'/)
- if (j .ne. Z'fff80' .or. any (ja .ne. ta)) STOP 3
- ta = (/Z'5a5a5', Z'5a5a5', Z'aaba2', Z'aaba2', Z'5aaaa', Z'5addd'/)
- if (k .ne. Z'54a8f' .or. any (ka .ne. ta)) STOP 4
+ ta = (/int(Z'f0ff03'), int(Z'f0af03'), int(Z'f0af01'), int(Z'f0af01'), int(Z'f0af01'), int(Z'f0ff0f')/)
+ if (i .ne. int(Z'777f07') .or. any (ia .ne. ta)) STOP 2
+ ta = (/int(Z'f5a01'), int(Z'f5a09'), int(Z'f5a09'), int(Z'f5a08'), int(Z'f5f08'), int(Z'f5f00')/)
+ if (j .ne. int(Z'fff80') .or. any (ja .ne. ta)) STOP 3
+ ta = (/int(Z'5a5a5'), int(Z'5a5a5'), int(Z'aaba2'), int(Z'aaba2'), int(Z'5aaaa'), int(Z'5addd')/)
+ if (k .ne. int(Z'54a8f') .or. any (ka .ne. ta)) STOP 4
end if
end
diff --git a/libgomp/testsuite/libgomp.fortran/reduction5.f90 b/libgomp/testsuite/libgomp.fortran/reduction5.f90
index f8fdcb4..a1d1a8e 100644
--- a/libgomp/testsuite/libgomp.fortran/reduction5.f90
+++ b/libgomp/testsuite/libgomp.fortran/reduction5.f90
@@ -10,15 +10,15 @@ contains
subroutine test1
use reduction5, bitwise_or => ior
integer :: n
- n = Z'f'
+ n = int(Z'f')
!$omp parallel sections num_threads (3) reduction (bitwise_or: n)
- n = ior (n, Z'20')
+ n = ior (n, int(Z'20'))
!$omp section
- n = bitwise_or (Z'410', n)
+ n = bitwise_or (int(Z'410'), n)
!$omp section
- n = bitwise_or (n, Z'2000')
+ n = bitwise_or (n, int(Z'2000'))
!$omp end parallel sections
- if (n .ne. Z'243f') STOP 1
+ if (n .ne. int(Z'243f')) STOP 1
end subroutine
subroutine test2
use reduction5, min => max, max => min
diff --git a/libgomp/testsuite/libgomp.oacc-fortran/routine-7.f90 b/libgomp/testsuite/libgomp.oacc-fortran/routine-7.f90
index f58a95f..1009f4a 100644
--- a/libgomp/testsuite/libgomp.oacc-fortran/routine-7.f90
+++ b/libgomp/testsuite/libgomp.oacc-fortran/routine-7.f90
@@ -109,7 +109,7 @@ end subroutine gang
subroutine seq (a)
!$acc routine seq
- integer, intent (inout) :: a(M)
+ integer, intent (inout) :: a(N)
integer :: i
do i = 1, N
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index ddd9618..c1fe2f6 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,20 @@
+2019-08-12 Martin Liska <mliska@suse.cz>
+
+ * Makefile.in: Add filedescriptor.c.
+ * filedescriptor.c: New file.
+ * lrealpath.c (is_valid_fd): Remove.
+
+2019-08-08 Martin Liska <mliska@suse.cz>
+
+ PR bootstrap/91352
+ * lrealpath.c (is_valid_fd): New function.
+
+2019-07-24 Martin Liska <mliska@suse.cz>
+
+ PR lto/91228
+ * simple-object-elf.c (simple_object_elf_copy_lto_debug_sections):
+ Find first '\0' starting from gnu_lto + 1.
+
2019-07-12 Ren Kimura <rkx1209dev@gmail.com>
* simple-object-elf.c (simple_object_elf_match): Check zero value shstrndx.
diff --git a/libiberty/Makefile.in b/libiberty/Makefile.in
index 0be45b4..f1628d4 100644
--- a/libiberty/Makefile.in
+++ b/libiberty/Makefile.in
@@ -127,7 +127,7 @@ CFILES = alloca.c argv.c asprintf.c atexit.c \
calloc.c choose-temp.c clock.c concat.c cp-demangle.c \
cp-demint.c cplus-dem.c crc32.c \
d-demangle.c dwarfnames.c dyn-string.c \
- fdmatch.c ffs.c fibheap.c filename_cmp.c floatformat.c \
+ fdmatch.c ffs.c fibheap.c filedescriptor.c filename_cmp.c floatformat.c \
fnmatch.c fopen_unlocked.c \
getcwd.c getopt.c getopt1.c getpagesize.c getpwd.c getruntime.c \
gettimeofday.c \
@@ -171,6 +171,7 @@ REQUIRED_OFILES = \
./cp-demint.$(objext) ./crc32.$(objext) ./d-demangle.$(objext) \
./dwarfnames.$(objext) ./dyn-string.$(objext) \
./fdmatch.$(objext) ./fibheap.$(objext) \
+ ./filedescriptor.$(objext) \
./filename_cmp.$(objext) ./floatformat.$(objext) \
./fnmatch.$(objext) ./fopen_unlocked.$(objext) \
./getopt.$(objext) ./getopt1.$(objext) ./getpwd.$(objext) \
@@ -756,6 +757,17 @@ $(CONFIGURED_OFILES): stamp-picdir stamp-noasandir
else true; fi
$(COMPILE.c) $(srcdir)/fibheap.c $(OUTPUT_OPTION)
+./filedescriptor.$(objext): $(srcdir)/filedescriptor.c config.h $(INCDIR)/ansidecl.h \
+ $(INCDIR)/libiberty.h
+ if [ x"$(PICFLAG)" != x ]; then \
+ $(COMPILE.c) $(PICFLAG) $(srcdir)/filedescriptor.c -o pic/$@; \
+ else true; fi
+ if [ x"$(NOASANFLAG)" != x ]; then \
+ $(COMPILE.c) $(PICFLAG) $(NOASANFLAG) $(srcdir)/filedescriptor.c -o noasan/$@; \
+ else true; fi
+ $(COMPILE.c) $(srcdir)/filedescriptor.c $(OUTPUT_OPTION)
+
+
./filename_cmp.$(objext): $(srcdir)/filename_cmp.c config.h $(INCDIR)/ansidecl.h \
$(INCDIR)/filenames.h $(INCDIR)/hashtab.h \
$(INCDIR)/safe-ctype.h
diff --git a/libiberty/filedescriptor.c b/libiberty/filedescriptor.c
new file mode 100644
index 0000000..3a1a68d
--- /dev/null
+++ b/libiberty/filedescriptor.c
@@ -0,0 +1,47 @@
+/* File descriptor related functions.
+
+ Copyright (C) 2019 Free Software Foundation, Inc.
+
+ This file is part of the libiberty library.
+
+ This program 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 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+#include "config.h"
+#include "ansidecl.h"
+#include "libiberty.h"
+
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+
+#if defined (_WIN32)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h> /* for GetFullPathName */
+#endif
+/* Return true when FD file descriptor exists. */
+
+int
+is_valid_fd (int fd)
+{
+#if defined(_WIN32)
+ HANDLE h = (HANDLE) _get_osfhandle (fd);
+ return h != (HANDLE) -1;
+#elif defined(F_GETFD)
+ return fcntl (fd, F_GETFD) >= 0;
+#else
+ return dup2 (fd, fd) < 0;
+#endif
+}
diff --git a/libiberty/simple-object-elf.c b/libiberty/simple-object-elf.c
index bdee963..7515926 100644
--- a/libiberty/simple-object-elf.c
+++ b/libiberty/simple-object-elf.c
@@ -1388,8 +1388,8 @@ simple_object_elf_copy_lto_debug_sections (simple_object_read *sobj,
(unsigned char *)strings,
strsz, &errmsg, err);
/* Find first '\0' in strings. */
- gnu_lto = (char *) memchr (gnu_lto, '\0',
- strings + strsz - gnu_lto + 1);
+ gnu_lto = (char *) memchr (gnu_lto + 1, '\0',
+ strings + strsz - gnu_lto);
/* Read the section index table if present. */
if (symtab_indices_shndx[i - 1] != 0)
{
diff --git a/libquadmath/ChangeLog b/libquadmath/ChangeLog
index cfcea9b..14a19b0 100644
--- a/libquadmath/ChangeLog
+++ b/libquadmath/ChangeLog
@@ -1,3 +1,9 @@
+2019-08-02 Jakub Jelinek <jakub@redhat.com>
+
+ * quadmath.h (M_Eq, M_LOG2Eq, M_LOG10Eq, M_LN2q, M_LN10q, M_PIq,
+ M_PI_2q, M_PI_4q, M_1_PIq, M_2_PIq, M_2_SQRTPIq, M_SQRT2q,
+ M_SQRT1_2q): Use two more decimal places.
+
2019-01-01 Jakub Jelinek <jakub@redhat.com>
Update copyright years.
diff --git a/libquadmath/quadmath.h b/libquadmath/quadmath.h
index 76275b5..81eb957 100644
--- a/libquadmath/quadmath.h
+++ b/libquadmath/quadmath.h
@@ -1,5 +1,5 @@
/* GCC Quad-Precision Math Library
- Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2010-2019 Free Software Foundation, Inc.
Written by Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
This file is part of the libquadmath library.
@@ -165,19 +165,19 @@ extern int quadmath_snprintf (char *str, size_t size,
(floating constant exceeds range of ‘__float128’) */
/* #define HUGE_VALQ (__extension__ 0x1.0p32767Q) */
-#define M_Eq 2.7182818284590452353602874713526625Q /* e */
-#define M_LOG2Eq 1.4426950408889634073599246810018921Q /* log_2 e */
-#define M_LOG10Eq 0.4342944819032518276511289189166051Q /* log_10 e */
-#define M_LN2q 0.6931471805599453094172321214581766Q /* log_e 2 */
-#define M_LN10q 2.3025850929940456840179914546843642Q /* log_e 10 */
-#define M_PIq 3.1415926535897932384626433832795029Q /* pi */
-#define M_PI_2q 1.5707963267948966192313216916397514Q /* pi/2 */
-#define M_PI_4q 0.7853981633974483096156608458198757Q /* pi/4 */
-#define M_1_PIq 0.3183098861837906715377675267450287Q /* 1/pi */
-#define M_2_PIq 0.6366197723675813430755350534900574Q /* 2/pi */
-#define M_2_SQRTPIq 1.1283791670955125738961589031215452Q /* 2/sqrt(pi) */
-#define M_SQRT2q 1.4142135623730950488016887242096981Q /* sqrt(2) */
-#define M_SQRT1_2q 0.7071067811865475244008443621048490Q /* 1/sqrt(2) */
+#define M_Eq 2.718281828459045235360287471352662498Q /* e */
+#define M_LOG2Eq 1.442695040888963407359924681001892137Q /* log_2 e */
+#define M_LOG10Eq 0.434294481903251827651128918916605082Q /* log_10 e */
+#define M_LN2q 0.693147180559945309417232121458176568Q /* log_e 2 */
+#define M_LN10q 2.302585092994045684017991454684364208Q /* log_e 10 */
+#define M_PIq 3.141592653589793238462643383279502884Q /* pi */
+#define M_PI_2q 1.570796326794896619231321691639751442Q /* pi/2 */
+#define M_PI_4q 0.785398163397448309615660845819875721Q /* pi/4 */
+#define M_1_PIq 0.318309886183790671537767526745028724Q /* 1/pi */
+#define M_2_PIq 0.636619772367581343075535053490057448Q /* 2/pi */
+#define M_2_SQRTPIq 1.128379167095512573896158903121545172Q /* 2/sqrt(pi) */
+#define M_SQRT2q 1.414213562373095048801688724209698079Q /* sqrt(2) */
+#define M_SQRT1_2q 0.707106781186547524400844362104849039Q /* 1/sqrt(2) */
#define __quadmath_extern_inline \
extern inline __attribute__ ((__gnu_inline__))
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index 52c119f..0073abe 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,3 +1,63 @@
+2019-08-16 Iain Sandoe <iain@sandoe.co.uk>
+
+ * LOCAL_PATCHES: Add r274585.
+
+2019-08-16 Iain Sandoe <iain@sandoe.co.uk>
+
+ * asan/asan_interceptors.h: Reapply r272406.
+
+2019-08-15 Martin Liska <mliska@suse.cz>
+
+ * LOCAL_PATCHES: Add r274540
+
+2019-08-15 Martin Liska <mliska@suse.cz>
+
+ * tsan/tsan_rtl_ppc64.S: Reapply.
+
+2019-08-15 Iain Sandoe <iain@sandoe.co.uk>
+
+ PR bootstrap/91455
+ * Makefile.in: Regenerated.
+ * aclocal.m4: Likewise.
+ * asan/Makefile.in: Likewise.
+ * configure: Likewise.
+ * interception/Makefile.in: Likewise.
+ * libbacktrace/Makefile.in: Likewise.
+ * lsan/Makefile.in: Likewise.
+ * sanitizer_common/Makefile.am: Include top_srcdir unconditionally.
+ * sanitizer_common/Makefile.in: Regenerated.
+ * tsan/Makefile.in: Likewise.
+ * ubsan/Makefile.in: Likewise.
+
+2019-08-14 Martin Liska <mliska@suse.cz>
+
+ * LOCAL_PATCHES: Refresh based on what was committed.
+
+2019-08-14 Martin Liska <mliska@suse.cz>
+
+ * asan/asan_globals.cpp (CheckODRViolationViaIndicator): Reapply
+ patch from trunk.
+ (CheckODRViolationViaPoisoning): Likewise.
+ (RegisterGlobal): Likewise.
+ * asan/asan_mapping.h: Likewise.
+ * sanitizer_common/sanitizer_linux_libcdep.cpp (defined): Likewise.
+ * sanitizer_common/sanitizer_mac.cpp (defined): Likewise.
+ * sanitizer_common/sanitizer_platform_limits_linux.cpp (defined): Likewise.
+ * sanitizer_common/sanitizer_platform_limits_posix.h (defined): Likewise.
+ * sanitizer_common/sanitizer_stacktrace.cpp (GetCanonicFrame): Likewise.
+ * ubsan/ubsan_handlers.cpp (__ubsan::__ubsan_handle_cfi_bad_icall): Likewise.
+ (__ubsan::__ubsan_handle_cfi_bad_icall_abort): Likewise.
+ * ubsan/ubsan_handlers.h (struct CFIBadIcallData): Likewise.
+ (struct CFICheckFailData): Likewise.
+ (RECOVERABLE): Likewise.
+ * ubsan/ubsan_platform.h: Likewise.
+
+2019-08-14 Martin Liska <mliska@suse.cz>
+
+ PR sanitizer/89832
+ PR sanitizer/91325
+ * All source files: Merge from upstream 368656.
+
2019-06-26 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* sanitizer_common/sanitizer_posix_libcdep.cc: Cherry-pick
diff --git a/libsanitizer/LOCAL_PATCHES b/libsanitizer/LOCAL_PATCHES
index f653712..4fe34f5 100644
--- a/libsanitizer/LOCAL_PATCHES
+++ b/libsanitizer/LOCAL_PATCHES
@@ -1,6 +1,3 @@
-r258525
-r265667
-r265668
-r265669
-r265950
-r270208
+r274427
+r274540
+r274585
diff --git a/libsanitizer/MERGE b/libsanitizer/MERGE
index 8f02e23..bb1b045 100644
--- a/libsanitizer/MERGE
+++ b/libsanitizer/MERGE
@@ -1,4 +1,4 @@
-345033
+368656
The first line of this file holds the svn revision number of the
last merge done from the master library sources.
diff --git a/libsanitizer/asan/Makefile.am b/libsanitizer/asan/Makefile.am
index b18ab2a..7bba555 100644
--- a/libsanitizer/asan/Makefile.am
+++ b/libsanitizer/asan/Makefile.am
@@ -17,37 +17,38 @@ toolexeclib_LTLIBRARIES = libasan.la
nodist_toolexeclib_HEADERS = libasan_preinit.o
asan_files = \
- asan_activation.cc \
- asan_allocator.cc \
- asan_debugging.cc \
- asan_descriptions.cc \
- asan_errors.cc \
- asan_fake_stack.cc \
- asan_flags.cc \
- asan_globals.cc \
- asan_interceptors.cc \
- asan_interceptors_memintrinsics.cc \
- asan_linux.cc \
- asan_mac.cc \
- asan_malloc_linux.cc \
- asan_malloc_mac.cc \
- asan_malloc_win.cc \
- asan_memory_profile.cc \
- asan_new_delete.cc \
- asan_poisoning.cc \
- asan_posix.cc \
- asan_premap_shadow.cc \
- asan_report.cc \
- asan_rtems.cc \
- asan_rtl.cc \
- asan_shadow_setup.cc \
- asan_stack.cc \
- asan_stats.cc \
- asan_suppressions.cc \
- asan_thread.cc \
- asan_win.cc \
- asan_win_dll_thunk.cc \
- asan_win_dynamic_runtime_thunk.cc
+ asan_activation.cpp \
+ asan_allocator.cpp \
+ asan_debugging.cpp \
+ asan_descriptions.cpp \
+ asan_errors.cpp \
+ asan_fake_stack.cpp \
+ asan_flags.cpp \
+ asan_globals.cpp \
+ asan_interceptors.cpp \
+ asan_interceptors_memintrinsics.cpp \
+ asan_linux.cpp \
+ asan_mac.cpp \
+ asan_malloc_linux.cpp \
+ asan_malloc_mac.cpp \
+ asan_malloc_win.cpp \
+ asan_memory_profile.cpp \
+ asan_new_delete.cpp \
+ asan_poisoning.cpp \
+ asan_posix.cpp \
+ asan_premap_shadow.cpp \
+ asan_report.cpp \
+ asan_rtems.cpp \
+ asan_rtl.cpp \
+ asan_shadow_setup.cpp \
+ asan_stack.cpp \
+ asan_stats.cpp \
+ asan_suppressions.cpp \
+ asan_thread.cpp \
+ asan_win.cpp \
+ asan_win_dll_thunk.cpp \
+ asan_win_dynamic_runtime_thunk.cpp \
+ asan_interceptors_vfork.S
libasan_la_SOURCES = $(asan_files)
libasan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(top_builddir)/lsan/libsanitizer_lsan.la
diff --git a/libsanitizer/asan/Makefile.in b/libsanitizer/asan/Makefile.in
index 41bace4..00b6082 100644
--- a/libsanitizer/asan/Makefile.in
+++ b/libsanitizer/asan/Makefile.in
@@ -158,7 +158,8 @@ am__objects_1 = asan_activation.lo asan_allocator.lo asan_debugging.lo \
asan_posix.lo asan_premap_shadow.lo asan_report.lo \
asan_rtems.lo asan_rtl.lo asan_shadow_setup.lo asan_stack.lo \
asan_stats.lo asan_suppressions.lo asan_thread.lo asan_win.lo \
- asan_win_dll_thunk.lo asan_win_dynamic_runtime_thunk.lo
+ asan_win_dll_thunk.lo asan_win_dynamic_runtime_thunk.lo \
+ asan_interceptors_vfork.lo
am_libasan_la_OBJECTS = $(am__objects_1)
libasan_la_OBJECTS = $(am_libasan_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
@@ -184,6 +185,16 @@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/../depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
+CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
+LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CCASFLAGS) $(CCASFLAGS)
+AM_V_CPPAS = $(am__v_CPPAS_@AM_V@)
+am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@)
+am__v_CPPAS_0 = @echo " CPPAS " $@;
+am__v_CPPAS_1 =
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
@@ -202,6 +213,24 @@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_@AM_V@)
+am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
+am__v_CC_0 = @echo " CC " $@;
+am__v_CC_1 =
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_@AM_V@)
+am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
+am__v_CCLD_0 = @echo " CCLD " $@;
+am__v_CCLD_1 =
SOURCES = $(libasan_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
@@ -256,8 +285,8 @@ CYGPATH_W = @CYGPATH_W@
DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS \
-D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS \
-DASAN_HAS_EXCEPTIONS=1 -DASAN_NEEDS_SEGV=1 \
- -DCAN_SANITIZE_UB=0 \
- -DASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION=0 $(am__append_1)
+ -DCAN_SANITIZE_UB=0 -DASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION=0 \
+ $(am__append_1)
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
@@ -394,37 +423,38 @@ ACLOCAL_AMFLAGS = -I $(top_srcdir) -I $(top_srcdir)/config
toolexeclib_LTLIBRARIES = libasan.la
nodist_toolexeclib_HEADERS = libasan_preinit.o
asan_files = \
- asan_activation.cc \
- asan_allocator.cc \
- asan_debugging.cc \
- asan_descriptions.cc \
- asan_errors.cc \
- asan_fake_stack.cc \
- asan_flags.cc \
- asan_globals.cc \
- asan_interceptors.cc \
- asan_interceptors_memintrinsics.cc \
- asan_linux.cc \
- asan_mac.cc \
- asan_malloc_linux.cc \
- asan_malloc_mac.cc \
- asan_malloc_win.cc \
- asan_memory_profile.cc \
- asan_new_delete.cc \
- asan_poisoning.cc \
- asan_posix.cc \
- asan_premap_shadow.cc \
- asan_report.cc \
- asan_rtems.cc \
- asan_rtl.cc \
- asan_shadow_setup.cc \
- asan_stack.cc \
- asan_stats.cc \
- asan_suppressions.cc \
- asan_thread.cc \
- asan_win.cc \
- asan_win_dll_thunk.cc \
- asan_win_dynamic_runtime_thunk.cc
+ asan_activation.cpp \
+ asan_allocator.cpp \
+ asan_debugging.cpp \
+ asan_descriptions.cpp \
+ asan_errors.cpp \
+ asan_fake_stack.cpp \
+ asan_flags.cpp \
+ asan_globals.cpp \
+ asan_interceptors.cpp \
+ asan_interceptors_memintrinsics.cpp \
+ asan_linux.cpp \
+ asan_mac.cpp \
+ asan_malloc_linux.cpp \
+ asan_malloc_mac.cpp \
+ asan_malloc_win.cpp \
+ asan_memory_profile.cpp \
+ asan_new_delete.cpp \
+ asan_poisoning.cpp \
+ asan_posix.cpp \
+ asan_premap_shadow.cpp \
+ asan_report.cpp \
+ asan_rtems.cpp \
+ asan_rtl.cpp \
+ asan_shadow_setup.cpp \
+ asan_stack.cpp \
+ asan_stats.cpp \
+ asan_suppressions.cpp \
+ asan_thread.cpp \
+ asan_win.cpp \
+ asan_win_dll_thunk.cpp \
+ asan_win_dynamic_runtime_thunk.cpp \
+ asan_interceptors_vfork.S
libasan_la_SOURCES = $(asan_files)
libasan_la_LIBADD = \
@@ -475,7 +505,7 @@ MAKEOVERRIDES =
all: all-am
.SUFFIXES:
-.SUFFIXES: .cc .lo .o .obj
+.SUFFIXES: .S .cpp .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
@@ -560,6 +590,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_globals.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_interceptors.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_interceptors_memintrinsics.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_interceptors_vfork.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_linux.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_mac.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_malloc_linux.Plo@am__quote@
@@ -582,21 +613,42 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_win_dll_thunk.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_win_dynamic_runtime_thunk.Plo@am__quote@
-.cc.o:
+.S.o:
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $<
+
+.S.obj:
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.S.lo:
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $<
+
+.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
-.cc.obj:
+.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-.cc.lo:
+.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
diff --git a/libsanitizer/asan/asan_activation.cc b/libsanitizer/asan/asan_activation.cpp
index 6f69f70..795df95 100644
--- a/libsanitizer/asan/asan_activation.cc
+++ b/libsanitizer/asan/asan_activation.cpp
@@ -1,7 +1,8 @@
-//===-- asan_activation.cc --------------------------------------*- C++ -*-===//
+//===-- asan_activation.cpp -------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_activation.h b/libsanitizer/asan/asan_activation.h
index 162a5eb..93c290c 100644
--- a/libsanitizer/asan/asan_activation.h
+++ b/libsanitizer/asan/asan_activation.h
@@ -1,7 +1,8 @@
//===-- asan_activation.h ---------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_activation_flags.inc b/libsanitizer/asan/asan_activation_flags.inc
index e71abb9..e0fdffc 100644
--- a/libsanitizer/asan/asan_activation_flags.inc
+++ b/libsanitizer/asan/asan_activation_flags.inc
@@ -1,7 +1,8 @@
//===-- asan_activation_flags.inc -------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_allocator.cc b/libsanitizer/asan/asan_allocator.cpp
index c2b31a5..b58116e 100644
--- a/libsanitizer/asan/asan_allocator.cc
+++ b/libsanitizer/asan/asan_allocator.cpp
@@ -1,7 +1,8 @@
-//===-- asan_allocator.cc -------------------------------------------------===//
+//===-- asan_allocator.cpp ------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -878,6 +879,17 @@ void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack) {
return SetErrnoOnNull(instance.Calloc(nmemb, size, stack));
}
+void *asan_reallocarray(void *p, uptr nmemb, uptr size,
+ BufferedStackTrace *stack) {
+ if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
+ errno = errno_ENOMEM;
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportReallocArrayOverflow(nmemb, size, stack);
+ }
+ return asan_realloc(p, nmemb * size, stack);
+}
+
void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack) {
if (!p)
return SetErrnoOnNull(instance.Allocate(size, 8, stack, FROM_MALLOC, true));
diff --git a/libsanitizer/asan/asan_allocator.h b/libsanitizer/asan/asan_allocator.h
index 1f58bb1..b37d8ef 100644
--- a/libsanitizer/asan/asan_allocator.h
+++ b/libsanitizer/asan/asan_allocator.h
@@ -1,13 +1,14 @@
//===-- asan_allocator.h ----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
-// ASan-private header for asan_allocator.cc.
+// ASan-private header for asan_allocator.cpp.
//===----------------------------------------------------------------------===//
#ifndef ASAN_ALLOCATOR_H
@@ -137,9 +138,9 @@ typedef VeryCompactSizeClassMap SizeClassMap;
const uptr kAllocatorSpace = 0x10000000000ULL;
const uptr kAllocatorSize = 0x10000000000ULL; // 3T.
typedef DefaultSizeClassMap SizeClassMap;
-# elif defined(__sparc__)
+#elif defined(__sparc__)
const uptr kAllocatorSpace = ~(uptr)0;
-const uptr kAllocatorSize = 0x20000000000ULL; // 2T.
+const uptr kAllocatorSize = 0x20000000000ULL; // 2T.
typedef DefaultSizeClassMap SizeClassMap;
# elif SANITIZER_WINDOWS
const uptr kAllocatorSpace = ~(uptr)0;
@@ -150,6 +151,7 @@ const uptr kAllocatorSpace = 0x600000000000ULL;
const uptr kAllocatorSize = 0x40000000000ULL; // 4T.
typedef DefaultSizeClassMap SizeClassMap;
# endif
+template <typename AddressSpaceViewTy>
struct AP64 { // Allocator64 parameters. Deliberately using a short name.
static const uptr kSpaceBeg = kAllocatorSpace;
static const uptr kSpaceSize = kAllocatorSize;
@@ -157,37 +159,37 @@ struct AP64 { // Allocator64 parameters. Deliberately using a short name.
typedef __asan::SizeClassMap SizeClassMap;
typedef AsanMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
+ using AddressSpaceView = AddressSpaceViewTy;
};
-typedef SizeClassAllocator64<AP64> PrimaryAllocator;
+template <typename AddressSpaceView>
+using PrimaryAllocatorASVT = SizeClassAllocator64<AP64<AddressSpaceView>>;
+using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
#else // Fallback to SizeClassAllocator32.
-static const uptr kRegionSizeLog = 20;
-static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
-# if SANITIZER_WORDSIZE == 32
-typedef FlatByteMap<kNumRegions> ByteMap;
-# elif SANITIZER_WORDSIZE == 64
-typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
-# endif
typedef CompactSizeClassMap SizeClassMap;
+template <typename AddressSpaceViewTy>
struct AP32 {
static const uptr kSpaceBeg = 0;
static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
static const uptr kMetadataSize = 16;
typedef __asan::SizeClassMap SizeClassMap;
- static const uptr kRegionSizeLog = __asan::kRegionSizeLog;
- typedef __asan::ByteMap ByteMap;
+ static const uptr kRegionSizeLog = 20;
+ using AddressSpaceView = AddressSpaceViewTy;
typedef AsanMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
};
-typedef SizeClassAllocator32<AP32> PrimaryAllocator;
+template <typename AddressSpaceView>
+using PrimaryAllocatorASVT = SizeClassAllocator32<AP32<AddressSpaceView> >;
+using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
#endif // SANITIZER_CAN_USE_ALLOCATOR64
static const uptr kNumberOfSizeClasses = SizeClassMap::kNumClasses;
-typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
-typedef LargeMmapAllocator<AsanMapUnmapCallback> SecondaryAllocator;
-typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
- SecondaryAllocator> AsanAllocator;
+template <typename AddressSpaceView>
+using AsanAllocatorASVT =
+ CombinedAllocator<PrimaryAllocatorASVT<AddressSpaceView>>;
+using AsanAllocator = AsanAllocatorASVT<LocalAddressSpaceView>;
+using AllocatorCache = AsanAllocator::AllocatorCache;
struct AsanThreadLocalMallocStorage {
uptr quarantine_cache[16];
@@ -207,6 +209,8 @@ void asan_delete(void *ptr, uptr size, uptr alignment,
void *asan_malloc(uptr size, BufferedStackTrace *stack);
void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack);
void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack);
+void *asan_reallocarray(void *p, uptr nmemb, uptr size,
+ BufferedStackTrace *stack);
void *asan_valloc(uptr size, BufferedStackTrace *stack);
void *asan_pvalloc(uptr size, BufferedStackTrace *stack);
diff --git a/libsanitizer/asan/asan_debugging.cc b/libsanitizer/asan/asan_debugging.cpp
index 075af337..3fc15ad 100644
--- a/libsanitizer/asan/asan_debugging.cc
+++ b/libsanitizer/asan/asan_debugging.cpp
@@ -1,7 +1,8 @@
-//===-- asan_debugging.cc -------------------------------------------------===//
+//===-- asan_debugging.cpp ------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_descriptions.cc b/libsanitizer/asan/asan_descriptions.cpp
index 99f226d..153c874 100644
--- a/libsanitizer/asan/asan_descriptions.cc
+++ b/libsanitizer/asan/asan_descriptions.cpp
@@ -1,7 +1,8 @@
-//===-- asan_descriptions.cc ------------------------------------*- C++ -*-===//
+//===-- asan_descriptions.cpp -----------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_descriptions.h b/libsanitizer/asan/asan_descriptions.h
index 43d0cbf..28b3810 100644
--- a/libsanitizer/asan/asan_descriptions.h
+++ b/libsanitizer/asan/asan_descriptions.h
@@ -1,13 +1,14 @@
//===-- asan_descriptions.h -------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
-// ASan-private header for asan_descriptions.cc.
+// ASan-private header for asan_descriptions.cpp.
// TODO(filcab): Most struct definitions should move to the interface headers.
//===----------------------------------------------------------------------===//
#ifndef ASAN_DESCRIPTIONS_H
diff --git a/libsanitizer/asan/asan_errors.cc b/libsanitizer/asan/asan_errors.cpp
index 65941f6..75ee996 100644
--- a/libsanitizer/asan/asan_errors.cc
+++ b/libsanitizer/asan/asan_errors.cpp
@@ -1,7 +1,8 @@
-//===-- asan_errors.cc ------------------------------------------*- C++ -*-===//
+//===-- asan_errors.cpp -----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -34,7 +35,7 @@ static void OnStackUnwind(const SignalContext &sig,
// corresponding code in the sanitizer_common and we use this callback to
// print it.
static_cast<const ScarinessScoreBase *>(callback_context)->Print();
- GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context, fast);
+ stack->Unwind(sig.pc, sig.bp, sig.context, fast);
}
void ErrorDeadlySignal::Print() {
@@ -176,6 +177,19 @@ void ErrorCallocOverflow::Print() {
ReportErrorSummary(scariness.GetDescription(), stack);
}
+void ErrorReallocArrayOverflow::Print() {
+ Decorator d;
+ Printf("%s", d.Error());
+ Report(
+ "ERROR: AddressSanitizer: reallocarray parameters overflow: count * size "
+ "(%zd * %zd) cannot be represented in type size_t (thread %s)\n",
+ count, size, AsanThreadIdAndName(tid).c_str());
+ Printf("%s", d.Default());
+ stack->Print();
+ PrintHintAllocatorCannotReturnNull();
+ ReportErrorSummary(scariness.GetDescription(), stack);
+}
+
void ErrorPvallocOverflow::Print() {
Decorator d;
Printf("%s", d.Error());
diff --git a/libsanitizer/asan/asan_errors.h b/libsanitizer/asan/asan_errors.h
index b155f24..b84f56c 100644
--- a/libsanitizer/asan/asan_errors.h
+++ b/libsanitizer/asan/asan_errors.h
@@ -1,7 +1,8 @@
//===-- asan_errors.h -------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -162,6 +163,21 @@ struct ErrorCallocOverflow : ErrorBase {
void Print();
};
+struct ErrorReallocArrayOverflow : ErrorBase {
+ const BufferedStackTrace *stack;
+ uptr count;
+ uptr size;
+
+ ErrorReallocArrayOverflow() = default; // (*)
+ ErrorReallocArrayOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_,
+ uptr size_)
+ : ErrorBase(tid, 10, "reallocarray-overflow"),
+ stack(stack_),
+ count(count_),
+ size(size_) {}
+ void Print();
+};
+
struct ErrorPvallocOverflow : ErrorBase {
const BufferedStackTrace *stack;
uptr size;
@@ -370,6 +386,7 @@ struct ErrorGeneric : ErrorBase {
macro(MallocUsableSizeNotOwned) \
macro(SanitizerGetAllocatedSizeNotOwned) \
macro(CallocOverflow) \
+ macro(ReallocArrayOverflow) \
macro(PvallocOverflow) \
macro(InvalidAllocationAlignment) \
macro(InvalidAlignedAllocAlignment) \
@@ -387,8 +404,10 @@ struct ErrorGeneric : ErrorBase {
#define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name,
#define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name;
-#define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \
- ErrorDescription(Error##name const &e) : kind(kErrorKind##name), name(e) {}
+#define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \
+ ErrorDescription(Error##name const &e) : kind(kErrorKind##name) { \
+ internal_memcpy(&name, &e, sizeof(name)); \
+ }
#define ASAN_ERROR_DESCRIPTION_PRINT(name) \
case kErrorKind##name: \
return name.Print();
diff --git a/libsanitizer/asan/asan_fake_stack.cc b/libsanitizer/asan/asan_fake_stack.cpp
index f4a5bb7..295e6de 100644
--- a/libsanitizer/asan/asan_fake_stack.cc
+++ b/libsanitizer/asan/asan_fake_stack.cpp
@@ -1,7 +1,8 @@
-//===-- asan_fake_stack.cc ------------------------------------------------===//
+//===-- asan_fake_stack.cpp -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_fake_stack.h b/libsanitizer/asan/asan_fake_stack.h
index 6ac61dd..270a198 100644
--- a/libsanitizer/asan/asan_fake_stack.h
+++ b/libsanitizer/asan/asan_fake_stack.h
@@ -1,13 +1,14 @@
//===-- asan_fake_stack.h ---------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
-// ASan-private header for asan_fake_stack.cc, implements FakeStack.
+// ASan-private header for asan_fake_stack.cpp, implements FakeStack.
//===----------------------------------------------------------------------===//
#ifndef ASAN_FAKE_STACK_H
diff --git a/libsanitizer/asan/asan_flags.cc b/libsanitizer/asan/asan_flags.cpp
index 522fce3..c5c70ea 100644
--- a/libsanitizer/asan/asan_flags.cc
+++ b/libsanitizer/asan/asan_flags.cpp
@@ -1,7 +1,8 @@
-//===-- asan_flags.cc -------------------------------------------*- C++ -*-===//
+//===-- asan_flags.cpp ------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -119,12 +120,12 @@ void InitializeFlags() {
#endif
// Override from command line.
- asan_parser.ParseString(GetEnv("ASAN_OPTIONS"));
+ asan_parser.ParseStringFromEnv("ASAN_OPTIONS");
#if CAN_SANITIZE_LEAKS
- lsan_parser.ParseString(GetEnv("LSAN_OPTIONS"));
+ lsan_parser.ParseStringFromEnv("LSAN_OPTIONS");
#endif
#if CAN_SANITIZE_UB
- ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
+ ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS");
#endif
InitializeCommonFlags();
diff --git a/libsanitizer/asan/asan_flags.h b/libsanitizer/asan/asan_flags.h
index 6b33789..b55c81f 100644
--- a/libsanitizer/asan/asan_flags.h
+++ b/libsanitizer/asan/asan_flags.h
@@ -1,7 +1,8 @@
//===-- asan_flags.h -------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_flags.inc b/libsanitizer/asan/asan_flags.inc
index 9cd1f60..d360e03 100644
--- a/libsanitizer/asan/asan_flags.inc
+++ b/libsanitizer/asan/asan_flags.inc
@@ -1,7 +1,8 @@
//===-- asan_flags.inc ------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -150,8 +151,6 @@ ASAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
ASAN_FLAG(bool, halt_on_error, true,
"Crash the program after printing the first error report "
"(WARNING: USE AT YOUR OWN RISK!)")
-ASAN_FLAG(bool, use_odr_indicator, false,
- "Use special ODR indicator symbol for ODR violation detection")
ASAN_FLAG(bool, allocator_frees_and_returns_null_on_realloc_zero, true,
"realloc(p, 0) is equivalent to free(p) by default (Same as the "
"POSIX standard). If set to false, realloc(p, 0) will return a "
@@ -159,3 +158,5 @@ ASAN_FLAG(bool, allocator_frees_and_returns_null_on_realloc_zero, true,
ASAN_FLAG(bool, verify_asan_link_order, true,
"Check position of ASan runtime in library list (needs to be disabled"
" when other library has to be preloaded system-wide)")
+ASAN_FLAG(bool, windows_hook_rtl_allocators, false,
+ "(Windows only) enable hooking of Rtl(Allocate|Free|Size|ReAllocate)Heap.")
diff --git a/libsanitizer/asan/asan_fuchsia.cc b/libsanitizer/asan/asan_fuchsia.cpp
index f8207ec..f8b2d5f 100644
--- a/libsanitizer/asan/asan_fuchsia.cc
+++ b/libsanitizer/asan/asan_fuchsia.cpp
@@ -1,7 +1,8 @@
-//===-- asan_fuchsia.cc --------------------------------------------------===//
+//===-- asan_fuchsia.cpp -------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===---------------------------------------------------------------------===//
//
@@ -27,7 +28,7 @@ namespace __asan {
// The system already set up the shadow memory for us.
// __sanitizer::GetMaxUserVirtualAddress has already been called by
-// AsanInitInternal->InitializeHighMemEnd (asan_rtl.cc).
+// AsanInitInternal->InitializeHighMemEnd (asan_rtl.cpp).
// Just do some additional sanity checks here.
void InitializeShadowMemory() {
if (Verbosity()) PrintAddressSpaceLayout();
@@ -171,13 +172,13 @@ static void ThreadCreateHook(void *hook, bool aborted) {
// This is called in the newly-created thread before it runs anything else,
// with the pointer returned by BeforeThreadCreateHook (above).
-// cf. asan_interceptors.cc:asan_thread_start
+// cf. asan_interceptors.cpp:asan_thread_start
static void ThreadStartHook(void *hook, uptr os_id) {
AsanThread *thread = static_cast<AsanThread *>(hook);
SetCurrentThread(thread);
// In lieu of AsanThread::ThreadStart.
- asanThreadRegistry().StartThread(thread->tid(), os_id, /*workerthread*/ false,
+ asanThreadRegistry().StartThread(thread->tid(), os_id, ThreadType::Regular,
nullptr);
}
@@ -188,6 +189,13 @@ static void ThreadExitHook(void *hook, uptr os_id) {
AsanThread::TSDDtor(per_thread);
}
+bool HandleDlopenInit() {
+ // Not supported on this platform.
+ static_assert(!SANITIZER_SUPPORTS_INIT_FOR_DLOPEN,
+ "Expected SANITIZER_SUPPORTS_INIT_FOR_DLOPEN to be false");
+ return false;
+}
+
} // namespace __asan
// These are declared (in extern "C") by <zircon/sanitizer.h>.
diff --git a/libsanitizer/asan/asan_globals.cc b/libsanitizer/asan/asan_globals.cpp
index 10f0909..c77e535 100644
--- a/libsanitizer/asan/asan_globals.cc
+++ b/libsanitizer/asan/asan_globals.cpp
@@ -1,7 +1,8 @@
-//===-- asan_globals.cc ---------------------------------------------------===//
+//===-- asan_globals.cpp --------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -81,9 +82,11 @@ static bool IsAddressNearGlobal(uptr addr, const __asan_global &g) {
}
static void ReportGlobal(const Global &g, const char *prefix) {
- Report("%s Global[%p]: beg=%p size=%zu/%zu name=%s module=%s dyn_init=%zu\n",
- prefix, &g, (void *)g.beg, g.size, g.size_with_redzone, g.name,
- g.module_name, g.has_dynamic_init);
+ Report(
+ "%s Global[%p]: beg=%p size=%zu/%zu name=%s module=%s dyn_init=%zu "
+ "odr_indicator=%p\n",
+ prefix, &g, (void *)g.beg, g.size, g.size_with_redzone, g.name,
+ g.module_name, g.has_dynamic_init, (void *)g.odr_indicator);
if (g.location) {
Report(" location (%p): name=%s[%p], %d %d\n", g.location,
g.location->filename, g.location->filename, g.location->line_no,
@@ -112,15 +115,12 @@ int GetGlobalsForAddress(uptr addr, Global *globals, u32 *reg_sites,
if (flags()->report_globals >= 2)
ReportGlobal(g, "Search");
if (IsAddressNearGlobal(addr, g)) {
-#if defined(__GNUC__) && defined(__sparc__)
internal_memcpy(&globals[res], &g, sizeof(g));
-#else
- globals[res] = g;
-#endif
if (reg_sites)
reg_sites[res] = FindRegistrationSite(&g);
res++;
- if (res == max_globals) break;
+ if (res == max_globals)
+ break;
}
}
return res;
@@ -135,6 +135,9 @@ enum GlobalSymbolState {
// this method in case compiler instruments global variables through their
// local aliases.
static void CheckODRViolationViaIndicator(const Global *g) {
+ // Instrumentation requests to skip ODR check.
+ if (g->odr_indicator == UINTPTR_MAX)
+ return;
u8 *odr_indicator = reinterpret_cast<u8 *>(g->odr_indicator);
if (*odr_indicator == UNREGISTERED) {
*odr_indicator = REGISTERED;
@@ -168,9 +171,7 @@ static void CheckODRViolationViaIndicator(const Global *g) {
// This routine chooses between two different methods of ODR violation
// detection.
static inline bool UseODRIndicator(const Global *g) {
- // Use ODR indicator method iff use_odr_indicator flag is set and
- // indicator symbol address is not 0.
- return flags()->use_odr_indicator && g->odr_indicator > 0;
+ return g->odr_indicator > 0;
}
// Register a global variable.
@@ -231,7 +232,7 @@ static void UnregisterGlobal(const Global *g) {
// implementation. It might not be worth doing anyway.
// Release ODR indicator.
- if (UseODRIndicator(g)) {
+ if (UseODRIndicator(g) && g->odr_indicator != UINTPTR_MAX) {
u8 *odr_indicator = reinterpret_cast<u8 *>(g->odr_indicator);
*odr_indicator = UNREGISTERED;
}
diff --git a/libsanitizer/asan/asan_globals_win.cc b/libsanitizer/asan/asan_globals_win.cpp
index a78bc87..ff5fe22 100644
--- a/libsanitizer/asan/asan_globals_win.cc
+++ b/libsanitizer/asan/asan_globals_win.cpp
@@ -1,7 +1,8 @@
-//===-- asan_globals_win.cc -----------------------------------------------===//
+//===-- asan_globals_win.cpp ----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_init_version.h b/libsanitizer/asan/asan_init_version.h
index 7833133..b806d79 100644
--- a/libsanitizer/asan/asan_init_version.h
+++ b/libsanitizer/asan/asan_init_version.h
@@ -1,7 +1,8 @@
//===-- asan_init_version.h -------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_interceptors.cc b/libsanitizer/asan/asan_interceptors.cpp
index fc9818b..482e44d 100644
--- a/libsanitizer/asan/asan_interceptors.cc
+++ b/libsanitizer/asan/asan_interceptors.cpp
@@ -1,7 +1,8 @@
-//===-- asan_interceptors.cc ----------------------------------------------===//
+//===-- asan_interceptors.cpp ---------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -23,7 +24,7 @@
#include "sanitizer_common/sanitizer_libc.h"
// There is no general interception at all on Fuchsia and RTEMS.
-// Only the functions in asan_interceptors_memintrinsics.cc are
+// Only the functions in asan_interceptors_memintrinsics.cpp are
// really defined to replace libc functions.
#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
@@ -578,6 +579,11 @@ INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
}
#endif // ASAN_INTERCEPT___CXA_ATEXIT
+#if ASAN_INTERCEPT_VFORK
+DEFINE_REAL(int, vfork)
+DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(int, vfork)
+#endif
+
// ---------------------- InitializeAsanInterceptors ---------------- {{{1
namespace __asan {
void InitializeAsanInterceptors() {
@@ -655,6 +661,10 @@ void InitializeAsanInterceptors() {
ASAN_INTERCEPT_FUNC(__cxa_atexit);
#endif
+#if ASAN_INTERCEPT_VFORK
+ ASAN_INTERCEPT_FUNC(vfork);
+#endif
+
InitializePlatformInterceptors();
VReport(1, "AddressSanitizer: libc interceptors initialized\n");
diff --git a/libsanitizer/asan/asan_interceptors.h b/libsanitizer/asan/asan_interceptors.h
index beb1dc9..035a84e 100644
--- a/libsanitizer/asan/asan_interceptors.h
+++ b/libsanitizer/asan/asan_interceptors.h
@@ -1,13 +1,14 @@
//===-- asan_interceptors.h -------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
-// ASan-private header for asan_interceptors.cc
+// ASan-private header for asan_interceptors.cpp
//===----------------------------------------------------------------------===//
#ifndef ASAN_INTERCEPTORS_H
#define ASAN_INTERCEPTORS_H
@@ -109,6 +110,13 @@ void InitializePlatformInterceptors();
# define ASAN_INTERCEPT___STRDUP 0
#endif
+#if SANITIZER_LINUX && (defined(__arm__) || defined(__aarch64__) || \
+ defined(__i386__) || defined(__x86_64__))
+# define ASAN_INTERCEPT_VFORK 1
+#else
+# define ASAN_INTERCEPT_VFORK 0
+#endif
+
DECLARE_REAL(int, memcmp, const void *a1, const void *a2, uptr size)
DECLARE_REAL(char*, strchr, const char *str, int c)
DECLARE_REAL(SIZE_T, strlen, const char *s)
@@ -117,16 +125,16 @@ DECLARE_REAL(uptr, strnlen, const char *s, uptr maxlen)
DECLARE_REAL(char*, strstr, const char *s1, const char *s2)
#if !SANITIZER_MAC
-#define ASAN_INTERCEPT_FUNC(name) \
- do { \
- if ((!INTERCEPT_FUNCTION(name) || !REAL(name))) \
- VReport(1, "AddressSanitizer: failed to intercept '" #name "'\n"); \
+#define ASAN_INTERCEPT_FUNC(name) \
+ do { \
+ if (!INTERCEPT_FUNCTION(name)) \
+ VReport(1, "AddressSanitizer: failed to intercept '%s'\n'", #name); \
} while (0)
-#define ASAN_INTERCEPT_FUNC_VER(name, ver) \
- do { \
- if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name))) \
- VReport( \
- 1, "AddressSanitizer: failed to intercept '" #name "@@" #ver "'\n"); \
+#define ASAN_INTERCEPT_FUNC_VER(name, ver) \
+ do { \
+ if (!INTERCEPT_FUNCTION_VER(name, ver)) \
+ VReport(1, "AddressSanitizer: failed to intercept '%s@@%s'\n", #name, \
+ #ver); \
} while (0)
#else
// OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION.
diff --git a/libsanitizer/asan/asan_interceptors_memintrinsics.cc b/libsanitizer/asan/asan_interceptors_memintrinsics.cpp
index b0c06a0..56df60b 100644
--- a/libsanitizer/asan/asan_interceptors_memintrinsics.cc
+++ b/libsanitizer/asan/asan_interceptors_memintrinsics.cpp
@@ -1,7 +1,8 @@
-//===-- asan_interceptors_memintrinsics.cc --------------------------------===//
+//===-- asan_interceptors_memintrinsics.cpp -------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===---------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_interceptors_memintrinsics.h b/libsanitizer/asan/asan_interceptors_memintrinsics.h
index faf8119..632f051 100644
--- a/libsanitizer/asan/asan_interceptors_memintrinsics.h
+++ b/libsanitizer/asan/asan_interceptors_memintrinsics.h
@@ -1,13 +1,14 @@
//===-- asan_interceptors_memintrinsics.h -----------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===---------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
-// ASan-private header for asan_memintrin.cc
+// ASan-private header for asan_interceptors_memintrinsics.cpp
//===---------------------------------------------------------------------===//
#ifndef ASAN_MEMINTRIN_H
#define ASAN_MEMINTRIN_H
diff --git a/libsanitizer/asan/asan_interceptors_vfork.S b/libsanitizer/asan/asan_interceptors_vfork.S
new file mode 100644
index 0000000..90a169d
--- /dev/null
+++ b/libsanitizer/asan/asan_interceptors_vfork.S
@@ -0,0 +1,12 @@
+#include "sanitizer_common/sanitizer_asm.h"
+
+#if defined(__linux__)
+#define COMMON_INTERCEPTOR_SPILL_AREA __asan_extra_spill_area
+#define COMMON_INTERCEPTOR_HANDLE_VFORK __asan_handle_vfork
+#include "sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S"
+#include "sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S"
+#include "sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S"
+#include "sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S"
+#endif
+
+NO_EXEC_STACK_DIRECTIVE
diff --git a/libsanitizer/asan/asan_interface.inc b/libsanitizer/asan/asan_interface.inc
index b2fcde1..7c341f2 100644
--- a/libsanitizer/asan/asan_interface.inc
+++ b/libsanitizer/asan/asan_interface.inc
@@ -1,7 +1,8 @@
//===-- asan_interface.inc ------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Asan interface list.
@@ -37,6 +38,7 @@ INTERFACE_FUNCTION(__asan_get_report_pc)
INTERFACE_FUNCTION(__asan_get_report_sp)
INTERFACE_FUNCTION(__asan_get_shadow_mapping)
INTERFACE_FUNCTION(__asan_handle_no_return)
+INTERFACE_FUNCTION(__asan_handle_vfork)
INTERFACE_FUNCTION(__asan_init)
INTERFACE_FUNCTION(__asan_load_cxx_array_cookie)
INTERFACE_FUNCTION(__asan_load1)
diff --git a/libsanitizer/asan/asan_interface_internal.h b/libsanitizer/asan/asan_interface_internal.h
index be9605d..c83aa11 100644
--- a/libsanitizer/asan/asan_interface_internal.h
+++ b/libsanitizer/asan/asan_interface_internal.h
@@ -1,7 +1,8 @@
//===-- asan_interface_internal.h -------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -248,6 +249,8 @@ extern "C" {
SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
const char* __asan_default_suppressions();
+
+ SANITIZER_INTERFACE_ATTRIBUTE void __asan_handle_vfork(void *sp);
} // extern "C"
#endif // ASAN_INTERFACE_INTERNAL_H
diff --git a/libsanitizer/asan/asan_internal.h b/libsanitizer/asan/asan_internal.h
index 7c23989..72a4c3f 100644
--- a/libsanitizer/asan/asan_internal.h
+++ b/libsanitizer/asan/asan_internal.h
@@ -1,7 +1,8 @@
//===-- asan_internal.h -----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -60,29 +61,29 @@ using __sanitizer::StackTrace;
void AsanInitFromRtl();
-// asan_win.cc
+// asan_win.cpp
void InitializePlatformExceptionHandlers();
// Returns whether an address is a valid allocated system heap block.
// 'addr' must point to the beginning of the block.
bool IsSystemHeapAddress(uptr addr);
-// asan_rtl.cc
+// asan_rtl.cpp
void PrintAddressSpaceLayout();
void NORETURN ShowStatsAndAbort();
-// asan_shadow_setup.cc
+// asan_shadow_setup.cpp
void InitializeShadowMemory();
-// asan_malloc_linux.cc / asan_malloc_mac.cc
+// asan_malloc_linux.cpp / asan_malloc_mac.cpp
void ReplaceSystemMalloc();
-// asan_linux.cc / asan_mac.cc / asan_rtems.cc / asan_win.cc
+// asan_linux.cpp / asan_mac.cpp / asan_rtems.cpp / asan_win.cpp
uptr FindDynamicShadowStart();
void *AsanDoesNotSupportStaticLinkage();
void AsanCheckDynamicRTPrereqs();
void AsanCheckIncompatibleRT();
-// asan_thread.cc
+// asan_thread.cpp
AsanThread *CreateMainThread();
// Support function for __asan_(un)register_image_globals. Searches for the
@@ -109,6 +110,11 @@ void *AsanDlSymNext(const char *sym);
void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name);
+// Returns `true` iff most of ASan init process should be skipped due to the
+// ASan library being loaded via `dlopen()`. Platforms may perform any
+// `dlopen()` specific initialization inside this function.
+bool HandleDlopenInit();
+
// Add convenient macro for interface functions that may be represented as
// weak hooks.
#define ASAN_MALLOC_HOOK(ptr, size) \
diff --git a/libsanitizer/asan/asan_linux.cc b/libsanitizer/asan/asan_linux.cpp
index d92d059..ce5e873 100644
--- a/libsanitizer/asan/asan_linux.cc
+++ b/libsanitizer/asan/asan_linux.cpp
@@ -1,7 +1,8 @@
-//===-- asan_linux.cc -----------------------------------------------------===//
+//===-- asan_linux.cpp ----------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -246,6 +247,13 @@ void *AsanDlSymNext(const char *sym) {
return dlsym(RTLD_NEXT, sym);
}
+bool HandleDlopenInit() {
+ // Not supported on this platform.
+ static_assert(!SANITIZER_SUPPORTS_INIT_FOR_DLOPEN,
+ "Expected SANITIZER_SUPPORTS_INIT_FOR_DLOPEN to be false");
+ return false;
+}
+
} // namespace __asan
#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD ||
diff --git a/libsanitizer/asan/asan_mac.cc b/libsanitizer/asan/asan_mac.cpp
index 89a3db4..769d499 100644
--- a/libsanitizer/asan/asan_mac.cc
+++ b/libsanitizer/asan/asan_mac.cpp
@@ -1,7 +1,8 @@
-//===-- asan_mac.cc -------------------------------------------------------===//
+//===-- asan_mac.cpp ------------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -180,8 +181,8 @@ void asan_register_worker_thread(int parent_tid, StackTrace *stack) {
t = AsanThread::Create(/* start_routine */ nullptr, /* arg */ nullptr,
parent_tid, stack, /* detached */ true);
t->Init();
- asanThreadRegistry().StartThread(t->tid(), GetTid(),
- /* workerthread */ true, 0);
+ asanThreadRegistry().StartThread(t->tid(), GetTid(), ThreadType::Worker,
+ nullptr);
SetCurrentThread(t);
}
}
diff --git a/libsanitizer/asan/asan_malloc_linux.cc b/libsanitizer/asan/asan_malloc_linux.cpp
index a6e6927..706bc39 100644
--- a/libsanitizer/asan/asan_malloc_linux.cc
+++ b/libsanitizer/asan/asan_malloc_linux.cpp
@@ -1,7 +1,8 @@
-//===-- asan_malloc_linux.cc ----------------------------------------------===//
+//===-- asan_malloc_linux.cpp ---------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -164,6 +165,14 @@ INTERCEPTOR(void*, realloc, void *ptr, uptr size) {
return asan_realloc(ptr, size, &stack);
}
+#if SANITIZER_INTERCEPT_REALLOCARRAY
+INTERCEPTOR(void*, reallocarray, void *ptr, uptr nmemb, uptr size) {
+ ENSURE_ASAN_INITED();
+ GET_STACK_TRACE_MALLOC;
+ return asan_reallocarray(ptr, nmemb, size, &stack);
+}
+#endif // SANITIZER_INTERCEPT_REALLOCARRAY
+
#if SANITIZER_INTERCEPT_MEMALIGN
INTERCEPTOR(void*, memalign, uptr boundary, uptr size) {
GET_STACK_TRACE_MALLOC;
@@ -207,7 +216,7 @@ INTERCEPTOR(struct fake_mallinfo, mallinfo, void) {
}
INTERCEPTOR(int, mallopt, int cmd, int value) {
- return -1;
+ return 0;
}
#endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
diff --git a/libsanitizer/asan/asan_malloc_local.h b/libsanitizer/asan/asan_malloc_local.h
index 3541893..3f784b9 100644
--- a/libsanitizer/asan/asan_malloc_local.h
+++ b/libsanitizer/asan/asan_malloc_local.h
@@ -1,7 +1,8 @@
//===-- asan_malloc_local.h -------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -16,25 +17,34 @@
#include "sanitizer_common/sanitizer_platform.h"
#include "asan_internal.h"
-// On RTEMS, we use the local pool to handle memory allocation when the ASan
-// run-time is not up.
static INLINE bool EarlyMalloc() {
- return SANITIZER_RTEMS && (!__asan::asan_inited ||
- __asan::asan_init_is_running);
+ return SANITIZER_RTEMS &&
+ (!__asan::asan_inited || __asan::asan_init_is_running);
}
-void* MemalignFromLocalPool(uptr alignment, uptr size);
-
#if SANITIZER_RTEMS
bool IsFromLocalPool(const void *ptr);
+void *MemalignFromLocalPool(uptr alignment, uptr size);
+
+// On RTEMS, we use the local pool to handle memory allocation when the ASan
+// run-time is not up. This macro is expanded in the context of the operator new
+// implementation.
+#define MAYBE_ALLOCATE_FROM_LOCAL_POOL(nothrow) \
+ do { \
+ if (UNLIKELY(EarlyMalloc())) { \
+ void *res = MemalignFromLocalPool(SHADOW_GRANULARITY, size); \
+ if (!nothrow) \
+ CHECK(res); \
+ return res; \
+ } \
+ } while (0)
-#define ALLOCATE_FROM_LOCAL_POOL UNLIKELY(EarlyMalloc())
#define IS_FROM_LOCAL_POOL(ptr) UNLIKELY(IsFromLocalPool(ptr))
#else // SANITIZER_RTEMS
-#define ALLOCATE_FROM_LOCAL_POOL 0
+#define MAYBE_ALLOCATE_FROM_LOCAL_POOL(nothrow)
#define IS_FROM_LOCAL_POOL(ptr) 0
#endif // SANITIZER_RTEMS
diff --git a/libsanitizer/asan/asan_malloc_mac.cc b/libsanitizer/asan/asan_malloc_mac.cpp
index e34884b..e848468 100644
--- a/libsanitizer/asan/asan_malloc_mac.cc
+++ b/libsanitizer/asan/asan_malloc_mac.cpp
@@ -1,7 +1,8 @@
-//===-- asan_malloc_mac.cc ------------------------------------------------===//
+//===-- asan_malloc_mac.cpp -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -17,6 +18,7 @@
#include "asan_report.h"
#include "asan_stack.h"
#include "asan_stats.h"
+#include "lsan/lsan_common.h"
using namespace __asan;
#define COMMON_MALLOC_ZONE_NAME "asan"
@@ -56,7 +58,45 @@ using namespace __asan;
GET_STACK_TRACE_FREE; \
ReportMacMzReallocUnknown((uptr)ptr, (uptr)zone_ptr, zone_name, &stack);
#define COMMON_MALLOC_NAMESPACE __asan
+#define COMMON_MALLOC_HAS_ZONE_ENUMERATOR 0
+#define COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT 1
#include "sanitizer_common/sanitizer_malloc_mac.inc"
+namespace COMMON_MALLOC_NAMESPACE {
+
+bool HandleDlopenInit() {
+ static_assert(SANITIZER_SUPPORTS_INIT_FOR_DLOPEN,
+ "Expected SANITIZER_SUPPORTS_INIT_FOR_DLOPEN to be true");
+ // We have no reliable way of knowing how we are being loaded
+ // so make it a requirement on Apple platforms to set this environment
+ // variable to indicate that we want to perform initialization via
+ // dlopen().
+ auto init_str = GetEnv("APPLE_ASAN_INIT_FOR_DLOPEN");
+ if (!init_str)
+ return false;
+ if (internal_strncmp(init_str, "1", 1) != 0)
+ return false;
+ // When we are loaded via `dlopen()` path we still initialize the malloc zone
+ // so Symbolication clients (e.g. `leaks`) that load the ASan allocator can
+ // find an initialized malloc zone.
+ InitMallocZoneFields();
+ return true;
+}
+} // namespace COMMON_MALLOC_NAMESPACE
+
+namespace {
+
+void mi_extra_init(sanitizer_malloc_introspection_t *mi) {
+ uptr last_byte_plus_one = 0;
+ mi->allocator_ptr = 0;
+ // Range is [begin_ptr, end_ptr)
+ __lsan::GetAllocatorGlobalRange(&(mi->allocator_ptr), &last_byte_plus_one);
+ CHECK_NE(mi->allocator_ptr, 0);
+ CHECK_GT(last_byte_plus_one, mi->allocator_ptr);
+ mi->allocator_size = last_byte_plus_one - (mi->allocator_ptr);
+ CHECK_GT(mi->allocator_size, 0);
+}
+} // namespace
+
#endif
diff --git a/libsanitizer/asan/asan_malloc_win.cc b/libsanitizer/asan/asan_malloc_win.cc
deleted file mode 100644
index 2451860..0000000
--- a/libsanitizer/asan/asan_malloc_win.cc
+++ /dev/null
@@ -1,259 +0,0 @@
-//===-- asan_malloc_win.cc ------------------------------------------------===//
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-// Windows-specific malloc interception.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_WINDOWS
-// Intentionally not including windows.h here, to avoid the risk of
-// pulling in conflicting declarations of these functions. (With mingw-w64,
-// there's a risk of windows.h pulling in stdint.h.)
-typedef int BOOL;
-typedef void *HANDLE;
-typedef const void *LPCVOID;
-typedef void *LPVOID;
-
-#define HEAP_ZERO_MEMORY 0x00000008
-#define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010
-
-
-#include "asan_allocator.h"
-#include "asan_interceptors.h"
-#include "asan_internal.h"
-#include "asan_stack.h"
-#include "interception/interception.h"
-
-#include <stddef.h>
-
-using namespace __asan; // NOLINT
-
-// MT: Simply defining functions with the same signature in *.obj
-// files overrides the standard functions in the CRT.
-// MD: Memory allocation functions are defined in the CRT .dll,
-// so we have to intercept them before they are called for the first time.
-
-#if ASAN_DYNAMIC
-# define ALLOCATION_FUNCTION_ATTRIBUTE
-#else
-# define ALLOCATION_FUNCTION_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE
-#endif
-
-extern "C" {
-ALLOCATION_FUNCTION_ATTRIBUTE
-void free(void *ptr) {
- GET_STACK_TRACE_FREE;
- return asan_free(ptr, &stack, FROM_MALLOC);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void _free_dbg(void *ptr, int) {
- free(ptr);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void _free_base(void *ptr) {
- free(ptr);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *malloc(size_t size) {
- GET_STACK_TRACE_MALLOC;
- return asan_malloc(size, &stack);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_malloc_base(size_t size) {
- return malloc(size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_malloc_dbg(size_t size, int, const char *, int) {
- return malloc(size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *calloc(size_t nmemb, size_t size) {
- GET_STACK_TRACE_MALLOC;
- return asan_calloc(nmemb, size, &stack);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_calloc_base(size_t nmemb, size_t size) {
- return calloc(nmemb, size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_calloc_dbg(size_t nmemb, size_t size, int, const char *, int) {
- return calloc(nmemb, size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_calloc_impl(size_t nmemb, size_t size, int *errno_tmp) {
- return calloc(nmemb, size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *realloc(void *ptr, size_t size) {
- GET_STACK_TRACE_MALLOC;
- return asan_realloc(ptr, size, &stack);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_realloc_dbg(void *ptr, size_t size, int) {
- UNREACHABLE("_realloc_dbg should not exist!");
- return 0;
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_realloc_base(void *ptr, size_t size) {
- return realloc(ptr, size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_recalloc(void *p, size_t n, size_t elem_size) {
- if (!p)
- return calloc(n, elem_size);
- const size_t size = n * elem_size;
- if (elem_size != 0 && size / elem_size != n)
- return 0;
- return realloc(p, size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_recalloc_base(void *p, size_t n, size_t elem_size) {
- return _recalloc(p, n, elem_size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-size_t _msize(void *ptr) {
- GET_CURRENT_PC_BP_SP;
- (void)sp;
- return asan_malloc_usable_size(ptr, pc, bp);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_expand(void *memblock, size_t size) {
- // _expand is used in realloc-like functions to resize the buffer if possible.
- // We don't want memory to stand still while resizing buffers, so return 0.
- return 0;
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_expand_dbg(void *memblock, size_t size) {
- return _expand(memblock, size);
-}
-
-// TODO(timurrrr): Might want to add support for _aligned_* allocation
-// functions to detect a bit more bugs. Those functions seem to wrap malloc().
-
-int _CrtDbgReport(int, const char*, int,
- const char*, const char*, ...) {
- ShowStatsAndAbort();
-}
-
-int _CrtDbgReportW(int reportType, const wchar_t*, int,
- const wchar_t*, const wchar_t*, ...) {
- ShowStatsAndAbort();
-}
-
-int _CrtSetReportMode(int, int) {
- return 0;
-}
-} // extern "C"
-
-INTERCEPTOR_WINAPI(LPVOID, HeapAlloc, HANDLE hHeap, DWORD dwFlags,
- SIZE_T dwBytes) {
- GET_STACK_TRACE_MALLOC;
- void *p = asan_malloc(dwBytes, &stack);
- // Reading MSDN suggests that the *entire* usable allocation is zeroed out.
- // Otherwise it is difficult to HeapReAlloc with HEAP_ZERO_MEMORY.
- // https://blogs.msdn.microsoft.com/oldnewthing/20120316-00/?p=8083
- if (dwFlags == HEAP_ZERO_MEMORY)
- internal_memset(p, 0, asan_mz_size(p));
- else
- CHECK(dwFlags == 0 && "unsupported heap flags");
- return p;
-}
-
-INTERCEPTOR_WINAPI(BOOL, HeapFree, HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
- CHECK(dwFlags == 0 && "unsupported heap flags");
- GET_STACK_TRACE_FREE;
- asan_free(lpMem, &stack, FROM_MALLOC);
- return true;
-}
-
-INTERCEPTOR_WINAPI(LPVOID, HeapReAlloc, HANDLE hHeap, DWORD dwFlags,
- LPVOID lpMem, SIZE_T dwBytes) {
- GET_STACK_TRACE_MALLOC;
- // Realloc should never reallocate in place.
- if (dwFlags & HEAP_REALLOC_IN_PLACE_ONLY)
- return nullptr;
- CHECK(dwFlags == 0 && "unsupported heap flags");
- return asan_realloc(lpMem, dwBytes, &stack);
-}
-
-INTERCEPTOR_WINAPI(SIZE_T, HeapSize, HANDLE hHeap, DWORD dwFlags,
- LPCVOID lpMem) {
- CHECK(dwFlags == 0 && "unsupported heap flags");
- GET_CURRENT_PC_BP_SP;
- (void)sp;
- return asan_malloc_usable_size(lpMem, pc, bp);
-}
-
-namespace __asan {
-
-static void TryToOverrideFunction(const char *fname, uptr new_func) {
- // Failure here is not fatal. The CRT may not be present, and different CRT
- // versions use different symbols.
- if (!__interception::OverrideFunction(fname, new_func))
- VPrintf(2, "Failed to override function %s\n", fname);
-}
-
-void ReplaceSystemMalloc() {
-#if defined(ASAN_DYNAMIC)
- TryToOverrideFunction("free", (uptr)free);
- TryToOverrideFunction("_free_base", (uptr)free);
- TryToOverrideFunction("malloc", (uptr)malloc);
- TryToOverrideFunction("_malloc_base", (uptr)malloc);
- TryToOverrideFunction("_malloc_crt", (uptr)malloc);
- TryToOverrideFunction("calloc", (uptr)calloc);
- TryToOverrideFunction("_calloc_base", (uptr)calloc);
- TryToOverrideFunction("_calloc_crt", (uptr)calloc);
- TryToOverrideFunction("realloc", (uptr)realloc);
- TryToOverrideFunction("_realloc_base", (uptr)realloc);
- TryToOverrideFunction("_realloc_crt", (uptr)realloc);
- TryToOverrideFunction("_recalloc", (uptr)_recalloc);
- TryToOverrideFunction("_recalloc_base", (uptr)_recalloc);
- TryToOverrideFunction("_recalloc_crt", (uptr)_recalloc);
- TryToOverrideFunction("_msize", (uptr)_msize);
- TryToOverrideFunction("_expand", (uptr)_expand);
- TryToOverrideFunction("_expand_base", (uptr)_expand);
-
- // Recent versions of ucrtbase.dll appear to be built with PGO and LTCG, which
- // enable cross-module inlining. This means our _malloc_base hook won't catch
- // all CRT allocations. This code here patches the import table of
- // ucrtbase.dll so that all attempts to use the lower-level win32 heap
- // allocation API will be directed to ASan's heap. We don't currently
- // intercept all calls to HeapAlloc. If we did, we would have to check on
- // HeapFree whether the pointer came from ASan of from the system.
-#define INTERCEPT_UCRT_FUNCTION(func) \
- if (!INTERCEPT_FUNCTION_DLLIMPORT("ucrtbase.dll", \
- "api-ms-win-core-heap-l1-1-0.dll", func)) \
- VPrintf(2, "Failed to intercept ucrtbase.dll import %s\n", #func);
- INTERCEPT_UCRT_FUNCTION(HeapAlloc);
- INTERCEPT_UCRT_FUNCTION(HeapFree);
- INTERCEPT_UCRT_FUNCTION(HeapReAlloc);
- INTERCEPT_UCRT_FUNCTION(HeapSize);
-#undef INTERCEPT_UCRT_FUNCTION
-#endif
-}
-} // namespace __asan
-
-#endif // _WIN32
diff --git a/libsanitizer/asan/asan_malloc_win.cpp b/libsanitizer/asan/asan_malloc_win.cpp
new file mode 100644
index 0000000..291d411e
--- /dev/null
+++ b/libsanitizer/asan/asan_malloc_win.cpp
@@ -0,0 +1,553 @@
+//===-- asan_malloc_win.cpp -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// Windows-specific malloc interception.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_common/sanitizer_allocator_interface.h"
+#include "sanitizer_common/sanitizer_platform.h"
+#if SANITIZER_WINDOWS
+#include "asan_allocator.h"
+#include "asan_interceptors.h"
+#include "asan_internal.h"
+#include "asan_stack.h"
+#include "interception/interception.h"
+#include <stddef.h>
+
+// Intentionally not including windows.h here, to avoid the risk of
+// pulling in conflicting declarations of these functions. (With mingw-w64,
+// there's a risk of windows.h pulling in stdint.h.)
+typedef int BOOL;
+typedef void *HANDLE;
+typedef const void *LPCVOID;
+typedef void *LPVOID;
+
+typedef unsigned long DWORD;
+constexpr unsigned long HEAP_ZERO_MEMORY = 0x00000008;
+constexpr unsigned long HEAP_REALLOC_IN_PLACE_ONLY = 0x00000010;
+constexpr unsigned long HEAP_ALLOCATE_SUPPORTED_FLAGS = (HEAP_ZERO_MEMORY);
+constexpr unsigned long HEAP_ALLOCATE_UNSUPPORTED_FLAGS =
+ (~HEAP_ALLOCATE_SUPPORTED_FLAGS);
+constexpr unsigned long HEAP_FREE_SUPPORTED_FLAGS = (0);
+constexpr unsigned long HEAP_FREE_UNSUPPORTED_FLAGS =
+ (~HEAP_ALLOCATE_SUPPORTED_FLAGS);
+constexpr unsigned long HEAP_REALLOC_SUPPORTED_FLAGS =
+ (HEAP_REALLOC_IN_PLACE_ONLY | HEAP_ZERO_MEMORY);
+constexpr unsigned long HEAP_REALLOC_UNSUPPORTED_FLAGS =
+ (~HEAP_ALLOCATE_SUPPORTED_FLAGS);
+
+
+extern "C" {
+LPVOID WINAPI HeapAlloc(HANDLE hHeap, DWORD dwFlags, size_t dwBytes);
+LPVOID WINAPI HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem,
+ size_t dwBytes);
+BOOL WINAPI HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem);
+size_t WINAPI HeapSize(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem);
+
+BOOL WINAPI HeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem);
+}
+
+using namespace __asan; // NOLINT
+
+// MT: Simply defining functions with the same signature in *.obj
+// files overrides the standard functions in the CRT.
+// MD: Memory allocation functions are defined in the CRT .dll,
+// so we have to intercept them before they are called for the first time.
+
+#if ASAN_DYNAMIC
+# define ALLOCATION_FUNCTION_ATTRIBUTE
+#else
+# define ALLOCATION_FUNCTION_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE
+#endif
+
+extern "C" {
+ALLOCATION_FUNCTION_ATTRIBUTE
+size_t _msize(void *ptr) {
+ GET_CURRENT_PC_BP_SP;
+ (void)sp;
+ return asan_malloc_usable_size(ptr, pc, bp);
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+size_t _msize_base(void *ptr) {
+ return _msize(ptr);
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void free(void *ptr) {
+ GET_STACK_TRACE_FREE;
+ return asan_free(ptr, &stack, FROM_MALLOC);
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void _free_dbg(void *ptr, int) {
+ free(ptr);
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void _free_base(void *ptr) {
+ free(ptr);
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *malloc(size_t size) {
+ GET_STACK_TRACE_MALLOC;
+ return asan_malloc(size, &stack);
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_malloc_base(size_t size) {
+ return malloc(size);
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_malloc_dbg(size_t size, int, const char *, int) {
+ return malloc(size);
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *calloc(size_t nmemb, size_t size) {
+ GET_STACK_TRACE_MALLOC;
+ return asan_calloc(nmemb, size, &stack);
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_calloc_base(size_t nmemb, size_t size) {
+ return calloc(nmemb, size);
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_calloc_dbg(size_t nmemb, size_t size, int, const char *, int) {
+ return calloc(nmemb, size);
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_calloc_impl(size_t nmemb, size_t size, int *errno_tmp) {
+ return calloc(nmemb, size);
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *realloc(void *ptr, size_t size) {
+ GET_STACK_TRACE_MALLOC;
+ return asan_realloc(ptr, size, &stack);
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_realloc_dbg(void *ptr, size_t size, int) {
+ UNREACHABLE("_realloc_dbg should not exist!");
+ return 0;
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_realloc_base(void *ptr, size_t size) {
+ return realloc(ptr, size);
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_recalloc(void *p, size_t n, size_t elem_size) {
+ if (!p)
+ return calloc(n, elem_size);
+ const size_t size = n * elem_size;
+ if (elem_size != 0 && size / elem_size != n)
+ return 0;
+
+ size_t old_size = _msize(p);
+ void *new_alloc = malloc(size);
+ if (new_alloc) {
+ REAL(memcpy)(new_alloc, p, Min<size_t>(size, old_size));
+ if (old_size < size)
+ REAL(memset)(((u8 *)new_alloc) + old_size, 0, size - old_size);
+ free(p);
+ }
+ return new_alloc;
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_recalloc_base(void *p, size_t n, size_t elem_size) {
+ return _recalloc(p, n, elem_size);
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_expand(void *memblock, size_t size) {
+ // _expand is used in realloc-like functions to resize the buffer if possible.
+ // We don't want memory to stand still while resizing buffers, so return 0.
+ return 0;
+}
+
+ALLOCATION_FUNCTION_ATTRIBUTE
+void *_expand_dbg(void *memblock, size_t size) {
+ return _expand(memblock, size);
+}
+
+// TODO(timurrrr): Might want to add support for _aligned_* allocation
+// functions to detect a bit more bugs. Those functions seem to wrap malloc().
+
+int _CrtDbgReport(int, const char*, int,
+ const char*, const char*, ...) {
+ ShowStatsAndAbort();
+}
+
+int _CrtDbgReportW(int reportType, const wchar_t*, int,
+ const wchar_t*, const wchar_t*, ...) {
+ ShowStatsAndAbort();
+}
+
+int _CrtSetReportMode(int, int) {
+ return 0;
+}
+} // extern "C"
+
+#define OWNED_BY_RTL(heap, memory) \
+ (!__sanitizer_get_ownership(memory) && HeapValidate(heap, 0, memory))
+
+INTERCEPTOR_WINAPI(size_t, HeapSize, HANDLE hHeap, DWORD dwFlags,
+ LPCVOID lpMem) {
+ // If the RTL allocators are hooked we need to check whether the ASAN
+ // allocator owns the pointer we're about to use. Allocations occur before
+ // interception takes place, so if it is not owned by the RTL heap we can
+ // pass it to the ASAN heap for inspection.
+ if (flags()->windows_hook_rtl_allocators) {
+ if (!asan_inited || OWNED_BY_RTL(hHeap, lpMem))
+ return REAL(HeapSize)(hHeap, dwFlags, lpMem);
+ } else {
+ CHECK(dwFlags == 0 && "unsupported heap flags");
+ }
+ GET_CURRENT_PC_BP_SP;
+ (void)sp;
+ return asan_malloc_usable_size(lpMem, pc, bp);
+}
+
+INTERCEPTOR_WINAPI(LPVOID, HeapAlloc, HANDLE hHeap, DWORD dwFlags,
+ size_t dwBytes) {
+ // If the ASAN runtime is not initialized, or we encounter an unsupported
+ // flag, fall back to the original allocator.
+ if (flags()->windows_hook_rtl_allocators) {
+ if (UNLIKELY(!asan_inited ||
+ (dwFlags & HEAP_ALLOCATE_UNSUPPORTED_FLAGS) != 0)) {
+ return REAL(HeapAlloc)(hHeap, dwFlags, dwBytes);
+ }
+ } else {
+ // In the case that we don't hook the rtl allocators,
+ // this becomes an assert since there is no failover to the original
+ // allocator.
+ CHECK((HEAP_ALLOCATE_UNSUPPORTED_FLAGS & dwFlags) != 0 &&
+ "unsupported flags");
+ }
+ GET_STACK_TRACE_MALLOC;
+ void *p = asan_malloc(dwBytes, &stack);
+ // Reading MSDN suggests that the *entire* usable allocation is zeroed out.
+ // Otherwise it is difficult to HeapReAlloc with HEAP_ZERO_MEMORY.
+ // https://blogs.msdn.microsoft.com/oldnewthing/20120316-00/?p=8083
+ if (p && (dwFlags & HEAP_ZERO_MEMORY)) {
+ GET_CURRENT_PC_BP_SP;
+ (void)sp;
+ auto usable_size = asan_malloc_usable_size(p, pc, bp);
+ internal_memset(p, 0, usable_size);
+ }
+ return p;
+}
+
+INTERCEPTOR_WINAPI(BOOL, HeapFree, HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
+ // Heap allocations happen before this function is hooked, so we must fall
+ // back to the original function if the pointer is not from the ASAN heap,
+ // or unsupported flags are provided.
+ if (flags()->windows_hook_rtl_allocators) {
+ if (OWNED_BY_RTL(hHeap, lpMem))
+ return REAL(HeapFree)(hHeap, dwFlags, lpMem);
+ } else {
+ CHECK((HEAP_FREE_UNSUPPORTED_FLAGS & dwFlags) != 0 && "unsupported flags");
+ }
+ GET_STACK_TRACE_FREE;
+ asan_free(lpMem, &stack, FROM_MALLOC);
+ return true;
+}
+
+namespace __asan {
+using AllocFunction = LPVOID(WINAPI *)(HANDLE, DWORD, size_t);
+using ReAllocFunction = LPVOID(WINAPI *)(HANDLE, DWORD, LPVOID, size_t);
+using SizeFunction = size_t(WINAPI *)(HANDLE, DWORD, LPVOID);
+using FreeFunction = BOOL(WINAPI *)(HANDLE, DWORD, LPVOID);
+
+void *SharedReAlloc(ReAllocFunction reallocFunc, SizeFunction heapSizeFunc,
+ FreeFunction freeFunc, AllocFunction allocFunc,
+ HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, size_t dwBytes) {
+ CHECK(reallocFunc && heapSizeFunc && freeFunc && allocFunc);
+ GET_STACK_TRACE_MALLOC;
+ GET_CURRENT_PC_BP_SP;
+ (void)sp;
+ if (flags()->windows_hook_rtl_allocators) {
+ enum AllocationOwnership { NEITHER = 0, ASAN = 1, RTL = 2 };
+ AllocationOwnership ownershipState;
+ bool owned_rtlalloc = false;
+ bool owned_asan = __sanitizer_get_ownership(lpMem);
+
+ if (!owned_asan)
+ owned_rtlalloc = HeapValidate(hHeap, 0, lpMem);
+
+ if (owned_asan && !owned_rtlalloc)
+ ownershipState = ASAN;
+ else if (!owned_asan && owned_rtlalloc)
+ ownershipState = RTL;
+ else if (!owned_asan && !owned_rtlalloc)
+ ownershipState = NEITHER;
+
+ // If this heap block which was allocated before the ASAN
+ // runtime came up, use the real HeapFree function.
+ if (UNLIKELY(!asan_inited)) {
+ return reallocFunc(hHeap, dwFlags, lpMem, dwBytes);
+ }
+ bool only_asan_supported_flags =
+ (HEAP_REALLOC_UNSUPPORTED_FLAGS & dwFlags) == 0;
+
+ if (ownershipState == RTL ||
+ (ownershipState == NEITHER && !only_asan_supported_flags)) {
+ if (only_asan_supported_flags) {
+ // if this is a conversion to ASAN upported flags, transfer this
+ // allocation to the ASAN allocator
+ void *replacement_alloc;
+ if (dwFlags & HEAP_ZERO_MEMORY)
+ replacement_alloc = asan_calloc(1, dwBytes, &stack);
+ else
+ replacement_alloc = asan_malloc(dwBytes, &stack);
+ if (replacement_alloc) {
+ size_t old_size = heapSizeFunc(hHeap, dwFlags, lpMem);
+ if (old_size == ((size_t)0) - 1) {
+ asan_free(replacement_alloc, &stack, FROM_MALLOC);
+ return nullptr;
+ }
+ REAL(memcpy)(replacement_alloc, lpMem, old_size);
+ freeFunc(hHeap, dwFlags, lpMem);
+ }
+ return replacement_alloc;
+ } else {
+ // owned by rtl or neither with unsupported ASAN flags,
+ // just pass back to original allocator
+ CHECK(ownershipState == RTL || ownershipState == NEITHER);
+ CHECK(!only_asan_supported_flags);
+ return reallocFunc(hHeap, dwFlags, lpMem, dwBytes);
+ }
+ }
+
+ if (ownershipState == ASAN && !only_asan_supported_flags) {
+ // Conversion to unsupported flags allocation,
+ // transfer this allocation back to the original allocator.
+ void *replacement_alloc = allocFunc(hHeap, dwFlags, dwBytes);
+ size_t old_usable_size = 0;
+ if (replacement_alloc) {
+ old_usable_size = asan_malloc_usable_size(lpMem, pc, bp);
+ REAL(memcpy)(replacement_alloc, lpMem,
+ Min<size_t>(dwBytes, old_usable_size));
+ asan_free(lpMem, &stack, FROM_MALLOC);
+ }
+ return replacement_alloc;
+ }
+
+ CHECK((ownershipState == ASAN || ownershipState == NEITHER) &&
+ only_asan_supported_flags);
+ // At this point we should either be ASAN owned with ASAN supported flags
+ // or we owned by neither and have supported flags.
+ // Pass through even when it's neither since this could be a null realloc or
+ // UAF that ASAN needs to catch.
+ } else {
+ CHECK((HEAP_REALLOC_UNSUPPORTED_FLAGS & dwFlags) != 0 &&
+ "unsupported flags");
+ }
+ // asan_realloc will never reallocate in place, so for now this flag is
+ // unsupported until we figure out a way to fake this.
+ if (dwFlags & HEAP_REALLOC_IN_PLACE_ONLY)
+ return nullptr;
+
+ // HeapReAlloc and HeapAlloc both happily accept 0 sized allocations.
+ // passing a 0 size into asan_realloc will free the allocation.
+ // To avoid this and keep behavior consistent, fudge the size if 0.
+ // (asan_malloc already does this)
+ if (dwBytes == 0)
+ dwBytes = 1;
+
+ size_t old_size;
+ if (dwFlags & HEAP_ZERO_MEMORY)
+ old_size = asan_malloc_usable_size(lpMem, pc, bp);
+
+ void *ptr = asan_realloc(lpMem, dwBytes, &stack);
+ if (ptr == nullptr)
+ return nullptr;
+
+ if (dwFlags & HEAP_ZERO_MEMORY) {
+ size_t new_size = asan_malloc_usable_size(ptr, pc, bp);
+ if (old_size < new_size)
+ REAL(memset)(((u8 *)ptr) + old_size, 0, new_size - old_size);
+ }
+
+ return ptr;
+}
+} // namespace __asan
+
+INTERCEPTOR_WINAPI(LPVOID, HeapReAlloc, HANDLE hHeap, DWORD dwFlags,
+ LPVOID lpMem, size_t dwBytes) {
+ return SharedReAlloc(REAL(HeapReAlloc), (SizeFunction)REAL(HeapSize),
+ REAL(HeapFree), REAL(HeapAlloc), hHeap, dwFlags, lpMem,
+ dwBytes);
+}
+
+// The following functions are undocumented and subject to change.
+// However, hooking them is necessary to hook Windows heap
+// allocations with detours and their definitions are unlikely to change.
+// Comments in /minkernel/ntos/rtl/heappublic.c indicate that these functions
+// are part of the heap's public interface.
+typedef unsigned long LOGICAL;
+
+// This function is documented as part of the Driver Development Kit but *not*
+// the Windows Development Kit.
+LOGICAL RtlFreeHeap(void* HeapHandle, DWORD Flags,
+ void* BaseAddress);
+
+// This function is documented as part of the Driver Development Kit but *not*
+// the Windows Development Kit.
+void* RtlAllocateHeap(void* HeapHandle, DWORD Flags, size_t Size);
+
+// This function is completely undocumented.
+void*
+RtlReAllocateHeap(void* HeapHandle, DWORD Flags, void* BaseAddress,
+ size_t Size);
+
+// This function is completely undocumented.
+size_t RtlSizeHeap(void* HeapHandle, DWORD Flags, void* BaseAddress);
+
+INTERCEPTOR_WINAPI(size_t, RtlSizeHeap, HANDLE HeapHandle, DWORD Flags,
+ void* BaseAddress) {
+ if (!flags()->windows_hook_rtl_allocators ||
+ UNLIKELY(!asan_inited || OWNED_BY_RTL(HeapHandle, BaseAddress))) {
+ return REAL(RtlSizeHeap)(HeapHandle, Flags, BaseAddress);
+ }
+ GET_CURRENT_PC_BP_SP;
+ (void)sp;
+ return asan_malloc_usable_size(BaseAddress, pc, bp);
+}
+
+INTERCEPTOR_WINAPI(BOOL, RtlFreeHeap, HANDLE HeapHandle, DWORD Flags,
+ void* BaseAddress) {
+ // Heap allocations happen before this function is hooked, so we must fall
+ // back to the original function if the pointer is not from the ASAN heap, or
+ // unsupported flags are provided.
+ if (!flags()->windows_hook_rtl_allocators ||
+ UNLIKELY((HEAP_FREE_UNSUPPORTED_FLAGS & Flags) != 0 ||
+ OWNED_BY_RTL(HeapHandle, BaseAddress))) {
+ return REAL(RtlFreeHeap)(HeapHandle, Flags, BaseAddress);
+ }
+ GET_STACK_TRACE_FREE;
+ asan_free(BaseAddress, &stack, FROM_MALLOC);
+ return true;
+}
+
+INTERCEPTOR_WINAPI(void*, RtlAllocateHeap, HANDLE HeapHandle, DWORD Flags,
+ size_t Size) {
+ // If the ASAN runtime is not initialized, or we encounter an unsupported
+ // flag, fall back to the original allocator.
+ if (!flags()->windows_hook_rtl_allocators ||
+ UNLIKELY(!asan_inited ||
+ (Flags & HEAP_ALLOCATE_UNSUPPORTED_FLAGS) != 0)) {
+ return REAL(RtlAllocateHeap)(HeapHandle, Flags, Size);
+ }
+ GET_STACK_TRACE_MALLOC;
+ void *p;
+ // Reading MSDN suggests that the *entire* usable allocation is zeroed out.
+ // Otherwise it is difficult to HeapReAlloc with HEAP_ZERO_MEMORY.
+ // https://blogs.msdn.microsoft.com/oldnewthing/20120316-00/?p=8083
+ if (Flags & HEAP_ZERO_MEMORY) {
+ p = asan_calloc(Size, 1, &stack);
+ } else {
+ p = asan_malloc(Size, &stack);
+ }
+ return p;
+}
+
+INTERCEPTOR_WINAPI(void*, RtlReAllocateHeap, HANDLE HeapHandle, DWORD Flags,
+ void* BaseAddress, size_t Size) {
+ // If it's actually a heap block which was allocated before the ASAN runtime
+ // came up, use the real RtlFreeHeap function.
+ if (!flags()->windows_hook_rtl_allocators)
+ return REAL(RtlReAllocateHeap)(HeapHandle, Flags, BaseAddress, Size);
+
+ return SharedReAlloc(REAL(RtlReAllocateHeap), REAL(RtlSizeHeap),
+ REAL(RtlFreeHeap), REAL(RtlAllocateHeap), HeapHandle,
+ Flags, BaseAddress, Size);
+}
+
+namespace __asan {
+
+static void TryToOverrideFunction(const char *fname, uptr new_func) {
+ // Failure here is not fatal. The CRT may not be present, and different CRT
+ // versions use different symbols.
+ if (!__interception::OverrideFunction(fname, new_func))
+ VPrintf(2, "Failed to override function %s\n", fname);
+}
+
+void ReplaceSystemMalloc() {
+#if defined(ASAN_DYNAMIC)
+ TryToOverrideFunction("free", (uptr)free);
+ TryToOverrideFunction("_free_base", (uptr)free);
+ TryToOverrideFunction("malloc", (uptr)malloc);
+ TryToOverrideFunction("_malloc_base", (uptr)malloc);
+ TryToOverrideFunction("_malloc_crt", (uptr)malloc);
+ TryToOverrideFunction("calloc", (uptr)calloc);
+ TryToOverrideFunction("_calloc_base", (uptr)calloc);
+ TryToOverrideFunction("_calloc_crt", (uptr)calloc);
+ TryToOverrideFunction("realloc", (uptr)realloc);
+ TryToOverrideFunction("_realloc_base", (uptr)realloc);
+ TryToOverrideFunction("_realloc_crt", (uptr)realloc);
+ TryToOverrideFunction("_recalloc", (uptr)_recalloc);
+ TryToOverrideFunction("_recalloc_base", (uptr)_recalloc);
+ TryToOverrideFunction("_recalloc_crt", (uptr)_recalloc);
+ TryToOverrideFunction("_msize", (uptr)_msize);
+ TryToOverrideFunction("_msize_base", (uptr)_msize);
+ TryToOverrideFunction("_expand", (uptr)_expand);
+ TryToOverrideFunction("_expand_base", (uptr)_expand);
+
+ if (flags()->windows_hook_rtl_allocators) {
+ INTERCEPT_FUNCTION(HeapSize);
+ INTERCEPT_FUNCTION(HeapFree);
+ INTERCEPT_FUNCTION(HeapReAlloc);
+ INTERCEPT_FUNCTION(HeapAlloc);
+
+ // Undocumented functions must be intercepted by name, not by symbol.
+ __interception::OverrideFunction("RtlSizeHeap", (uptr)WRAP(RtlSizeHeap),
+ (uptr *)&REAL(RtlSizeHeap));
+ __interception::OverrideFunction("RtlFreeHeap", (uptr)WRAP(RtlFreeHeap),
+ (uptr *)&REAL(RtlFreeHeap));
+ __interception::OverrideFunction("RtlReAllocateHeap",
+ (uptr)WRAP(RtlReAllocateHeap),
+ (uptr *)&REAL(RtlReAllocateHeap));
+ __interception::OverrideFunction("RtlAllocateHeap",
+ (uptr)WRAP(RtlAllocateHeap),
+ (uptr *)&REAL(RtlAllocateHeap));
+ } else {
+#define INTERCEPT_UCRT_FUNCTION(func) \
+ if (!INTERCEPT_FUNCTION_DLLIMPORT("ucrtbase.dll", \
+ "api-ms-win-core-heap-l1-1-0.dll", func)) \
+ VPrintf(2, "Failed to intercept ucrtbase.dll import %s\n", #func);
+ INTERCEPT_UCRT_FUNCTION(HeapAlloc);
+ INTERCEPT_UCRT_FUNCTION(HeapFree);
+ INTERCEPT_UCRT_FUNCTION(HeapReAlloc);
+ INTERCEPT_UCRT_FUNCTION(HeapSize);
+#undef INTERCEPT_UCRT_FUNCTION
+ }
+ // Recent versions of ucrtbase.dll appear to be built with PGO and LTCG, which
+ // enable cross-module inlining. This means our _malloc_base hook won't catch
+ // all CRT allocations. This code here patches the import table of
+ // ucrtbase.dll so that all attempts to use the lower-level win32 heap
+ // allocation API will be directed to ASan's heap. We don't currently
+ // intercept all calls to HeapAlloc. If we did, we would have to check on
+ // HeapFree whether the pointer came from ASan of from the system.
+
+#endif // defined(ASAN_DYNAMIC)
+}
+} // namespace __asan
+
+#endif // _WIN32
diff --git a/libsanitizer/asan/asan_mapping.h b/libsanitizer/asan/asan_mapping.h
index 2357c50..09be904 100644
--- a/libsanitizer/asan/asan_mapping.h
+++ b/libsanitizer/asan/asan_mapping.h
@@ -1,7 +1,8 @@
//===-- asan_mapping.h ------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -159,10 +160,6 @@ static const u64 kDefaultShadowOffset32 = 1ULL << 29; // 0x20000000
static const u64 kDefaultShadowOffset64 = 1ULL << 44;
static const u64 kDefaultShort64bitShadowOffset =
0x7FFFFFFF & (~0xFFFULL << kDefaultShadowScale); // < 2G.
-static const u64 kIosShadowOffset32 = 1ULL << 30; // 0x40000000
-static const u64 kIosShadowOffset64 = 0x120200000;
-static const u64 kIosSimShadowOffset32 = 1ULL << 30;
-static const u64 kIosSimShadowOffset64 = kDefaultShadowOffset64;
static const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000;
static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37;
@@ -200,11 +197,7 @@ static const u64 kMyriadCacheBitMask32 = 0x40000000ULL;
# elif SANITIZER_WINDOWS
# define SHADOW_OFFSET kWindowsShadowOffset32
# elif SANITIZER_IOS
-# if SANITIZER_IOSSIM
-# define SHADOW_OFFSET kIosSimShadowOffset32
-# else
-# define SHADOW_OFFSET kIosShadowOffset32
-# endif
+# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
# elif SANITIZER_MYRIAD2
# define SHADOW_OFFSET kMyriadShadowOffset32
# else
@@ -212,11 +205,7 @@ static const u64 kMyriadCacheBitMask32 = 0x40000000ULL;
# endif
#else
# if SANITIZER_IOS
-# if SANITIZER_IOSSIM
-# define SHADOW_OFFSET kIosSimShadowOffset64
-# else
-# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
-# endif
+# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
# elif defined(__aarch64__)
# define SHADOW_OFFSET kAArch64_ShadowOffset64
# elif defined(__powerpc64__)
@@ -231,8 +220,8 @@ static const u64 kMyriadCacheBitMask32 = 0x40000000ULL;
# define SHADOW_OFFSET kDefaultShadowOffset64
# elif defined(__mips64)
# define SHADOW_OFFSET kMIPS64_ShadowOffset64
-# elif defined(__sparc__)
-# define SHADOW_OFFSET kSPARC64_ShadowOffset64
+#elif defined(__sparc__)
+#define SHADOW_OFFSET kSPARC64_ShadowOffset64
# elif SANITIZER_WINDOWS64
# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
# else
diff --git a/libsanitizer/asan/asan_mapping_myriad.h b/libsanitizer/asan/asan_mapping_myriad.h
index fa8d4fe..6969e3a 100644
--- a/libsanitizer/asan/asan_mapping_myriad.h
+++ b/libsanitizer/asan/asan_mapping_myriad.h
@@ -1,7 +1,8 @@
//===-- asan_mapping_myriad.h -----------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_mapping_sparc64.h b/libsanitizer/asan/asan_mapping_sparc64.h
index ecde5ca..432a181 100644
--- a/libsanitizer/asan/asan_mapping_sparc64.h
+++ b/libsanitizer/asan/asan_mapping_sparc64.h
@@ -1,7 +1,8 @@
//===-- asan_mapping_sparc64.h ----------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_memory_profile.cc b/libsanitizer/asan/asan_memory_profile.cpp
index 23183bd..4fcd560 100644
--- a/libsanitizer/asan/asan_memory_profile.cc
+++ b/libsanitizer/asan/asan_memory_profile.cpp
@@ -1,7 +1,8 @@
-//===-- asan_memory_profile.cc.cc -----------------------------------------===//
+//===-- asan_memory_profile.cpp ----------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_new_delete.cc b/libsanitizer/asan/asan_new_delete.cpp
index 7e194e2..c15e208 100644
--- a/libsanitizer/asan/asan_new_delete.cc
+++ b/libsanitizer/asan/asan_new_delete.cpp
@@ -1,7 +1,8 @@
-//===-- asan_interceptors.cc ----------------------------------------------===//
+//===-- asan_interceptors.cpp ---------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -70,25 +71,19 @@ enum class align_val_t: size_t {};
// TODO(alekseyshl): throw std::bad_alloc instead of dying on OOM.
// For local pool allocation, align to SHADOW_GRANULARITY to match asan
// allocator behavior.
-#define OPERATOR_NEW_BODY(type, nothrow) \
- if (ALLOCATE_FROM_LOCAL_POOL) {\
- void *res = MemalignFromLocalPool(SHADOW_GRANULARITY, size);\
- if (!nothrow) CHECK(res);\
- return res;\
- }\
- GET_STACK_TRACE_MALLOC;\
- void *res = asan_memalign(0, size, &stack, type);\
- if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
+#define OPERATOR_NEW_BODY(type, nothrow) \
+ MAYBE_ALLOCATE_FROM_LOCAL_POOL(nothrow); \
+ GET_STACK_TRACE_MALLOC; \
+ void *res = asan_memalign(0, size, &stack, type); \
+ if (!nothrow && UNLIKELY(!res)) \
+ ReportOutOfMemory(size, &stack); \
return res;
-#define OPERATOR_NEW_BODY_ALIGN(type, nothrow) \
- if (ALLOCATE_FROM_LOCAL_POOL) {\
- void *res = MemalignFromLocalPool((uptr)align, size);\
- if (!nothrow) CHECK(res);\
- return res;\
- }\
- GET_STACK_TRACE_MALLOC;\
- void *res = asan_memalign((uptr)align, size, &stack, type);\
- if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
+#define OPERATOR_NEW_BODY_ALIGN(type, nothrow) \
+ MAYBE_ALLOCATE_FROM_LOCAL_POOL(nothrow); \
+ GET_STACK_TRACE_MALLOC; \
+ void *res = asan_memalign((uptr)align, size, &stack, type); \
+ if (!nothrow && UNLIKELY(!res)) \
+ ReportOutOfMemory(size, &stack); \
return res;
// On OS X it's not enough to just provide our own 'operator new' and
diff --git a/libsanitizer/asan/asan_poisoning.cc b/libsanitizer/asan/asan_poisoning.cpp
index 35409ba..6b36be7 100644
--- a/libsanitizer/asan/asan_poisoning.cc
+++ b/libsanitizer/asan/asan_poisoning.cpp
@@ -1,7 +1,8 @@
-//===-- asan_poisoning.cc -------------------------------------------------===//
+//===-- asan_poisoning.cpp ------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_poisoning.h b/libsanitizer/asan/asan_poisoning.h
index 7e8c588..62dd9bd 100644
--- a/libsanitizer/asan/asan_poisoning.h
+++ b/libsanitizer/asan/asan_poisoning.h
@@ -1,7 +1,8 @@
//===-- asan_poisoning.h ----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -14,6 +15,7 @@
#include "asan_internal.h"
#include "asan_mapping.h"
#include "sanitizer_common/sanitizer_flags.h"
+#include "sanitizer_common/sanitizer_platform.h"
namespace __asan {
@@ -37,6 +39,10 @@ void PoisonShadowPartialRightRedzone(uptr addr,
ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
u8 value) {
DCHECK(!value || CanPoisonMemory());
+#if SANITIZER_FUCHSIA
+ __sanitizer_fill_shadow(aligned_beg, aligned_size, value,
+ common_flags()->clear_shadow_mmap_threshold);
+#else
uptr shadow_beg = MEM_TO_SHADOW(aligned_beg);
uptr shadow_end = MEM_TO_SHADOW(
aligned_beg + aligned_size - SHADOW_GRANULARITY) + 1;
@@ -45,10 +51,6 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
// probably provide higher-level interface for these operations.
// For now, just memset on Windows.
if (value || SANITIZER_WINDOWS == 1 ||
- // TODO(mcgrathr): Fuchsia doesn't allow the shadow mapping to be
- // changed at all. It doesn't currently have an efficient means
- // to zero a bunch of pages, but maybe we should add one.
- SANITIZER_FUCHSIA == 1 ||
// RTEMS doesn't have have pages, let alone a fast way to zero
// them, so default to memset.
SANITIZER_RTEMS == 1 ||
@@ -71,6 +73,7 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
ReserveShadowMemoryRange(page_beg, page_end - 1, nullptr);
}
}
+#endif // SANITIZER_FUCHSIA
}
ALWAYS_INLINE void FastPoisonShadowPartialRightRedzone(
diff --git a/libsanitizer/asan/asan_posix.cc b/libsanitizer/asan/asan_posix.cpp
index d765dc7..920d216 100644
--- a/libsanitizer/asan/asan_posix.cc
+++ b/libsanitizer/asan/asan_posix.cpp
@@ -1,7 +1,8 @@
-//===-- asan_posix.cc -----------------------------------------------------===//
+//===-- asan_posix.cpp ----------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -38,6 +39,51 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
// ---------------------- TSD ---------------- {{{1
+#if SANITIZER_NETBSD && !ASAN_DYNAMIC
+// Thread Static Data cannot be used in early static ASan init on NetBSD.
+// Reuse the Asan TSD API for compatibility with existing code
+// with an alternative implementation.
+
+static void (*tsd_destructor)(void *tsd) = nullptr;
+
+struct tsd_key {
+ tsd_key() : key(nullptr) {}
+ ~tsd_key() {
+ CHECK(tsd_destructor);
+ if (key)
+ (*tsd_destructor)(key);
+ }
+ void *key;
+};
+
+static thread_local struct tsd_key key;
+
+void AsanTSDInit(void (*destructor)(void *tsd)) {
+ CHECK(!tsd_destructor);
+ tsd_destructor = destructor;
+}
+
+void *AsanTSDGet() {
+ CHECK(tsd_destructor);
+ return key.key;
+}
+
+void AsanTSDSet(void *tsd) {
+ CHECK(tsd_destructor);
+ CHECK(tsd);
+ CHECK(!key.key);
+ key.key = tsd;
+}
+
+void PlatformTSDDtor(void *tsd) {
+ CHECK(tsd_destructor);
+ CHECK_EQ(key.key, tsd);
+ key.key = nullptr;
+ // Make sure that signal handler can not see a stale current thread pointer.
+ atomic_signal_fence(memory_order_seq_cst);
+ AsanThread::TSDDtor(tsd);
+}
+#else
static pthread_key_t tsd_key;
static bool tsd_key_inited = false;
void AsanTSDInit(void (*destructor)(void *tsd)) {
@@ -65,6 +111,7 @@ void PlatformTSDDtor(void *tsd) {
}
AsanThread::TSDDtor(tsd);
}
+#endif
} // namespace __asan
#endif // SANITIZER_POSIX
diff --git a/libsanitizer/asan/asan_preinit.cc b/libsanitizer/asan/asan_preinit.cpp
index 6cb115b..b07556e 100644
--- a/libsanitizer/asan/asan_preinit.cc
+++ b/libsanitizer/asan/asan_preinit.cpp
@@ -1,7 +1,8 @@
-//===-- asan_preinit.cc ---------------------------------------------------===//
+//===-- asan_preinit.cpp --------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_premap_shadow.cc b/libsanitizer/asan/asan_premap_shadow.cpp
index 4273ae5..7835e99 100644
--- a/libsanitizer/asan/asan_premap_shadow.cc
+++ b/libsanitizer/asan/asan_premap_shadow.cpp
@@ -1,7 +1,8 @@
-//===-- asan_premap_shadow.cc ---------------------------------------------===//
+//===-- asan_premap_shadow.cpp --------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_premap_shadow.h b/libsanitizer/asan/asan_premap_shadow.h
index 345b56e..c9c886e 100644
--- a/libsanitizer/asan/asan_premap_shadow.h
+++ b/libsanitizer/asan/asan_premap_shadow.h
@@ -1,7 +1,8 @@
//===-- asan_mapping.h ------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_report.cc b/libsanitizer/asan/asan_report.cpp
index 787b689..d36b0b4 100644
--- a/libsanitizer/asan/asan_report.cc
+++ b/libsanitizer/asan/asan_report.cpp
@@ -1,7 +1,8 @@
-//===-- asan_report.cc ----------------------------------------------------===//
+//===-- asan_report.cpp ---------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -189,7 +190,7 @@ class ScopedInErrorReport {
void ReportError(const ErrorDescription &description) {
// Can only report one error per ScopedInErrorReport.
CHECK_EQ(current_error_.kind, kErrorKindInvalid);
- current_error_ = description;
+ internal_memcpy(&current_error_, &description, sizeof(current_error_));
}
static ErrorDescription &CurrentError() {
@@ -262,6 +263,13 @@ void ReportCallocOverflow(uptr count, uptr size, BufferedStackTrace *stack) {
in_report.ReportError(error);
}
+void ReportReallocArrayOverflow(uptr count, uptr size,
+ BufferedStackTrace *stack) {
+ ScopedInErrorReport in_report(/*fatal*/ true);
+ ErrorReallocArrayOverflow error(GetCurrentTidOrInvalid(), stack, count, size);
+ in_report.ReportError(error);
+}
+
void ReportPvallocOverflow(uptr size, BufferedStackTrace *stack) {
ScopedInErrorReport in_report(/*fatal*/ true);
ErrorPvallocOverflow error(GetCurrentTidOrInvalid(), stack, size);
diff --git a/libsanitizer/asan/asan_report.h b/libsanitizer/asan/asan_report.h
index b48605d..dcf6089 100644
--- a/libsanitizer/asan/asan_report.h
+++ b/libsanitizer/asan/asan_report.h
@@ -1,7 +1,8 @@
//===-- asan_report.h -------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -60,6 +61,8 @@ void ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack);
void ReportSanitizerGetAllocatedSizeNotOwned(uptr addr,
BufferedStackTrace *stack);
void ReportCallocOverflow(uptr count, uptr size, BufferedStackTrace *stack);
+void ReportReallocArrayOverflow(uptr count, uptr size,
+ BufferedStackTrace *stack);
void ReportPvallocOverflow(uptr size, BufferedStackTrace *stack);
void ReportInvalidAllocationAlignment(uptr alignment,
BufferedStackTrace *stack);
diff --git a/libsanitizer/asan/asan_rtems.cc b/libsanitizer/asan/asan_rtems.cpp
index fa68373..360d578 100644
--- a/libsanitizer/asan/asan_rtems.cc
+++ b/libsanitizer/asan/asan_rtems.cpp
@@ -1,7 +1,8 @@
-//===-- asan_rtems.cc -----------------------------------------------------===//
+//===-- asan_rtems.cpp ----------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -182,8 +183,8 @@ static void ThreadStartHook(void *hook, uptr os_id) {
// Determine whether we are starting or restarting the thread.
if (status == ThreadStatusCreated)
// In lieu of AsanThread::ThreadStart.
- asanThreadRegistry().StartThread(thread->tid(), os_id,
- /*workerthread*/ false, nullptr);
+ asanThreadRegistry().StartThread(thread->tid(), os_id, ThreadType::Regular,
+ nullptr);
else {
// In a thread restart, a thread may resume execution at an
// arbitrary function entry point, with its stack and TLS state
@@ -211,6 +212,12 @@ static void HandleExit() {
}
}
+bool HandleDlopenInit() {
+ // Not supported on this platform.
+ static_assert(!SANITIZER_SUPPORTS_INIT_FOR_DLOPEN,
+ "Expected SANITIZER_SUPPORTS_INIT_FOR_DLOPEN to be false");
+ return false;
+}
} // namespace __asan
// These are declared (in extern "C") by <some_path/sanitizer.h>.
diff --git a/libsanitizer/asan/asan_rtl.cc b/libsanitizer/asan/asan_rtl.cpp
index ba3acf2..b16ca95 100644
--- a/libsanitizer/asan/asan_rtl.cc
+++ b/libsanitizer/asan/asan_rtl.cpp
@@ -1,7 +1,8 @@
-//===-- asan_rtl.cc -------------------------------------------------------===//
+//===-- asan_rtl.cpp ------------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -381,6 +382,19 @@ void PrintAddressSpaceLayout() {
kHighShadowBeg > kMidMemEnd);
}
+#if defined(__thumb__) && defined(__linux__)
+#define START_BACKGROUND_THREAD_IN_ASAN_INTERNAL
+#endif
+
+#ifndef START_BACKGROUND_THREAD_IN_ASAN_INTERNAL
+static bool UNUSED __local_asan_dyninit = [] {
+ MaybeStartBackgroudThread();
+ SetSoftRssLimitExceededCallback(AsanSoftRssLimitExceededCallback);
+
+ return false;
+}();
+#endif
+
static void AsanInitInternal() {
if (LIKELY(asan_inited)) return;
SanitizerToolName = "AddressSanitizer";
@@ -394,6 +408,14 @@ static void AsanInitInternal() {
// initialization steps look at flags().
InitializeFlags();
+ // Stop performing init at this point if we are being loaded via
+ // dlopen() and the platform supports it.
+ if (SANITIZER_SUPPORTS_INIT_FOR_DLOPEN && UNLIKELY(HandleDlopenInit())) {
+ asan_init_is_running = false;
+ VReport(1, "AddressSanitizer init is being performed for dlopen().\n");
+ return;
+ }
+
AsanCheckIncompatibleRT();
AsanCheckDynamicRTPrereqs();
AvoidCVE_2016_2143();
@@ -418,6 +440,8 @@ static void AsanInitInternal() {
__asan_option_detect_stack_use_after_return =
flags()->detect_stack_use_after_return;
+ __sanitizer::InitializePlatformEarly();
+
// Re-exec ourselves if we need to set additional env or command line args.
MaybeReexec();
@@ -445,8 +469,10 @@ static void AsanInitInternal() {
allocator_options.SetFrom(flags(), common_flags());
InitializeAllocator(allocator_options);
+#ifdef START_BACKGROUND_THREAD_IN_ASAN_INTERNAL
MaybeStartBackgroudThread();
SetSoftRssLimitExceededCallback(AsanSoftRssLimitExceededCallback);
+#endif
// On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited
// should be set to 1 prior to initializing the threads.
@@ -571,6 +597,19 @@ void NOINLINE __asan_handle_no_return() {
curr_thread->fake_stack()->HandleNoReturn();
}
+extern "C" void *__asan_extra_spill_area() {
+ AsanThread *t = GetCurrentThread();
+ CHECK(t);
+ return t->extra_spill_area();
+}
+
+void __asan_handle_vfork(void *sp) {
+ AsanThread *t = GetCurrentThread();
+ CHECK(t);
+ uptr bottom = t->stack_bottom();
+ PoisonShadow(bottom, (uptr)sp - bottom, 0);
+}
+
void NOINLINE __asan_set_death_callback(void (*callback)(void)) {
SetUserDieCallback(callback);
}
diff --git a/libsanitizer/asan/asan_scariness_score.h b/libsanitizer/asan/asan_scariness_score.h
index aa947ed..9e7ba47 100644
--- a/libsanitizer/asan/asan_scariness_score.h
+++ b/libsanitizer/asan/asan_scariness_score.h
@@ -1,7 +1,8 @@
//===-- asan_scariness_score.h ----------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_shadow_setup.cc b/libsanitizer/asan/asan_shadow_setup.cpp
index 823187b..fc9bf51 100644
--- a/libsanitizer/asan/asan_shadow_setup.cc
+++ b/libsanitizer/asan/asan_shadow_setup.cpp
@@ -1,7 +1,8 @@
-//===-- asan_shadow_setup.cc ----------------------------------------------===//
+//===-- asan_shadow_setup.cpp ---------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -12,7 +13,7 @@
#include "sanitizer_common/sanitizer_platform.h"
-// asan_fuchsia.cc and asan_rtems.cc have their own
+// asan_fuchsia.cpp and asan_rtems.cpp have their own
// InitializeShadowMemory implementation.
#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
@@ -36,7 +37,7 @@ void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name) {
size);
Abort();
}
- if (common_flags()->no_huge_pages_for_shadow) NoHugePagesInRegion(beg, size);
+ SetShadowRegionHugePageMode(beg, size);
if (common_flags()->use_madv_dontdump) DontDumpShadowMemory(beg, size);
}
diff --git a/libsanitizer/asan/asan_stack.cc b/libsanitizer/asan/asan_stack.cc
deleted file mode 100644
index 973c5ce..0000000
--- a/libsanitizer/asan/asan_stack.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-//===-- asan_stack.cc -----------------------------------------------------===//
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-// Code for ASan stack trace.
-//===----------------------------------------------------------------------===//
-#include "asan_internal.h"
-#include "asan_stack.h"
-#include "sanitizer_common/sanitizer_atomic.h"
-
-namespace __asan {
-
-static atomic_uint32_t malloc_context_size;
-
-void SetMallocContextSize(u32 size) {
- atomic_store(&malloc_context_size, size, memory_order_release);
-}
-
-u32 GetMallocContextSize() {
- return atomic_load(&malloc_context_size, memory_order_acquire);
-}
-
-} // namespace __asan
-
-// ------------------ Interface -------------- {{{1
-
-extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_print_stack_trace() {
- using namespace __asan;
- PRINT_CURRENT_STACK();
-}
-} // extern "C"
diff --git a/libsanitizer/asan/asan_stack.cpp b/libsanitizer/asan/asan_stack.cpp
new file mode 100644
index 0000000..b7f4e6a
--- /dev/null
+++ b/libsanitizer/asan/asan_stack.cpp
@@ -0,0 +1,88 @@
+//===-- asan_stack.cpp ----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// Code for ASan stack trace.
+//===----------------------------------------------------------------------===//
+#include "asan_internal.h"
+#include "asan_stack.h"
+#include "sanitizer_common/sanitizer_atomic.h"
+
+namespace __asan {
+
+static atomic_uint32_t malloc_context_size;
+
+void SetMallocContextSize(u32 size) {
+ atomic_store(&malloc_context_size, size, memory_order_release);
+}
+
+u32 GetMallocContextSize() {
+ return atomic_load(&malloc_context_size, memory_order_acquire);
+}
+
+namespace {
+
+// ScopedUnwinding is a scope for stacktracing member of a context
+class ScopedUnwinding {
+ public:
+ explicit ScopedUnwinding(AsanThread *t) : thread(t) {
+ if (thread) {
+ can_unwind = !thread->isUnwinding();
+ thread->setUnwinding(true);
+ }
+ }
+ ~ScopedUnwinding() {
+ if (thread)
+ thread->setUnwinding(false);
+ }
+
+ bool CanUnwind() const { return can_unwind; }
+
+ private:
+ AsanThread *thread = nullptr;
+ bool can_unwind = true;
+};
+
+} // namespace
+
+} // namespace __asan
+
+void __sanitizer::BufferedStackTrace::UnwindImpl(
+ uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
+ using namespace __asan;
+ size = 0;
+ if (UNLIKELY(!asan_inited))
+ return;
+ request_fast = StackTrace::WillUseFastUnwind(request_fast);
+ AsanThread *t = GetCurrentThread();
+ ScopedUnwinding unwind_scope(t);
+ if (!unwind_scope.CanUnwind())
+ return;
+ if (request_fast) {
+ if (t) {
+ Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(),
+ true);
+ }
+ return;
+ }
+ if (SANITIZER_MIPS && t &&
+ !IsValidFrame(bp, t->stack_top(), t->stack_bottom()))
+ return;
+ Unwind(max_depth, pc, bp, context, 0, 0, false);
+}
+
+// ------------------ Interface -------------- {{{1
+
+extern "C" {
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_print_stack_trace() {
+ using namespace __asan;
+ PRINT_CURRENT_STACK();
+}
+} // extern "C"
diff --git a/libsanitizer/asan/asan_stack.h b/libsanitizer/asan/asan_stack.h
index 5775e9d..4089d3d 100644
--- a/libsanitizer/asan/asan_stack.h
+++ b/libsanitizer/asan/asan_stack.h
@@ -1,13 +1,14 @@
//===-- asan_stack.h --------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
-// ASan-private header for asan_stack.cc.
+// ASan-private header for asan_stack.cpp.
//===----------------------------------------------------------------------===//
#ifndef ASAN_STACK_H
@@ -25,34 +26,6 @@ static const u32 kDefaultMallocContextSize = 30;
void SetMallocContextSize(u32 size);
u32 GetMallocContextSize();
-// Get the stack trace with the given pc and bp.
-// The pc will be in the position 0 of the resulting stack trace.
-// The bp may refer to the current frame or to the caller's frame.
-ALWAYS_INLINE
-void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp,
- void *context, bool fast) {
-#if SANITIZER_WINDOWS
- stack->Unwind(max_depth, pc, bp, context, 0, 0, fast);
-#else
- AsanThread *t;
- stack->size = 0;
- if (LIKELY(asan_inited)) {
- if ((t = GetCurrentThread()) && !t->isUnwinding()) {
- uptr stack_top = t->stack_top();
- uptr stack_bottom = t->stack_bottom();
- ScopedUnwinding unwind_scope(t);
- if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
- stack->Unwind(max_depth, pc, bp, context, stack_top, stack_bottom,
- fast);
- }
- } else if (!t && !fast) {
- /* If GetCurrentThread() has failed, try to do slow unwind anyways. */
- stack->Unwind(max_depth, pc, bp, context, 0, 0, false);
- }
- }
-#endif // SANITIZER_WINDOWS
-}
-
} // namespace __asan
// NOTE: A Rule of thumb is to retrieve stack trace in the interceptors
@@ -69,19 +42,19 @@ void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp,
if (max_size > 1) stack.trace_buffer[1] = GET_CALLER_PC(); \
} \
} else { \
- GetStackTrace(&stack, max_size, StackTrace::GetCurrentPc(), \
- GET_CURRENT_FRAME(), 0, fast); \
+ stack.Unwind(StackTrace::GetCurrentPc(), \
+ GET_CURRENT_FRAME(), nullptr, fast, max_size); \
}
#define GET_STACK_TRACE_FATAL(pc, bp) \
BufferedStackTrace stack; \
- GetStackTrace(&stack, kStackTraceMax, pc, bp, 0, \
- common_flags()->fast_unwind_on_fatal)
+ stack.Unwind(pc, bp, nullptr, \
+ common_flags()->fast_unwind_on_fatal)
#define GET_STACK_TRACE_SIGNAL(sig) \
BufferedStackTrace stack; \
- GetStackTrace(&stack, kStackTraceMax, (sig).pc, (sig).bp, (sig).context, \
- common_flags()->fast_unwind_on_fatal)
+ stack.Unwind((sig).pc, (sig).bp, (sig).context, \
+ common_flags()->fast_unwind_on_fatal)
#define GET_STACK_TRACE_FATAL_HERE \
GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_fatal)
diff --git a/libsanitizer/asan/asan_stats.cc b/libsanitizer/asan/asan_stats.cpp
index 64a788a..bc4e8c1 100644
--- a/libsanitizer/asan/asan_stats.cc
+++ b/libsanitizer/asan/asan_stats.cpp
@@ -1,7 +1,8 @@
-//===-- asan_stats.cc -----------------------------------------------------===//
+//===-- asan_stats.cpp ----------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_stats.h b/libsanitizer/asan/asan_stats.h
index a48e3f9..d6da653 100644
--- a/libsanitizer/asan/asan_stats.h
+++ b/libsanitizer/asan/asan_stats.h
@@ -1,7 +1,8 @@
//===-- asan_stats.h --------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_suppressions.cc b/libsanitizer/asan/asan_suppressions.cpp
index 0040602..a9c0d10 100644
--- a/libsanitizer/asan/asan_suppressions.cc
+++ b/libsanitizer/asan/asan_suppressions.cpp
@@ -1,7 +1,8 @@
-//===-- asan_suppressions.cc ----------------------------------------------===//
+//===-- asan_suppressions.cpp ---------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/asan/asan_suppressions.h b/libsanitizer/asan/asan_suppressions.h
index 331d722..121d4dd 100644
--- a/libsanitizer/asan/asan_suppressions.h
+++ b/libsanitizer/asan/asan_suppressions.h
@@ -1,13 +1,14 @@
//===-- asan_suppressions.h -------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
-// ASan-private header for asan_suppressions.cc.
+// ASan-private header for asan_suppressions.cpp.
//===----------------------------------------------------------------------===//
#ifndef ASAN_SUPPRESSIONS_H
#define ASAN_SUPPRESSIONS_H
diff --git a/libsanitizer/asan/asan_thread.cc b/libsanitizer/asan/asan_thread.cpp
index 82da9a2..d48b341 100644
--- a/libsanitizer/asan/asan_thread.cc
+++ b/libsanitizer/asan/asan_thread.cpp
@@ -1,7 +1,8 @@
-//===-- asan_thread.cc ----------------------------------------------------===//
+//===-- asan_thread.cpp ---------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -221,9 +222,11 @@ void AsanThread::Init(const InitOptions *options) {
atomic_store(&stack_switching_, false, memory_order_release);
CHECK_EQ(this->stack_size(), 0U);
SetThreadStackAndTls(options);
- CHECK_GT(this->stack_size(), 0U);
- CHECK(AddrIsInMem(stack_bottom_));
- CHECK(AddrIsInMem(stack_top_ - 1));
+ if (stack_top_ != stack_bottom_) {
+ CHECK_GT(this->stack_size(), 0U);
+ CHECK(AddrIsInMem(stack_bottom_));
+ CHECK(AddrIsInMem(stack_top_ - 1));
+ }
ClearShadowForThreadStackAndTLS();
fake_stack_ = nullptr;
if (__asan_option_detect_stack_use_after_return)
@@ -242,8 +245,7 @@ void AsanThread::Init(const InitOptions *options) {
thread_return_t AsanThread::ThreadStart(
tid_t os_id, atomic_uintptr_t *signal_thread_is_registered) {
Init();
- asanThreadRegistry().StartThread(tid(), os_id, /*workerthread*/ false,
- nullptr);
+ asanThreadRegistry().StartThread(tid(), os_id, ThreadType::Regular, nullptr);
if (signal_thread_is_registered)
atomic_store(signal_thread_is_registered, 1, memory_order_release);
@@ -287,20 +289,23 @@ void AsanThread::SetThreadStackAndTls(const InitOptions *options) {
DCHECK_EQ(options, nullptr);
uptr tls_size = 0;
uptr stack_size = 0;
- GetThreadStackAndTls(tid() == 0, const_cast<uptr *>(&stack_bottom_),
- const_cast<uptr *>(&stack_size), &tls_begin_, &tls_size);
+ GetThreadStackAndTls(tid() == 0, &stack_bottom_, &stack_size, &tls_begin_,
+ &tls_size);
stack_top_ = stack_bottom_ + stack_size;
tls_end_ = tls_begin_ + tls_size;
dtls_ = DTLS_Get();
- int local;
- CHECK(AddrIsInStack((uptr)&local));
+ if (stack_top_ != stack_bottom_) {
+ int local;
+ CHECK(AddrIsInStack((uptr)&local));
+ }
}
#endif // !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
void AsanThread::ClearShadowForThreadStackAndTLS() {
- PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0);
+ if (stack_top_ != stack_bottom_)
+ PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0);
if (tls_begin_ != tls_end_) {
uptr tls_begin_aligned = RoundDownTo(tls_begin_, SHADOW_GRANULARITY);
uptr tls_end_aligned = RoundUpTo(tls_end_, SHADOW_GRANULARITY);
@@ -312,6 +317,9 @@ void AsanThread::ClearShadowForThreadStackAndTLS() {
bool AsanThread::GetStackFrameAccessByAddr(uptr addr,
StackFrameAccess *access) {
+ if (stack_top_ == stack_bottom_)
+ return false;
+
uptr bottom = 0;
if (AddrIsInStack(addr)) {
bottom = stack_bottom();
diff --git a/libsanitizer/asan/asan_thread.h b/libsanitizer/asan/asan_thread.h
index 187cb13..c503f50 100644
--- a/libsanitizer/asan/asan_thread.h
+++ b/libsanitizer/asan/asan_thread.h
@@ -1,13 +1,14 @@
//===-- asan_thread.h -------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
-// ASan-private header for asan_thread.cc.
+// ASan-private header for asan_thread.cpp.
//===----------------------------------------------------------------------===//
#ifndef ASAN_THREAD_H
@@ -129,6 +130,8 @@ class AsanThread {
AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
AsanStats &stats() { return stats_; }
+ void *extra_spill_area() { return &extra_spill_area_; }
+
private:
// NOTE: There is no AsanThread constructor. It is allocated
// via mmap() and *must* be valid in zero-initialized state.
@@ -164,18 +167,7 @@ class AsanThread {
AsanThreadLocalMallocStorage malloc_storage_;
AsanStats stats_;
bool unwinding_;
-};
-
-// ScopedUnwinding is a scope for stacktracing member of a context
-class ScopedUnwinding {
- public:
- explicit ScopedUnwinding(AsanThread *t) : thread(t) {
- t->setUnwinding(true);
- }
- ~ScopedUnwinding() { thread->setUnwinding(false); }
-
- private:
- AsanThread *thread;
+ uptr extra_spill_area_;
};
// Returns a single instance of registry.
diff --git a/libsanitizer/asan/asan_win.cc b/libsanitizer/asan/asan_win.cpp
index 8473f59..f8b98ca 100644
--- a/libsanitizer/asan/asan_win.cc
+++ b/libsanitizer/asan/asan_win.cpp
@@ -1,7 +1,8 @@
-//===-- asan_win.cc -------------------------------------------------------===//
+//===-- asan_win.cpp ------------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -19,10 +20,10 @@
#include "asan_interceptors.h"
#include "asan_internal.h"
+#include "asan_mapping.h"
#include "asan_report.h"
#include "asan_stack.h"
#include "asan_thread.h"
-#include "asan_mapping.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_mutex.h"
#include "sanitizer_common/sanitizer_win.h"
@@ -76,7 +77,7 @@ static long WINAPI SEHHandler(EXCEPTION_POINTERS *info) {
}
INTERCEPTOR_WINAPI(LPTOP_LEVEL_EXCEPTION_FILTER, SetUnhandledExceptionFilter,
- LPTOP_LEVEL_EXCEPTION_FILTER ExceptionFilter) {
+ LPTOP_LEVEL_EXCEPTION_FILTER ExceptionFilter) {
CHECK(REAL(SetUnhandledExceptionFilter));
if (ExceptionFilter == &SEHHandler)
return REAL(SetUnhandledExceptionFilter)(ExceptionFilter);
@@ -103,7 +104,9 @@ INTERCEPTOR_WINAPI(void, RaiseException, void *a, void *b, void *c, void *d) {
#ifdef _WIN64
-INTERCEPTOR_WINAPI(int, __C_specific_handler, void *a, void *b, void *c, void *d) { // NOLINT
+INTERCEPTOR_WINAPI(EXCEPTION_DISPOSITION, __C_specific_handler,
+ _EXCEPTION_RECORD *a, void *b, _CONTEXT *c,
+ _DISPATCHER_CONTEXT *d) { // NOLINT
CHECK(REAL(__C_specific_handler));
__asan_handle_no_return();
return REAL(__C_specific_handler)(a, b, c, d);
@@ -129,15 +132,14 @@ INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {
#endif
static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
- AsanThread *t = (AsanThread*)arg;
+ AsanThread *t = (AsanThread *)arg;
SetCurrentThread(t);
return t->ThreadStart(GetTid(), /* signal_thread_is_registered */ nullptr);
}
-INTERCEPTOR_WINAPI(DWORD, CreateThread,
- void* security, uptr stack_size,
- DWORD (__stdcall *start_routine)(void*), void* arg,
- DWORD thr_flags, void* tid) {
+INTERCEPTOR_WINAPI(HANDLE, CreateThread, LPSECURITY_ATTRIBUTES security,
+ SIZE_T stack_size, LPTHREAD_START_ROUTINE start_routine,
+ void *arg, DWORD thr_flags, DWORD *tid) {
// Strict init-order checking is thread-hostile.
if (flags()->strict_init_order)
StopInitOrderChecking();
@@ -147,9 +149,9 @@ INTERCEPTOR_WINAPI(DWORD, CreateThread,
bool detached = false; // FIXME: how can we determine it on Windows?
u32 current_tid = GetCurrentTidOrInvalid();
AsanThread *t =
- AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
- return REAL(CreateThread)(security, stack_size,
- asan_thread_start, t, thr_flags, tid);
+ AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
+ return REAL(CreateThread)(security, stack_size, asan_thread_start, t,
+ thr_flags, tid);
}
// }}}
@@ -160,10 +162,9 @@ void InitializePlatformInterceptors() {
// The interceptors were not designed to be removable, so we have to keep this
// module alive for the life of the process.
HMODULE pinned;
- CHECK(GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
- GET_MODULE_HANDLE_EX_FLAG_PIN,
- (LPCWSTR)&InitializePlatformInterceptors,
- &pinned));
+ CHECK(GetModuleHandleExW(
+ GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN,
+ (LPCWSTR)&InitializePlatformInterceptors, &pinned));
ASAN_INTERCEPT_FUNC(CreateThread);
ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter);
@@ -195,6 +196,30 @@ static bool tsd_key_inited = false;
static __declspec(thread) void *fake_tsd = 0;
+// https://docs.microsoft.com/en-us/windows/desktop/api/winternl/ns-winternl-_teb
+// "[This structure may be altered in future versions of Windows. Applications
+// should use the alternate functions listed in this topic.]"
+typedef struct _TEB {
+ PVOID Reserved1[12];
+ // PVOID ThreadLocalStoragePointer; is here, at the last field in Reserved1.
+ PVOID ProcessEnvironmentBlock;
+ PVOID Reserved2[399];
+ BYTE Reserved3[1952];
+ PVOID TlsSlots[64];
+ BYTE Reserved4[8];
+ PVOID Reserved5[26];
+ PVOID ReservedForOle;
+ PVOID Reserved6[4];
+ PVOID TlsExpansionSlots;
+} TEB, *PTEB;
+
+constexpr size_t TEB_RESERVED_FIELDS_THREAD_LOCAL_STORAGE_OFFSET = 11;
+BOOL IsTlsInitialized() {
+ PTEB teb = (PTEB)NtCurrentTeb();
+ return teb->Reserved1[TEB_RESERVED_FIELDS_THREAD_LOCAL_STORAGE_OFFSET] !=
+ nullptr;
+}
+
void AsanTSDInit(void (*destructor)(void *tsd)) {
// FIXME: we're ignoring the destructor for now.
tsd_key_inited = true;
@@ -202,7 +227,7 @@ void AsanTSDInit(void (*destructor)(void *tsd)) {
void *AsanTSDGet() {
CHECK(tsd_key_inited);
- return fake_tsd;
+ return IsTlsInitialized() ? fake_tsd : nullptr;
}
void AsanTSDSet(void *tsd) {
@@ -210,9 +235,7 @@ void AsanTSDSet(void *tsd) {
fake_tsd = tsd;
}
-void PlatformTSDDtor(void *tsd) {
- AsanThread::TSDDtor(tsd);
-}
+void PlatformTSDDtor(void *tsd) { AsanThread::TSDDtor(tsd); }
// }}}
// ---------------------- Various stuff ---------------- {{{
@@ -243,9 +266,7 @@ void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
UNIMPLEMENTED();
}
-void AsanOnDeadlySignal(int, void *siginfo, void *context) {
- UNIMPLEMENTED();
-}
+void AsanOnDeadlySignal(int, void *siginfo, void *context) { UNIMPLEMENTED(); }
#if SANITIZER_WINDOWS64
// Exception handler for dealing with shadow memory.
@@ -254,7 +275,9 @@ ShadowExceptionHandler(PEXCEPTION_POINTERS exception_pointers) {
uptr page_size = GetPageSizeCached();
// Only handle access violations.
if (exception_pointers->ExceptionRecord->ExceptionCode !=
- EXCEPTION_ACCESS_VIOLATION) {
+ EXCEPTION_ACCESS_VIOLATION ||
+ exception_pointers->ExceptionRecord->NumberParameters < 2) {
+ __asan_handle_no_return();
return EXCEPTION_CONTINUE_SEARCH;
}
@@ -263,7 +286,10 @@ ShadowExceptionHandler(PEXCEPTION_POINTERS exception_pointers) {
(uptr)(exception_pointers->ExceptionRecord->ExceptionInformation[1]);
// Check valid shadow range.
- if (!AddrIsInShadow(addr)) return EXCEPTION_CONTINUE_SEARCH;
+ if (!AddrIsInShadow(addr)) {
+ __asan_handle_no_return();
+ return EXCEPTION_CONTINUE_SEARCH;
+ }
// This is an access violation while trying to read from the shadow. Commit
// the relevant page and let execution continue.
@@ -274,7 +300,8 @@ ShadowExceptionHandler(PEXCEPTION_POINTERS exception_pointers) {
// Commit the page.
uptr result =
(uptr)::VirtualAlloc((LPVOID)page, page_size, MEM_COMMIT, PAGE_READWRITE);
- if (result != page) return EXCEPTION_CONTINUE_SEARCH;
+ if (result != page)
+ return EXCEPTION_CONTINUE_SEARCH;
// The page mapping succeeded, so continue execution as usual.
return EXCEPTION_CONTINUE_EXECUTION;
@@ -291,7 +318,7 @@ void InitializePlatformExceptionHandlers() {
}
bool IsSystemHeapAddress(uptr addr) {
- return ::HeapValidate(GetProcessHeap(), 0, (void*)addr) != FALSE;
+ return ::HeapValidate(GetProcessHeap(), 0, (void *)addr) != FALSE;
}
// We want to install our own exception handler (EH) to print helpful reports
@@ -310,8 +337,7 @@ bool IsSystemHeapAddress(uptr addr) {
// asan_dynamic_runtime_thunk.lib to all the modules, thus __asan_set_seh_filter
// will be called for each instrumented module. This ensures that at least one
// __asan_set_seh_filter call happens after the .exe module CRT is initialized.
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-int __asan_set_seh_filter() {
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE int __asan_set_seh_filter() {
// We should only store the previous handler if it's not our own handler in
// order to avoid loops in the EH chain.
auto prev_seh_handler = SetUnhandledExceptionFilter(SEHHandler);
@@ -320,6 +346,13 @@ int __asan_set_seh_filter() {
return 0;
}
+bool HandleDlopenInit() {
+ // Not supported on this platform.
+ static_assert(!SANITIZER_SUPPORTS_INIT_FOR_DLOPEN,
+ "Expected SANITIZER_SUPPORTS_INIT_FOR_DLOPEN to be false");
+ return false;
+}
+
#if !ASAN_DYNAMIC
// The CRT runs initializers in this order:
// - C initializers, from XIA to XIZ
@@ -338,14 +371,28 @@ __declspec(allocate(".CRT$XCAB")) int (*__intercept_seh)() =
// which run before the CRT. Users also add code to .CRT$XLC, so it's important
// to run our initializers first.
static void NTAPI asan_thread_init(void *module, DWORD reason, void *reserved) {
- if (reason == DLL_PROCESS_ATTACH) __asan_init();
+ if (reason == DLL_PROCESS_ATTACH)
+ __asan_init();
}
#pragma section(".CRT$XLAB", long, read) // NOLINT
-__declspec(allocate(".CRT$XLAB")) void (NTAPI *__asan_tls_init)(void *,
- unsigned long, void *) = asan_thread_init;
+__declspec(allocate(".CRT$XLAB")) void(NTAPI *__asan_tls_init)(
+ void *, unsigned long, void *) = asan_thread_init;
#endif
+static void NTAPI asan_thread_exit(void *module, DWORD reason, void *reserved) {
+ if (reason == DLL_THREAD_DETACH) {
+ // Unpoison the thread's stack because the memory may be re-used.
+ NT_TIB *tib = (NT_TIB *)NtCurrentTeb();
+ uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit;
+ __asan_unpoison_memory_region(tib->StackLimit, stackSize);
+ }
+}
+
+#pragma section(".CRT$XLY", long, read) // NOLINT
+__declspec(allocate(".CRT$XLY")) void(NTAPI *__asan_tls_exit)(
+ void *, unsigned long, void *) = asan_thread_exit;
+
WIN_FORCE_LINK(__asan_dso_reg_hook)
// }}}
diff --git a/libsanitizer/asan/asan_win_dll_thunk.cc b/libsanitizer/asan/asan_win_dll_thunk.cpp
index 8df7ab2..95eee5e 100644
--- a/libsanitizer/asan/asan_win_dll_thunk.cc
+++ b/libsanitizer/asan/asan_win_dll_thunk.cpp
@@ -1,7 +1,8 @@
-//===-- asan_win_dll_thunk.cc ---------------------------------------------===//
+//===-- asan_win_dll_thunk.cpp --------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -46,13 +47,14 @@ INTERCEPT_WRAP_W_WWW(_recalloc)
INTERCEPT_WRAP_W_WWW(_recalloc_base)
INTERCEPT_WRAP_W_W(_msize)
+INTERCEPT_WRAP_W_W(_msize_base)
INTERCEPT_WRAP_W_W(_expand)
INTERCEPT_WRAP_W_W(_expand_dbg)
// TODO(timurrrr): Might want to add support for _aligned_* allocation
// functions to detect a bit more bugs. Those functions seem to wrap malloc().
-// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cc).
+// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cpp)
INTERCEPT_LIBRARY_FUNCTION(atoi);
INTERCEPT_LIBRARY_FUNCTION(atol);
diff --git a/libsanitizer/asan/asan_win_dynamic_runtime_thunk.cc b/libsanitizer/asan/asan_win_dynamic_runtime_thunk.cpp
index d431b78..5bd457a 100644
--- a/libsanitizer/asan/asan_win_dynamic_runtime_thunk.cc
+++ b/libsanitizer/asan/asan_win_dynamic_runtime_thunk.cpp
@@ -1,7 +1,8 @@
-//===-- asan_win_dynamic_runtime_thunk.cc ---------------------------------===//
+//===-- asan_win_dynamic_runtime_thunk.cpp --------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -113,7 +114,7 @@ int (*__asan_schedule_unregister_globals)() = ScheduleUnregisterGlobals;
////////////////////////////////////////////////////////////////////////////////
// ASan SEH handling.
// We need to set the ASan-specific SEH handler at the end of CRT initialization
-// of each module (see also asan_win.cc).
+// of each module (see also asan_win.cpp).
extern "C" {
__declspec(dllimport) int __asan_set_seh_filter();
static int SetSEHFilter() { return __asan_set_seh_filter(); }
diff --git a/libsanitizer/asan/asan_win_weak_interception.cc b/libsanitizer/asan/asan_win_weak_interception.cpp
index 74c1dcd..62534e1 100644
--- a/libsanitizer/asan/asan_win_weak_interception.cc
+++ b/libsanitizer/asan/asan_win_weak_interception.cpp
@@ -1,7 +1,8 @@
-//===-- asan_win_weak_interception.cc -------------------------------------===//
+//===-- asan_win_weak_interception.cpp ------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// This module should be included in Address Sanitizer when it is implemented as
diff --git a/libsanitizer/builtins/assembly.h b/libsanitizer/builtins/assembly.h
index 3f5e59b..f437cb8 100644
--- a/libsanitizer/builtins/assembly.h
+++ b/libsanitizer/builtins/assembly.h
@@ -1,17 +1,15 @@
-/* ===-- assembly.h - compiler-rt assembler support macros -----------------===
- *
- * The LLVM Compiler Infrastructure
- *
- * This file is dual licensed under the MIT and the University of Illinois Open
- * Source Licenses. See LICENSE.TXT for details.
- *
- * ===----------------------------------------------------------------------===
- *
- * This file defines macros for use in compiler-rt assembler source.
- * This file is not part of the interface of this library.
- *
- * ===----------------------------------------------------------------------===
- */
+//===-- assembly.h - compiler-rt assembler support macros -----------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines macros for use in compiler-rt assembler source.
+// This file is not part of the interface of this library.
+//
+//===----------------------------------------------------------------------===//
#ifndef COMPILERRT_ASSEMBLY_H
#define COMPILERRT_ASSEMBLY_H
@@ -69,11 +67,9 @@
#if defined(__arm__)
-/*
- * Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros:
- * - for '-mthumb -march=armv6' compiler defines '__thumb__'
- * - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__'
- */
+// Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros:
+// - for '-mthumb -march=armv6' compiler defines '__thumb__'
+// - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__'
#if defined(__thumb2__) || defined(__thumb__)
#define DEFINE_CODE_STATE .thumb SEPARATOR
#define DECLARE_FUNC_ENCODING .thumb_func SEPARATOR
@@ -201,4 +197,4 @@
#define END_COMPILERRT_FUNCTION(name)
#endif
-#endif /* COMPILERRT_ASSEMBLY_H */
+#endif // COMPILERRT_ASSEMBLY_H
diff --git a/libsanitizer/configure.tgt b/libsanitizer/configure.tgt
index b241ddb..3fb90ea 100644
--- a/libsanitizer/configure.tgt
+++ b/libsanitizer/configure.tgt
@@ -28,9 +28,6 @@ case "${target}" in
LSAN_SUPPORTED=yes
TSAN_TARGET_DEPENDENT_OBJECTS=tsan_rtl_amd64.lo
fi
- if echo "int x = __x86_64__;" | $CC -c -x c -o /dev/null - > /dev/null 2>&1; then
- SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS=sanitizer_linux_x86_64.lo
- fi
;;
powerpc*-*-linux*)
if test x$ac_cv_sizeof_void_p = x8; then
diff --git a/libsanitizer/include/sanitizer/allocator_interface.h b/libsanitizer/include/sanitizer/allocator_interface.h
index e125ad2..6226135 100644
--- a/libsanitizer/include/sanitizer/allocator_interface.h
+++ b/libsanitizer/include/sanitizer/allocator_interface.h
@@ -1,7 +1,8 @@
//===-- allocator_interface.h ---------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/include/sanitizer/asan_interface.h b/libsanitizer/include/sanitizer/asan_interface.h
index 6e8fe25..ab2dc97 100644
--- a/libsanitizer/include/sanitizer/asan_interface.h
+++ b/libsanitizer/include/sanitizer/asan_interface.h
@@ -1,11 +1,12 @@
//===-- sanitizer/asan_interface.h ------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
-// This file is a part of AddressSanitizer.
+// This file is a part of AddressSanitizer (ASan).
//
// Public interface header.
//===----------------------------------------------------------------------===//
@@ -17,28 +18,54 @@
#ifdef __cplusplus
extern "C" {
#endif
- // Marks memory region [addr, addr+size) as unaddressable.
- // This memory must be previously allocated by the user program. Accessing
- // addresses in this region from instrumented code is forbidden until
- // this region is unpoisoned. This function is not guaranteed to poison
- // the whole region - it may poison only subregion of [addr, addr+size) due
- // to ASan alignment restrictions.
- // Method is NOT thread-safe in the sense that no two threads can
- // (un)poison memory in the same memory region simultaneously.
- void __asan_poison_memory_region(void const volatile *addr, size_t size);
- // Marks memory region [addr, addr+size) as addressable.
- // This memory must be previously allocated by the user program. Accessing
- // addresses in this region is allowed until this region is poisoned again.
- // This function may unpoison a superregion of [addr, addr+size) due to
- // ASan alignment restrictions.
- // Method is NOT thread-safe in the sense that no two threads can
- // (un)poison memory in the same memory region simultaneously.
- void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
-
-// User code should use macros instead of functions.
+/// Marks a memory region (<c>[addr, addr+size)</c>) as unaddressable.
+///
+/// This memory must be previously allocated by your program. Instrumented
+/// code is forbidden from accessing addresses in this region until it is
+/// unpoisoned. This function is not guaranteed to poison the entire region -
+/// it could poison only a subregion of <c>[addr, addr+size)</c> due to ASan
+/// alignment restrictions.
+///
+/// \note This function is not thread-safe because no two threads can poison or
+/// unpoison memory in the same memory region simultaneously.
+///
+/// \param addr Start of memory region.
+/// \param size Size of memory region.
+void __asan_poison_memory_region(void const volatile *addr, size_t size);
+
+/// Marks a memory region (<c>[addr, addr+size)</c>) as addressable.
+///
+/// This memory must be previously allocated by your program. Accessing
+/// addresses in this region is allowed until this region is poisoned again.
+/// This function could unpoison a super-region of <c>[addr, addr+size)</c> due
+/// to ASan alignment restrictions.
+///
+/// \note This function is not thread-safe because no two threads can
+/// poison or unpoison memory in the same memory region simultaneously.
+///
+/// \param addr Start of memory region.
+/// \param size Size of memory region.
+void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
+
+// Macros provided for convenience.
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+/// Marks a memory region as unaddressable.
+///
+/// \note Macro provided for convenience; defined as a no-op if ASan is not
+/// enabled.
+///
+/// \param addr Start of memory region.
+/// \param size Size of memory region.
#define ASAN_POISON_MEMORY_REGION(addr, size) \
__asan_poison_memory_region((addr), (size))
+
+/// Marks a memory region as addressable.
+///
+/// \note Macro provided for convenience; defined as a no-op if ASan is not
+/// enabled.
+///
+/// \param addr Start of memory region.
+/// \param size Size of memory region.
#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \
__asan_unpoison_memory_region((addr), (size))
#else
@@ -48,103 +75,245 @@ extern "C" {
((void)(addr), (void)(size))
#endif
- // Returns 1 if addr is poisoned (i.e. 1-byte read/write access to this
- // address will result in error report from AddressSanitizer).
- // Otherwise returns 0.
- int __asan_address_is_poisoned(void const volatile *addr);
-
- // If at least one byte in [beg, beg+size) is poisoned, return the address
- // of the first such byte. Otherwise return 0.
- void *__asan_region_is_poisoned(void *beg, size_t size);
-
- // Print the description of addr (useful when debugging in gdb).
- void __asan_describe_address(void *addr);
-
- // Useful for calling from a debugger to get information about an ASan error.
- // Returns 1 if an error has been (or is being) reported, otherwise returns 0.
- int __asan_report_present(void);
-
- // Useful for calling from a debugger to get information about an ASan error.
- // If an error has been (or is being) reported, the following functions return
- // the pc, bp, sp, address, access type (0 = read, 1 = write), access size and
- // bug description (e.g. "heap-use-after-free"). Otherwise they return 0.
- void *__asan_get_report_pc(void);
- void *__asan_get_report_bp(void);
- void *__asan_get_report_sp(void);
- void *__asan_get_report_address(void);
- int __asan_get_report_access_type(void);
- size_t __asan_get_report_access_size(void);
- const char *__asan_get_report_description(void);
-
- // Useful for calling from the debugger to get information about a pointer.
- // Returns the category of the given pointer as a constant string.
- // Possible return values are "global", "stack", "stack-fake", "heap",
- // "heap-invalid", "shadow-low", "shadow-gap", "shadow-high", "unknown".
- // If global or stack, tries to also return the variable name, address and
- // size. If heap, tries to return the chunk address and size. 'name' should
- // point to an allocated buffer of size 'name_size'.
- const char *__asan_locate_address(void *addr, char *name, size_t name_size,
- void **region_address, size_t *region_size);
-
- // Useful for calling from the debugger to get the allocation stack trace
- // and thread ID for a heap address. Stores up to 'size' frames into 'trace',
- // returns the number of stored frames or 0 on error.
- size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size,
- int *thread_id);
-
- // Useful for calling from the debugger to get the free stack trace
- // and thread ID for a heap address. Stores up to 'size' frames into 'trace',
- // returns the number of stored frames or 0 on error.
- size_t __asan_get_free_stack(void *addr, void **trace, size_t size,
- int *thread_id);
-
- // Useful for calling from the debugger to get the current shadow memory
- // mapping.
- void __asan_get_shadow_mapping(size_t *shadow_scale, size_t *shadow_offset);
-
- // This is an internal function that is called to report an error.
- // However it is still a part of the interface because users may want to
- // set a breakpoint on this function in a debugger.
- void __asan_report_error(void *pc, void *bp, void *sp,
- void *addr, int is_write, size_t access_size);
-
- // Deprecated. Call __sanitizer_set_death_callback instead.
- void __asan_set_death_callback(void (*callback)(void));
-
- void __asan_set_error_report_callback(void (*callback)(const char*));
-
- // User may provide function that would be called right when ASan detects
- // an error. This can be used to notice cases when ASan detects an error, but
- // the program crashes before ASan report is printed.
- void __asan_on_error(void);
-
- // Prints accumulated stats to stderr. Used for debugging.
- void __asan_print_accumulated_stats(void);
-
- // This function may be optionally provided by user and should return
- // a string containing ASan runtime options. See asan_flags.h for details.
- const char* __asan_default_options(void);
-
- // The following 2 functions facilitate garbage collection in presence of
- // asan's fake stack.
-
- // Returns an opaque handler to be used later in __asan_addr_is_in_fake_stack.
- // Returns NULL if the current thread does not have a fake stack.
- void *__asan_get_current_fake_stack(void);
-
- // If fake_stack is non-NULL and addr belongs to a fake frame in
- // fake_stack, returns the address on real stack that corresponds to
- // the fake frame and sets beg/end to the boundaries of this fake frame.
- // Otherwise returns NULL and does not touch beg/end.
- // If beg/end are NULL, they are not touched.
- // This function may be called from a thread other than the owner of
- // fake_stack, but the owner thread need to be alive.
- void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
- void **end);
-
- // Performs cleanup before a [[noreturn]] function. Must be called
- // before things like _exit and execl to avoid false positives on stack.
- void __asan_handle_no_return(void);
+/// Checks if an address is poisoned.
+///
+/// Returns 1 if <c><i>addr</i></c> is poisoned (that is, 1-byte read/write
+/// access to this address would result in an error report from ASan).
+/// Otherwise returns 0.
+///
+/// \param addr Address to check.
+///
+/// \retval 1 Address is poisoned.
+/// \retval 0 Address is not poisoned.
+int __asan_address_is_poisoned(void const volatile *addr);
+
+/// Checks if a region is poisoned.
+///
+/// If at least one byte in <c>[beg, beg+size)</c> is poisoned, returns the
+/// address of the first such byte. Otherwise returns 0.
+///
+/// \param beg Start of memory region.
+/// \param size Start of memory region.
+/// \returns Address of first poisoned byte.
+void *__asan_region_is_poisoned(void *beg, size_t size);
+
+/// Describes an address (useful for calling from the debugger).
+///
+/// Prints the description of <c><i>addr</i></c>.
+///
+/// \param addr Address to describe.
+void __asan_describe_address(void *addr);
+
+/// Checks if an error has been or is being reported (useful for calling from
+/// the debugger to get information about an ASan error).
+///
+/// Returns 1 if an error has been (or is being) reported. Otherwise returns 0.
+///
+/// \returns 1 if an error has been (or is being) reported. Otherwise returns
+/// 0.
+int __asan_report_present(void);
+
+/// Gets the PC (program counter) register value of an ASan error (useful for
+/// calling from the debugger).
+///
+/// Returns PC if an error has been (or is being) reported.
+/// Otherwise returns 0.
+///
+/// \returns PC value.
+void *__asan_get_report_pc(void);
+
+/// Gets the BP (base pointer) register value of an ASan error (useful for
+/// calling from the debugger).
+///
+/// Returns BP if an error has been (or is being) reported.
+/// Otherwise returns 0.
+///
+/// \returns BP value.
+void *__asan_get_report_bp(void);
+
+/// Gets the SP (stack pointer) register value of an ASan error (useful for
+/// calling from the debugger).
+///
+/// If an error has been (or is being) reported, returns SP.
+/// Otherwise returns 0.
+///
+/// \returns SP value.
+void *__asan_get_report_sp(void);
+
+/// Gets the address of the report buffer of an ASan error (useful for calling
+/// from the debugger).
+///
+/// Returns the address of the report buffer if an error has been (or is being)
+/// reported. Otherwise returns 0.
+///
+/// \returns Address of report buffer.
+void *__asan_get_report_address(void);
+
+/// Gets access type of an ASan error (useful for calling from the debugger).
+///
+/// Returns access type (read or write) if an error has been (or is being)
+/// reported. Otherwise returns 0.
+///
+/// \returns Access type (0 = read, 1 = write).
+int __asan_get_report_access_type(void);
+
+/// Gets access size of an ASan error (useful for calling from the debugger).
+///
+/// Returns access size if an error has been (or is being) reported. Otherwise
+/// returns 0.
+///
+/// \returns Access size in bytes.
+size_t __asan_get_report_access_size(void);
+
+/// Gets the bug description of an ASan error (useful for calling from a
+/// debugger).
+///
+/// \returns Returns a bug description if an error has been (or is being)
+/// reported - for example, "heap-use-after-free". Otherwise returns an empty
+/// string.
+const char *__asan_get_report_description(void);
+
+/// Gets information about a pointer (useful for calling from the debugger).
+///
+/// Returns the category of the given pointer as a constant string.
+/// Possible return values are <c>global</c>, <c>stack</c>, <c>stack-fake</c>,
+/// <c>heap</c>, <c>heap-invalid</c>, <c>shadow-low</c>, <c>shadow-gap</c>,
+/// <c>shadow-high</c>, and <c>unknown</c>.
+///
+/// If the return value is <c>global</c> or <c>stack</c>, tries to also return
+/// the variable name, address, and size. If the return value is <c>heap</c>,
+/// tries to return the chunk address and size. <c><i>name</i></c> should point
+/// to an allocated buffer of size <c><i>name_size</i></c>.
+///
+/// \param addr Address to locate.
+/// \param name Buffer to store the variable's name.
+/// \param name_size Size in bytes of the variable's name buffer.
+/// \param region_address [out] Address of the region.
+/// \param region_size [out] Size of the region in bytes.
+///
+/// \returns Returns the category of the given pointer as a constant string.
+const char *__asan_locate_address(void *addr, char *name, size_t name_size,
+ void **region_address, size_t *region_size);
+
+/// Gets the allocation stack trace and thread ID for a heap address (useful
+/// for calling from the debugger).
+///
+/// Stores up to <c><i>size</i></c> frames in <c><i>trace</i></c>. Returns
+/// the number of stored frames or 0 on error.
+///
+/// \param addr A heap address.
+/// \param trace A buffer to store the stack trace.
+/// \param size Size in bytes of the trace buffer.
+/// \param thread_id [out] The thread ID of the address.
+///
+/// \returns Returns the number of stored frames or 0 on error.
+size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size,
+ int *thread_id);
+
+/// Gets the free stack trace and thread ID for a heap address (useful for
+/// calling from the debugger).
+///
+/// Stores up to <c><i>size</i></c> frames in <c><i>trace</i></c>. Returns
+/// the number of stored frames or 0 on error.
+///
+/// \param addr A heap address.
+/// \param trace A buffer to store the stack trace.
+/// \param size Size in bytes of the trace buffer.
+/// \param thread_id [out] The thread ID of the address.
+///
+/// \returns Returns the number of stored frames or 0 on error.
+size_t __asan_get_free_stack(void *addr, void **trace, size_t size,
+ int *thread_id);
+
+/// Gets the current shadow memory mapping (useful for calling from the
+/// debugger).
+///
+/// \param shadow_scale [out] Shadow scale value.
+/// \param shadow_offset [out] Offset value.
+void __asan_get_shadow_mapping(size_t *shadow_scale, size_t *shadow_offset);
+
+/// This is an internal function that is called to report an error. However,
+/// it is still a part of the interface because you might want to set a
+/// breakpoint on this function in the debugger.
+///
+/// \param pc <c><i>pc</i></c> value of the ASan error.
+/// \param bp <c><i>bp</i></c> value of the ASan error.
+/// \param sp <c><i>sp</i></c> value of the ASan error.
+/// \param addr Address of the ASan error.
+/// \param is_write True if the error is a write error; false otherwise.
+/// \param access_size Size of the memory access of the ASan error.
+void __asan_report_error(void *pc, void *bp, void *sp,
+ void *addr, int is_write, size_t access_size);
+
+// Deprecated. Call __sanitizer_set_death_callback instead.
+void __asan_set_death_callback(void (*callback)(void));
+
+/// Sets the callback function to be called during ASan error reporting.
+///
+/// The callback provides a string pointer to the report.
+///
+/// \param callback User-provided function.
+void __asan_set_error_report_callback(void (*callback)(const char *));
+
+/// User-provided callback on ASan errors.
+///
+/// You can provide a function that would be called immediately when ASan
+/// detects an error. This is useful in cases when ASan detects an error but
+/// your program crashes before the ASan report is printed.
+void __asan_on_error(void);
+
+/// Prints accumulated statistics to <c>stderr</c> (useful for calling from the
+/// debugger).
+void __asan_print_accumulated_stats(void);
+
+/// User-provided default option settings.
+///
+/// You can provide your own implementation of this function to return a string
+/// containing ASan runtime options (for example,
+/// <c>verbosity=1:halt_on_error=0</c>).
+///
+/// \returns Default options string.
+const char* __asan_default_options(void);
+
+// The following two functions facilitate garbage collection in presence of
+// ASan's fake stack.
+
+/// Gets an opaque handler to the current thread's fake stack.
+///
+/// Returns an opaque handler to be used by
+/// <c>__asan_addr_is_in_fake_stack()</c>. Returns NULL if the current thread
+/// does not have a fake stack.
+///
+/// \returns An opaque handler to the fake stack or NULL.
+void *__asan_get_current_fake_stack(void);
+
+/// Checks if an address belongs to a given fake stack.
+///
+/// If <c><i>fake_stack</i></c> is non-NULL and <c><i>addr</i></c> belongs to a
+/// fake frame in <c><i>fake_stack</i></c>, returns the address of the real
+/// stack that corresponds to the fake frame and sets <c><i>beg</i></c> and
+/// <c><i>end</i></c> to the boundaries of this fake frame. Otherwise returns
+/// NULL and does not touch <c><i>beg</i></c> and <c><i>end</i></c>.
+///
+/// If <c><i>beg</i></c> or <c><i>end</i></c> are NULL, they are not touched.
+///
+/// \note This function can be called from a thread other than the owner of
+/// <c><i>fake_stack</i></c>, but the owner thread needs to be alive.
+///
+/// \param fake_stack An opaque handler to a fake stack.
+/// \param addr Address to test.
+/// \param beg [out] Beginning of fake frame.
+/// \param end [out] End of fake frame.
+/// \returns Stack address or NULL.
+void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
+ void **end);
+
+/// Performs shadow memory cleanup of the current thread's stack before a
+/// function marked with the <c>[[noreturn]]</c> attribute is called.
+///
+/// To avoid false positives on the stack, must be called before no-return
+/// functions like <c>_exit()</c> and <c>execl()</c>.
+void __asan_handle_no_return(void);
#ifdef __cplusplus
} // extern "C"
diff --git a/libsanitizer/include/sanitizer/common_interface_defs.h b/libsanitizer/include/sanitizer/common_interface_defs.h
index b8ae094..f979c6a 100644
--- a/libsanitizer/include/sanitizer/common_interface_defs.h
+++ b/libsanitizer/include/sanitizer/common_interface_defs.h
@@ -1,7 +1,8 @@
//===-- sanitizer/common_interface_defs.h -----------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -16,189 +17,335 @@
// GCC does not understand __has_feature.
#if !defined(__has_feature)
-# define __has_feature(x) 0
+#define __has_feature(x) 0
#endif
#ifdef __cplusplus
extern "C" {
#endif
- // Arguments for __sanitizer_sandbox_on_notify() below.
- typedef struct {
- // Enable sandbox support in sanitizer coverage.
- int coverage_sandboxed;
- // File descriptor to write coverage data to. If -1 is passed, a file will
- // be pre-opened by __sanitizer_sandobx_on_notify(). This field has no
- // effect if coverage_sandboxed == 0.
- intptr_t coverage_fd;
- // If non-zero, split the coverage data into well-formed blocks. This is
- // useful when coverage_fd is a socket descriptor. Each block will contain
- // a header, allowing data from multiple processes to be sent over the same
- // socket.
- unsigned int coverage_max_block_size;
- } __sanitizer_sandbox_arguments;
-
- // Tell the tools to write their reports to "path.<pid>" instead of stderr.
- void __sanitizer_set_report_path(const char *path);
- // Tell the tools to write their reports to the provided file descriptor
- // (casted to void *).
- void __sanitizer_set_report_fd(void *fd);
-
- // Notify the tools that the sandbox is going to be turned on. The reserved
- // parameter will be used in the future to hold a structure with functions
- // that the tools may call to bypass the sandbox.
- void __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args);
-
- // This function is called by the tool when it has just finished reporting
- // an error. 'error_summary' is a one-line string that summarizes
- // the error message. This function can be overridden by the client.
- void __sanitizer_report_error_summary(const char *error_summary);
-
- // Some of the sanitizers (e.g. asan/tsan) may miss bugs that happen
- // in unaligned loads/stores. In order to find such bugs reliably one needs
- // to replace plain unaligned loads/stores with these calls.
- uint16_t __sanitizer_unaligned_load16(const void *p);
- uint32_t __sanitizer_unaligned_load32(const void *p);
- uint64_t __sanitizer_unaligned_load64(const void *p);
- void __sanitizer_unaligned_store16(void *p, uint16_t x);
- void __sanitizer_unaligned_store32(void *p, uint32_t x);
- void __sanitizer_unaligned_store64(void *p, uint64_t x);
-
- // Returns 1 on the first call, then returns 0 thereafter. Called by the tool
- // to ensure only one report is printed when multiple errors occur
- // simultaneously.
- int __sanitizer_acquire_crash_state();
-
- // Annotate the current state of a contiguous container, such as
- // std::vector, std::string or similar.
- // A contiguous container is a container that keeps all of its elements
- // in a contiguous region of memory. The container owns the region of memory
- // [beg, end); the memory [beg, mid) is used to store the current elements
- // and the memory [mid, end) is reserved for future elements;
- // beg <= mid <= end. For example, in "std::vector<> v"
- // beg = &v[0];
- // end = beg + v.capacity() * sizeof(v[0]);
- // mid = beg + v.size() * sizeof(v[0]);
- //
- // This annotation tells the Sanitizer tool about the current state of the
- // container so that the tool can report errors when memory from [mid, end)
- // is accessed. Insert this annotation into methods like push_back/pop_back.
- // Supply the old and the new values of mid (old_mid/new_mid).
- // In the initial state mid == end and so should be the final
- // state when the container is destroyed or when it reallocates the storage.
- //
- // Use with caution and don't use for anything other than vector-like classes.
- //
- // For AddressSanitizer, 'beg' should be 8-aligned and 'end' should
- // be either 8-aligned or it should point to the end of a separate heap-,
- // stack-, or global- allocated buffer. I.e. the following will not work:
- // int64_t x[2]; // 16 bytes, 8-aligned.
- // char *beg = (char *)&x[0];
- // char *end = beg + 12; // Not 8 aligned, not the end of the buffer.
- // This however will work fine:
- // int32_t x[3]; // 12 bytes, but 8-aligned under AddressSanitizer.
- // char *beg = (char*)&x[0];
- // char *end = beg + 12; // Not 8-aligned, but is the end of the buffer.
- void __sanitizer_annotate_contiguous_container(const void *beg,
- const void *end,
- const void *old_mid,
- const void *new_mid);
- // Returns true if the contiguous container [beg, end) is properly poisoned
- // (e.g. with __sanitizer_annotate_contiguous_container), i.e. if
- // - [beg, mid) is addressable,
- // - [mid, end) is unaddressable.
- // Full verification requires O(end-beg) time; this function tries to avoid
- // such complexity by touching only parts of the container around beg/mid/end.
- int __sanitizer_verify_contiguous_container(const void *beg, const void *mid,
- const void *end);
-
- // Similar to __sanitizer_verify_contiguous_container but returns the address
- // of the first improperly poisoned byte otherwise. Returns null if the area
- // is poisoned properly.
- const void *__sanitizer_contiguous_container_find_bad_address(
- const void *beg, const void *mid, const void *end);
-
- // Print the stack trace leading to this call. Useful for debugging user code.
- void __sanitizer_print_stack_trace(void);
-
- // Symbolizes the supplied 'pc' using the format string 'fmt'.
- // Outputs at most 'out_buf_size' bytes into 'out_buf'.
- // If 'out_buf' is not empty then output is zero or more non empty C strings
- // followed by single empty C string. Multiple strings can be returned if PC
- // corresponds to inlined function. Inlined frames are printed in the order
- // from "most-inlined" to the "least-inlined", so the last frame should be the
- // not inlined function.
- // Inlined frames can be removed with 'symbolize_inline_frames=0'.
- // The format syntax is described in
- // lib/sanitizer_common/sanitizer_stacktrace_printer.h.
- void __sanitizer_symbolize_pc(void *pc, const char *fmt, char *out_buf,
- size_t out_buf_size);
- // Same as __sanitizer_symbolize_pc, but for data section (i.e. globals).
- void __sanitizer_symbolize_global(void *data_ptr, const char *fmt,
- char *out_buf, size_t out_buf_size);
-
- // Sets the callback to be called right before death on error.
- // Passing 0 will unset the callback.
- void __sanitizer_set_death_callback(void (*callback)(void));
-
- // Interceptor hooks.
- // Whenever a libc function interceptor is called it checks if the
- // corresponding weak hook is defined, and it so -- calls it.
- // The primary use case is data-flow-guided fuzzing, where the fuzzer needs
- // to know what is being passed to libc functions, e.g. memcmp.
- // FIXME: implement more hooks.
- void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1,
- const void *s2, size_t n, int result);
- void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
- const char *s2, size_t n, int result);
- void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
- const char *s2, size_t n, int result);
- void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1,
- const char *s2, int result);
- void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
- const char *s2, int result);
- void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
- const char *s2, char *result);
- void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
- const char *s2, char *result);
- void __sanitizer_weak_hook_memmem(void *called_pc,
- const void *s1, size_t len1,
- const void *s2, size_t len2, void *result);
-
- // Prints stack traces for all live heap allocations ordered by total
- // allocation size until `top_percent` of total live heap is shown.
- // `top_percent` should be between 1 and 100.
- // At most `max_number_of_contexts` contexts (stack traces) is printed.
- // Experimental feature currently available only with asan on Linux/x86_64.
- void __sanitizer_print_memory_profile(size_t top_percent,
- size_t max_number_of_contexts);
-
- // Fiber annotation interface.
- // Before switching to a different stack, one must call
- // __sanitizer_start_switch_fiber with a pointer to the bottom of the
- // destination stack and its size. When code starts running on the new stack,
- // it must call __sanitizer_finish_switch_fiber to finalize the switch.
- // The start_switch function takes a void** to store the current fake stack if
- // there is one (it is needed when detect_stack_use_after_return is enabled).
- // When restoring a stack, this pointer must be given to the finish_switch
- // function. In most cases, this void* can be stored on the stack just before
- // switching. When leaving a fiber definitely, null must be passed as first
- // argument to the start_switch function so that the fake stack is destroyed.
- // If you do not want support for stack use-after-return detection, you can
- // always pass null to these two functions.
- // Note that the fake stack mechanism is disabled during fiber switch, so if a
- // signal callback runs during the switch, it will not benefit from the stack
- // use-after-return detection.
- void __sanitizer_start_switch_fiber(void **fake_stack_save,
- const void *bottom, size_t size);
- void __sanitizer_finish_switch_fiber(void *fake_stack_save,
- const void **bottom_old,
- size_t *size_old);
-
- // Get full module name and calculate pc offset within it.
- // Returns 1 if pc belongs to some module, 0 if module was not found.
- int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_path,
- size_t module_path_len,
- void **pc_offset);
+// Arguments for __sanitizer_sandbox_on_notify() below.
+typedef struct {
+ // Enable sandbox support in sanitizer coverage.
+ int coverage_sandboxed;
+ // File descriptor to write coverage data to. If -1 is passed, a file will
+ // be pre-opened by __sanitizer_sandobx_on_notify(). This field has no
+ // effect if coverage_sandboxed == 0.
+ intptr_t coverage_fd;
+ // If non-zero, split the coverage data into well-formed blocks. This is
+ // useful when coverage_fd is a socket descriptor. Each block will contain
+ // a header, allowing data from multiple processes to be sent over the same
+ // socket.
+ unsigned int coverage_max_block_size;
+} __sanitizer_sandbox_arguments;
+
+// Tell the tools to write their reports to "path.<pid>" instead of stderr.
+void __sanitizer_set_report_path(const char *path);
+// Tell the tools to write their reports to the provided file descriptor
+// (casted to void *).
+void __sanitizer_set_report_fd(void *fd);
+
+// Notify the tools that the sandbox is going to be turned on. The reserved
+// parameter will be used in the future to hold a structure with functions
+// that the tools may call to bypass the sandbox.
+void __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args);
+
+// This function is called by the tool when it has just finished reporting
+// an error. 'error_summary' is a one-line string that summarizes
+// the error message. This function can be overridden by the client.
+void __sanitizer_report_error_summary(const char *error_summary);
+
+// Some of the sanitizers (for example ASan/TSan) could miss bugs that happen
+// in unaligned loads/stores. To find such bugs reliably, you need to replace
+// plain unaligned loads/stores with these calls.
+
+/// Loads a 16-bit unaligned value.
+///
+/// \param p Pointer to unaligned memory.
+///
+/// \returns Loaded value.
+uint16_t __sanitizer_unaligned_load16(const void *p);
+
+/// Loads a 32-bit unaligned value.
+///
+/// \param p Pointer to unaligned memory.
+///
+/// \returns Loaded value.
+uint32_t __sanitizer_unaligned_load32(const void *p);
+
+/// Loads a 64-bit unaligned value.
+///
+/// \param p Pointer to unaligned memory.
+///
+/// \returns Loaded value.
+uint64_t __sanitizer_unaligned_load64(const void *p);
+
+/// Stores a 16-bit unaligned value.
+///
+/// \param p Pointer to unaligned memory.
+/// \param x 16-bit value to store.
+void __sanitizer_unaligned_store16(void *p, uint16_t x);
+
+/// Stores a 32-bit unaligned value.
+///
+/// \param p Pointer to unaligned memory.
+/// \param x 32-bit value to store.
+void __sanitizer_unaligned_store32(void *p, uint32_t x);
+
+/// Stores a 64-bit unaligned value.
+///
+/// \param p Pointer to unaligned memory.
+/// \param x 64-bit value to store.
+void __sanitizer_unaligned_store64(void *p, uint64_t x);
+
+// Returns 1 on the first call, then returns 0 thereafter. Called by the tool
+// to ensure only one report is printed when multiple errors occur
+// simultaneously.
+int __sanitizer_acquire_crash_state();
+
+/// Annotates the current state of a contiguous container, such as
+/// <c>std::vector</c>, <c>std::string</c>, or similar.
+///
+/// A contiguous container is a container that keeps all of its elements
+/// in a contiguous region of memory. The container owns the region of memory
+/// <c>[beg, end)</c>; the memory <c>[beg, mid)</c> is used to store the
+/// current elements, and the memory <c>[mid, end)</c> is reserved for future
+/// elements (<c>beg <= mid <= end</c>). For example, in
+/// <c>std::vector<> v</c>:
+///
+/// \code
+/// beg = &v[0];
+/// end = beg + v.capacity() * sizeof(v[0]);
+/// mid = beg + v.size() * sizeof(v[0]);
+/// \endcode
+///
+/// This annotation tells the Sanitizer tool about the current state of the
+/// container so that the tool can report errors when memory from
+/// <c>[mid, end)</c> is accessed. Insert this annotation into methods like
+/// <c>push_back()</c> or <c>pop_back()</c>. Supply the old and new values of
+/// <c>mid</c>(<c><i>old_mid</i></c> and <c><i>new_mid</i></c>). In the initial
+/// state <c>mid == end</c>, so that should be the final state when the
+/// container is destroyed or when the container reallocates the storage.
+///
+/// For ASan, <c><i>beg</i></c> should be 8-aligned and <c><i>end</i></c>
+/// should be either 8-aligned or it should point to the end of a separate
+/// heap-, stack-, or global-allocated buffer. So the following example will
+/// not work:
+///
+/// \code
+/// int64_t x[2]; // 16 bytes, 8-aligned
+/// char *beg = (char *)&x[0];
+/// char *end = beg + 12; // Not 8-aligned, not the end of the buffer
+/// \endcode
+///
+/// The following, however, will work:
+/// \code
+/// int32_t x[3]; // 12 bytes, but 8-aligned under ASan.
+/// char *beg = (char*)&x[0];
+/// char *end = beg + 12; // Not 8-aligned, but is the end of the buffer
+/// \endcode
+///
+/// \note Use this function with caution and do not use for anything other
+/// than vector-like classes.
+///
+/// \param beg Beginning of memory region.
+/// \param end End of memory region.
+/// \param old_mid Old middle of memory region.
+/// \param new_mid New middle of memory region.
+void __sanitizer_annotate_contiguous_container(const void *beg,
+ const void *end,
+ const void *old_mid,
+ const void *new_mid);
+
+/// Returns true if the contiguous container <c>[beg, end)</c> is properly
+/// poisoned.
+///
+/// Proper poisoning could occur, for example, with
+/// <c>__sanitizer_annotate_contiguous_container</c>), that is, if
+/// <c>[beg, mid)</c> is addressable and <c>[mid, end)</c> is unaddressable.
+/// Full verification requires O (<c>end - beg</c>) time; this function tries
+/// to avoid such complexity by touching only parts of the container around
+/// <c><i>beg</i></c>, <c><i>mid</i></c>, and <c><i>end</i></c>.
+///
+/// \param beg Beginning of memory region.
+/// \param mid Middle of memory region.
+/// \param end Old end of memory region.
+///
+/// \returns True if the contiguous container <c>[beg, end)</c> is properly
+/// poisoned.
+int __sanitizer_verify_contiguous_container(const void *beg, const void *mid,
+ const void *end);
+
+/// Similar to <c>__sanitizer_verify_contiguous_container()</c> but also
+/// returns the address of the first improperly poisoned byte.
+///
+/// Returns NULL if the area is poisoned properly.
+///
+/// \param beg Beginning of memory region.
+/// \param mid Middle of memory region.
+/// \param end Old end of memory region.
+///
+/// \returns The bad address or NULL.
+const void *__sanitizer_contiguous_container_find_bad_address(const void *beg,
+ const void *mid,
+ const void *end);
+
+/// Prints the stack trace leading to this call (useful for calling from the
+/// debugger).
+void __sanitizer_print_stack_trace(void);
+
+// Symbolizes the supplied 'pc' using the format string 'fmt'.
+// Outputs at most 'out_buf_size' bytes into 'out_buf'.
+// If 'out_buf' is not empty then output is zero or more non empty C strings
+// followed by single empty C string. Multiple strings can be returned if PC
+// corresponds to inlined function. Inlined frames are printed in the order
+// from "most-inlined" to the "least-inlined", so the last frame should be the
+// not inlined function.
+// Inlined frames can be removed with 'symbolize_inline_frames=0'.
+// The format syntax is described in
+// lib/sanitizer_common/sanitizer_stacktrace_printer.h.
+void __sanitizer_symbolize_pc(void *pc, const char *fmt, char *out_buf,
+ size_t out_buf_size);
+// Same as __sanitizer_symbolize_pc, but for data section (i.e. globals).
+void __sanitizer_symbolize_global(void *data_ptr, const char *fmt,
+ char *out_buf, size_t out_buf_size);
+
+/// Sets the callback to be called immediately before death on error.
+///
+/// Passing 0 will unset the callback.
+///
+/// \param callback User-provided callback.
+void __sanitizer_set_death_callback(void (*callback)(void));
+
+
+// Interceptor hooks.
+// Whenever a libc function interceptor is called, it checks if the
+// corresponding weak hook is defined, and calls it if it is indeed defined.
+// The primary use-case is data-flow-guided fuzzing, where the fuzzer needs
+// to know what is being passed to libc functions (for example memcmp).
+// FIXME: implement more hooks.
+
+/// Interceptor hook for <c>memcmp()</c>.
+///
+/// \param called_pc PC (program counter) address of the original call.
+/// \param s1 Pointer to block of memory.
+/// \param s2 Pointer to block of memory.
+/// \param n Number of bytes to compare.
+/// \param result Value returned by the intercepted function.
+void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1,
+ const void *s2, size_t n, int result);
+
+/// Interceptor hook for <c>strncmp()</c>.
+///
+/// \param called_pc PC (program counter) address of the original call.
+/// \param s1 Pointer to block of memory.
+/// \param s2 Pointer to block of memory.
+/// \param n Number of bytes to compare.
+/// \param result Value returned by the intercepted function.
+void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1,
+ const char *s2, size_t n, int result);
+
+/// Interceptor hook for <c>strncasecmp()</c>.
+///
+/// \param called_pc PC (program counter) address of the original call.
+/// \param s1 Pointer to block of memory.
+/// \param s2 Pointer to block of memory.
+/// \param n Number of bytes to compare.
+/// \param result Value returned by the intercepted function.
+void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
+ const char *s2, size_t n, int result);
+
+/// Interceptor hook for <c>strcmp()</c>.
+///
+/// \param called_pc PC (program counter) address of the original call.
+/// \param s1 Pointer to block of memory.
+/// \param s2 Pointer to block of memory.
+/// \param result Value returned by the intercepted function.
+void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1,
+ const char *s2, int result);
+
+/// Interceptor hook for <c>strcasecmp()</c>.
+///
+/// \param called_pc PC (program counter) address of the original call.
+/// \param s1 Pointer to block of memory.
+/// \param s2 Pointer to block of memory.
+/// \param result Value returned by the intercepted function.
+void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
+ const char *s2, int result);
+
+/// Interceptor hook for <c>strstr()</c>.
+///
+/// \param called_pc PC (program counter) address of the original call.
+/// \param s1 Pointer to block of memory.
+/// \param s2 Pointer to block of memory.
+/// \param result Value returned by the intercepted function.
+void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1,
+ const char *s2, char *result);
+
+void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1,
+ const char *s2, char *result);
+
+void __sanitizer_weak_hook_memmem(void *called_pc,
+ const void *s1, size_t len1,
+ const void *s2, size_t len2, void *result);
+
+// Prints stack traces for all live heap allocations ordered by total
+// allocation size until top_percent of total live heap is shown. top_percent
+// should be between 1 and 100. At most max_number_of_contexts contexts
+// (stack traces) are printed.
+// Experimental feature currently available only with ASan on Linux/x86_64.
+void __sanitizer_print_memory_profile(size_t top_percent,
+ size_t max_number_of_contexts);
+
+/// Notify ASan that a fiber switch has started (required only if implementing
+/// your own fiber library).
+///
+/// Before switching to a different stack, you must call
+/// <c>__sanitizer_start_switch_fiber()</c> with a pointer to the bottom of the
+/// destination stack and with its size. When code starts running on the new
+/// stack, it must call <c>__sanitizer_finish_switch_fiber()</c> to finalize
+/// the switch. The <c>__sanitizer_start_switch_fiber()</c> function takes a
+/// <c>void**</c> pointer argument to store the current fake stack if there is
+/// one (it is necessary when the runtime option
+/// <c>detect_stack_use_after_return</c> is enabled).
+///
+/// When restoring a stack, this <c>void**</c> pointer must be given to the
+/// <c>__sanitizer_finish_switch_fiber()</c> function. In most cases, this
+/// pointer can be stored on the stack immediately before switching. When
+/// leaving a fiber definitely, NULL must be passed as the first argument to
+/// the <c>__sanitizer_start_switch_fiber()</c> function so that the fake stack
+/// is destroyed. If your program does not need stack use-after-return
+/// detection, you can always pass NULL to these two functions.
+///
+/// \note The fake stack mechanism is disabled during fiber switch, so if a
+/// signal callback runs during the switch, it will not benefit from stack
+/// use-after-return detection.
+///
+/// \param fake_stack_save [out] Fake stack save location.
+/// \param bottom Bottom address of stack.
+/// \param size Size of stack in bytes.
+void __sanitizer_start_switch_fiber(void **fake_stack_save,
+ const void *bottom, size_t size);
+
+/// Notify ASan that a fiber switch has completed (required only if
+/// implementing your own fiber library).
+///
+/// When code starts running on the new stack, it must call
+/// <c>__sanitizer_finish_switch_fiber()</c> to finalize
+/// the switch. For usage details, see the description of
+/// <c>__sanitizer_start_switch_fiber()</c>.
+///
+/// \param fake_stack_save Fake stack save location.
+/// \param bottom_old [out] Bottom address of old stack.
+/// \param size_old [out] Size of old stack in bytes.
+void __sanitizer_finish_switch_fiber(void *fake_stack_save,
+ const void **bottom_old,
+ size_t *size_old);
+
+// Get full module name and calculate pc offset within it.
+// Returns 1 if pc belongs to some module, 0 if module was not found.
+int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_path,
+ size_t module_path_len,
+ void **pc_offset);
#ifdef __cplusplus
} // extern "C"
diff --git a/libsanitizer/include/sanitizer/coverage_interface.h b/libsanitizer/include/sanitizer/coverage_interface.h
index 2f36135..c063cfe 100644
--- a/libsanitizer/include/sanitizer/coverage_interface.h
+++ b/libsanitizer/include/sanitizer/coverage_interface.h
@@ -1,7 +1,8 @@
//===-- sanitizer/coverage_interface.h --------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/include/sanitizer/dfsan_interface.h b/libsanitizer/include/sanitizer/dfsan_interface.h
index 0cebccf..c189ee5 100644
--- a/libsanitizer/include/sanitizer/dfsan_interface.h
+++ b/libsanitizer/include/sanitizer/dfsan_interface.h
@@ -1,7 +1,8 @@
//===-- dfsan_interface.h -------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -78,6 +79,12 @@ dfsan_label dfsan_has_label_with_desc(dfsan_label label, const char *desc);
/// Returns the number of labels allocated.
size_t dfsan_get_label_count(void);
+/// Flushes the DFSan shadow, i.e. forgets about all labels currently associated
+/// with the application memory. Will work only if there are no other
+/// threads executing DFSan-instrumented code concurrently.
+/// Use this call to start over the taint tracking within the same procces.
+void dfsan_flush(void);
+
/// Sets a callback to be invoked on calls to write(). The callback is invoked
/// before the write is done. The write is not guaranteed to succeed when the
/// callback executes. Pass in NULL to remove any callback.
diff --git a/libsanitizer/include/sanitizer/esan_interface.h b/libsanitizer/include/sanitizer/esan_interface.h
deleted file mode 100644
index e22b6a8..0000000
--- a/libsanitizer/include/sanitizer/esan_interface.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//===-- sanitizer/esan_interface.h ------------------------------*- C++ -*-===//
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of EfficiencySanitizer, a family of performance tuners.
-//
-// Public interface header.
-//===----------------------------------------------------------------------===//
-#ifndef SANITIZER_ESAN_INTERFACE_H
-#define SANITIZER_ESAN_INTERFACE_H
-
-#include <sanitizer/common_interface_defs.h>
-
-// We declare our interface routines as weak to allow the user to avoid
-// ifdefs and instead use this pattern to allow building the same sources
-// with and without our runtime library:
-// if (__esan_report)
-// __esan_report();
-#ifdef _MSC_VER
-/* selectany is as close to weak as we'll get. */
-#define COMPILER_RT_WEAK __declspec(selectany)
-#elif __GNUC__
-#define COMPILER_RT_WEAK __attribute__((weak))
-#else
-#define COMPILER_RT_WEAK
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// This function can be called mid-run (or at the end of a run for
-// a server process that doesn't shut down normally) to request that
-// data for that point in the run be reported from the tool.
-void COMPILER_RT_WEAK __esan_report(void);
-
-// This function returns the number of samples that the esan tool has collected
-// to this point. This is useful for testing.
-unsigned int COMPILER_RT_WEAK __esan_get_sample_count(void);
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif // SANITIZER_ESAN_INTERFACE_H
diff --git a/libsanitizer/include/sanitizer/hwasan_interface.h b/libsanitizer/include/sanitizer/hwasan_interface.h
index 938e9ac..4c9ad13 100644
--- a/libsanitizer/include/sanitizer/hwasan_interface.h
+++ b/libsanitizer/include/sanitizer/hwasan_interface.h
@@ -1,7 +1,8 @@
//===-- sanitizer/asan_interface.h ------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -17,11 +18,15 @@
#ifdef __cplusplus
extern "C" {
#endif
- // Initialize shadow but not the rest of the runtime.
+ // Libc hook for program startup in statically linked executables.
+ // Initializes enough of the runtime to run instrumented code. This function
+ // should only be called in statically linked executables because it modifies
+ // the GOT, which won't work in regular binaries because RELRO will already
+ // have been applied by the time the function is called. This also means that
+ // the function should be called before libc applies RELRO.
// Does not call libc unless there is an error.
- // Can be called multiple times, or not at all (in which case shadow will
- // be initialized in compiler-inserted __hwasan_init() call).
- void __hwasan_shadow_init(void);
+ // Can be called multiple times.
+ void __hwasan_init_static(void);
// This function may be optionally provided by user and should return
// a string containing HWASan runtime options. See asan_flags.h for details.
@@ -45,6 +50,10 @@ extern "C" {
// does would cause false reports.
void __hwasan_handle_longjmp(const void *sp_dst);
+ // Set memory tag for the part of the current thread stack below sp_dst to
+ // zero. Call this in vfork() before returning in the parent process.
+ void __hwasan_handle_vfork(const void *sp_dst);
+
// Libc hook for thread creation. Should be called in the child thread before
// any instrumented code.
void __hwasan_thread_enter();
@@ -60,6 +69,10 @@ extern "C" {
// Print one-line report about the memory usage of the current process.
void __hwasan_print_memory_usage();
+ /* Returns the offset of the first byte in the memory range that can not be
+ * accessed through the pointer in x, or -1 if the whole range is good. */
+ intptr_t __hwasan_test_shadow(const volatile void *x, size_t size);
+
int __sanitizer_posix_memalign(void **memptr, size_t alignment, size_t size);
void * __sanitizer_memalign(size_t alignment, size_t size);
void * __sanitizer_aligned_alloc(size_t alignment, size_t size);
@@ -74,6 +87,7 @@ extern "C" {
void __sanitizer_malloc_stats(void);
void * __sanitizer_calloc(size_t nmemb, size_t size);
void * __sanitizer_realloc(void *ptr, size_t size);
+ void * __sanitizer_reallocarray(void *ptr, size_t nmemb, size_t size);
void * __sanitizer_malloc(size_t size);
#ifdef __cplusplus
} // extern "C"
diff --git a/libsanitizer/include/sanitizer/linux_syscall_hooks.h b/libsanitizer/include/sanitizer/linux_syscall_hooks.h
index 34bb291..a1794b7 100644
--- a/libsanitizer/include/sanitizer/linux_syscall_hooks.h
+++ b/libsanitizer/include/sanitizer/linux_syscall_hooks.h
@@ -1,7 +1,8 @@
//===-- linux_syscall_hooks.h ---------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/include/sanitizer/lsan_interface.h b/libsanitizer/include/sanitizer/lsan_interface.h
index 93b2e9c..2bb9926 100644
--- a/libsanitizer/include/sanitizer/lsan_interface.h
+++ b/libsanitizer/include/sanitizer/lsan_interface.h
@@ -1,7 +1,8 @@
//===-- sanitizer/lsan_interface.h ------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/include/sanitizer/msan_interface.h b/libsanitizer/include/sanitizer/msan_interface.h
index 4dfae60..d40c556 100644
--- a/libsanitizer/include/sanitizer/msan_interface.h
+++ b/libsanitizer/include/sanitizer/msan_interface.h
@@ -1,7 +1,8 @@
//===-- msan_interface.h --------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -41,6 +42,9 @@ extern "C" {
contents). */
void __msan_unpoison_string(const volatile char *a);
+ /* Make first n parameters of the next function call fully initialized. */
+ void __msan_unpoison_param(size_t n);
+
/* Make memory region fully uninitialized (without changing its contents).
This is a legacy interface that does not update origin information. Use
__msan_allocated_memory() instead. */
diff --git a/libsanitizer/include/sanitizer/netbsd_syscall_hooks.h b/libsanitizer/include/sanitizer/netbsd_syscall_hooks.h
index 8cf5121..27780e0 100644
--- a/libsanitizer/include/sanitizer/netbsd_syscall_hooks.h
+++ b/libsanitizer/include/sanitizer/netbsd_syscall_hooks.h
@@ -1,7 +1,8 @@
//===-- netbsd_syscall_hooks.h --------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -19,8 +20,8 @@
// DO NOT EDIT! THIS FILE HAS BEEN GENERATED!
//
// Generated with: generate_netbsd_syscalls.awk
-// Generated date: 2018-03-03
-// Generated from: syscalls.master,v 1.291 2018/01/06 16:41:23 kamil Exp
+// Generated date: 2018-10-30
+// Generated from: syscalls.master,v 1.293 2018/07/31 13:00:13 rjs Exp
//
//===----------------------------------------------------------------------===//
#ifndef SANITIZER_NETBSD_SYSCALL_HOOKS_H
@@ -984,7 +985,15 @@
#define __sanitizer_syscall_post_fpathconf(res, fd, name) \
__sanitizer_syscall_post_impl_fpathconf(res, (long long)(fd), \
(long long)(name))
-/* syscall 193 has been skipped */
+#define __sanitizer_syscall_pre_getsockopt2(s, level, name, val, avalsize) \
+ __sanitizer_syscall_pre_impl_getsockopt2( \
+ (long long)(s), (long long)(level), (long long)(name), (long long)(val), \
+ (long long)(avalsize))
+#define __sanitizer_syscall_post_getsockopt2(res, s, level, name, val, \
+ avalsize) \
+ __sanitizer_syscall_post_impl_getsockopt2( \
+ res, (long long)(s), (long long)(level), (long long)(name), \
+ (long long)(val), (long long)(avalsize))
#define __sanitizer_syscall_pre_getrlimit(which, rlp) \
__sanitizer_syscall_pre_impl_getrlimit((long long)(which), (long long)(rlp))
#define __sanitizer_syscall_post_getrlimit(res, which, rlp) \
@@ -1750,18 +1759,8 @@
__sanitizer_syscall_post_impl___sigaction_sigtramp( \
res, (long long)(signum), (long long)(nsa), (long long)(osa), \
(long long)(tramp), (long long)(vers))
-#define __sanitizer_syscall_pre_pmc_get_info(ctr, op, args) \
- __sanitizer_syscall_pre_impl_pmc_get_info((long long)(ctr), (long long)(op), \
- (long long)(args))
-#define __sanitizer_syscall_post_pmc_get_info(res, ctr, op, args) \
- __sanitizer_syscall_post_impl_pmc_get_info( \
- res, (long long)(ctr), (long long)(op), (long long)(args))
-#define __sanitizer_syscall_pre_pmc_control(ctr, op, args) \
- __sanitizer_syscall_pre_impl_pmc_control((long long)(ctr), (long long)(op), \
- (long long)(args))
-#define __sanitizer_syscall_post_pmc_control(res, ctr, op, args) \
- __sanitizer_syscall_post_impl_pmc_control( \
- res, (long long)(ctr), (long long)(op), (long long)(args))
+/* syscall 341 has been skipped */
+/* syscall 342 has been skipped */
#define __sanitizer_syscall_pre_rasctl(addr, len, op) \
__sanitizer_syscall_pre_impl_rasctl((long long)(addr), (long long)(len), \
(long long)(op))
@@ -3442,7 +3441,13 @@ void __sanitizer_syscall_post_impl_pathconf(long long res, long long path,
void __sanitizer_syscall_pre_impl_fpathconf(long long fd, long long name);
void __sanitizer_syscall_post_impl_fpathconf(long long res, long long fd,
long long name);
-/* syscall 193 has been skipped */
+void __sanitizer_syscall_pre_impl_getsockopt2(long long s, long long level,
+ long long name, long long val,
+ long long avalsize);
+void __sanitizer_syscall_post_impl_getsockopt2(long long res, long long s,
+ long long level, long long name,
+ long long val,
+ long long avalsize);
void __sanitizer_syscall_pre_impl_getrlimit(long long which, long long rlp);
void __sanitizer_syscall_post_impl_getrlimit(long long res, long long which,
long long rlp);
@@ -3999,14 +4004,8 @@ void __sanitizer_syscall_pre_impl___sigaction_sigtramp(long long signum,
void __sanitizer_syscall_post_impl___sigaction_sigtramp(
long long res, long long signum, long long nsa, long long osa,
long long tramp, long long vers);
-void __sanitizer_syscall_pre_impl_pmc_get_info(long long ctr, long long op,
- long long args);
-void __sanitizer_syscall_post_impl_pmc_get_info(long long res, long long ctr,
- long long op, long long args);
-void __sanitizer_syscall_pre_impl_pmc_control(long long ctr, long long op,
- long long args);
-void __sanitizer_syscall_post_impl_pmc_control(long long res, long long ctr,
- long long op, long long args);
+/* syscall 341 has been skipped */
+/* syscall 342 has been skipped */
void __sanitizer_syscall_pre_impl_rasctl(long long addr, long long len,
long long op);
void __sanitizer_syscall_post_impl_rasctl(long long res, long long addr,
diff --git a/libsanitizer/include/sanitizer/scudo_interface.h b/libsanitizer/include/sanitizer/scudo_interface.h
index ca9a6f1..dd522c1 100644
--- a/libsanitizer/include/sanitizer/scudo_interface.h
+++ b/libsanitizer/include/sanitizer/scudo_interface.h
@@ -1,7 +1,8 @@
//===-- sanitizer/scudo_interface.h -----------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/include/sanitizer/tsan_interface.h b/libsanitizer/include/sanitizer/tsan_interface.h
index b86062b..011b233 100644
--- a/libsanitizer/include/sanitizer/tsan_interface.h
+++ b/libsanitizer/include/sanitizer/tsan_interface.h
@@ -1,7 +1,8 @@
//===-- tsan_interface.h ----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -135,6 +136,24 @@ void __tsan_external_assign_tag(void *addr, void *tag);
void __tsan_external_read(void *addr, void *caller_pc, void *tag);
void __tsan_external_write(void *addr, void *caller_pc, void *tag);
+// Fiber switching API.
+// - TSAN context for fiber can be created by __tsan_create_fiber
+// and freed by __tsan_destroy_fiber.
+// - TSAN context of current fiber or thread can be obtained
+// by calling __tsan_get_current_fiber.
+// - __tsan_switch_to_fiber should be called immediatly before switch
+// to fiber, such as call of swapcontext.
+// - Fiber name can be set by __tsan_set_fiber_name.
+void *__tsan_get_current_fiber(void);
+void *__tsan_create_fiber(unsigned flags);
+void __tsan_destroy_fiber(void *fiber);
+void __tsan_switch_to_fiber(void *fiber, unsigned flags);
+void __tsan_set_fiber_name(void *fiber, const char *name);
+
+// Flags for __tsan_switch_to_fiber:
+// Do not establish a happens-before relation between fibers
+const unsigned __tsan_switch_to_fiber_no_sync = 1 << 0;
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/libsanitizer/include/sanitizer/tsan_interface_atomic.h b/libsanitizer/include/sanitizer/tsan_interface_atomic.h
index d19c910..9ce0411 100644
--- a/libsanitizer/include/sanitizer/tsan_interface_atomic.h
+++ b/libsanitizer/include/sanitizer/tsan_interface_atomic.h
@@ -1,7 +1,8 @@
//===-- tsan_interface_atomic.h ---------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -29,7 +30,7 @@ __extension__ typedef __int128 __tsan_atomic128;
#endif
// Part of ABI, do not change.
-// http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/atomic?view=markup
+// https://github.com/llvm/llvm-project/blob/master/libcxx/include/atomic
typedef enum {
__tsan_memory_order_relaxed,
__tsan_memory_order_consume,
diff --git a/libsanitizer/interception/Makefile.am b/libsanitizer/interception/Makefile.am
index 22ce8d5..a22e0b4 100644
--- a/libsanitizer/interception/Makefile.am
+++ b/libsanitizer/interception/Makefile.am
@@ -13,10 +13,10 @@ ACLOCAL_AMFLAGS = -I m4
noinst_LTLIBRARIES = libinterception.la
interception_files = \
- interception_linux.cc \
- interception_mac.cc \
- interception_win.cc \
- interception_type_test.cc
+ interception_linux.cpp \
+ interception_mac.cpp \
+ interception_win.cpp \
+ interception_type_test.cpp
libinterception_la_SOURCES = $(interception_files)
diff --git a/libsanitizer/interception/Makefile.in b/libsanitizer/interception/Makefile.in
index 08a33e0..358afe9 100644
--- a/libsanitizer/interception/Makefile.in
+++ b/libsanitizer/interception/Makefile.in
@@ -340,10 +340,10 @@ AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic \
ACLOCAL_AMFLAGS = -I m4
noinst_LTLIBRARIES = libinterception.la
interception_files = \
- interception_linux.cc \
- interception_mac.cc \
- interception_win.cc \
- interception_type_test.cc
+ interception_linux.cpp \
+ interception_mac.cpp \
+ interception_win.cpp \
+ interception_type_test.cpp
libinterception_la_SOURCES = $(interception_files)
@@ -389,7 +389,7 @@ MAKEOVERRIDES =
all: all-am
.SUFFIXES:
-.SUFFIXES: .cc .lo .o .obj
+.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
@@ -445,21 +445,21 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interception_type_test.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interception_win.Plo@am__quote@
-.cc.o:
+.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
-.cc.obj:
+.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-.cc.lo:
+.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
diff --git a/libsanitizer/interception/interception.h b/libsanitizer/interception/interception.h
index 3d43df8..dacfa5e 100644
--- a/libsanitizer/interception/interception.h
+++ b/libsanitizer/interception/interception.h
@@ -1,7 +1,8 @@
//===-- interception.h ------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -184,11 +185,17 @@ const interpose_substitution substitution_##func_name[] \
#endif // SANITIZER_MAC
#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
-#define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) \
+# define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) \
DECLARE_REAL(ret_type, func, __VA_ARGS__) \
extern "C" ret_type WRAP(func)(__VA_ARGS__);
+// Declare an interceptor and its wrapper defined in a different translation
+// unit (ex. asm).
+# define DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(ret_type, func, ...) \
+ extern "C" ret_type WRAP(func)(__VA_ARGS__); \
+ extern "C" ret_type func(__VA_ARGS__);
#else
-#define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...)
+# define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...)
+# define DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(ret_type, func, ...)
#endif
// Generally, you don't need to use DEFINE_REAL by itself, as INTERCEPTOR
diff --git a/libsanitizer/interception/interception_linux.cc b/libsanitizer/interception/interception_linux.cc
deleted file mode 100644
index 781b77e..0000000
--- a/libsanitizer/interception/interception_linux.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-//===-- interception_linux.cc -----------------------------------*- C++ -*-===//
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-// Linux-specific interception methods.
-//===----------------------------------------------------------------------===//
-
-#include "interception.h"
-
-#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
- SANITIZER_OPENBSD || SANITIZER_SOLARIS
-
-#include <dlfcn.h> // for dlsym() and dlvsym()
-
-#if SANITIZER_NETBSD
-#include "sanitizer_common/sanitizer_libc.h"
-#endif
-
-namespace __interception {
-bool GetRealFunctionAddress(const char *func_name, uptr *func_addr,
- uptr real, uptr wrapper) {
-#if SANITIZER_NETBSD
- // XXX: Find a better way to handle renames
- if (internal_strcmp(func_name, "sigaction") == 0) func_name = "__sigaction14";
-#endif
- *func_addr = (uptr)dlsym(RTLD_NEXT, func_name);
- if (!*func_addr) {
- // If the lookup using RTLD_NEXT failed, the sanitizer runtime library is
- // later in the library search order than the DSO that we are trying to
- // intercept, which means that we cannot intercept this function. We still
- // want the address of the real definition, though, so look it up using
- // RTLD_DEFAULT.
- *func_addr = (uptr)dlsym(RTLD_DEFAULT, func_name);
- }
- return real == wrapper;
-}
-
-// Android and Solaris do not have dlvsym
-#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD
-void *GetFuncAddrVer(const char *func_name, const char *ver) {
- return dlvsym(RTLD_NEXT, func_name, ver);
-}
-#endif // !SANITIZER_ANDROID
-
-} // namespace __interception
-
-#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
- // SANITIZER_OPENBSD || SANITIZER_SOLARIS
diff --git a/libsanitizer/interception/interception_linux.cpp b/libsanitizer/interception/interception_linux.cpp
new file mode 100644
index 0000000..950cd51
--- /dev/null
+++ b/libsanitizer/interception/interception_linux.cpp
@@ -0,0 +1,83 @@
+//===-- interception_linux.cpp ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// Linux-specific interception methods.
+//===----------------------------------------------------------------------===//
+
+#include "interception.h"
+
+#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
+ SANITIZER_OPENBSD || SANITIZER_SOLARIS
+
+#include <dlfcn.h> // for dlsym() and dlvsym()
+
+namespace __interception {
+
+#if SANITIZER_NETBSD
+static int StrCmp(const char *s1, const char *s2) {
+ while (true) {
+ if (*s1 != *s2)
+ return false;
+ if (*s1 == 0)
+ return true;
+ s1++;
+ s2++;
+ }
+}
+#endif
+
+static void *GetFuncAddr(const char *name, uptr wrapper_addr) {
+#if SANITIZER_NETBSD
+ // FIXME: Find a better way to handle renames
+ if (StrCmp(name, "sigaction"))
+ name = "__sigaction14";
+#endif
+ void *addr = dlsym(RTLD_NEXT, name);
+ if (!addr) {
+ // If the lookup using RTLD_NEXT failed, the sanitizer runtime library is
+ // later in the library search order than the DSO that we are trying to
+ // intercept, which means that we cannot intercept this function. We still
+ // want the address of the real definition, though, so look it up using
+ // RTLD_DEFAULT.
+ addr = dlsym(RTLD_DEFAULT, name);
+
+ // In case `name' is not loaded, dlsym ends up finding the actual wrapper.
+ // We don't want to intercept the wrapper and have it point to itself.
+ if ((uptr)addr == wrapper_addr)
+ addr = nullptr;
+ }
+ return addr;
+}
+
+bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
+ uptr wrapper) {
+ void *addr = GetFuncAddr(name, wrapper);
+ *ptr_to_real = (uptr)addr;
+ return addr && (func == wrapper);
+}
+
+// Android and Solaris do not have dlvsym
+#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD
+static void *GetFuncAddr(const char *name, const char *ver) {
+ return dlvsym(RTLD_NEXT, name, ver);
+}
+
+bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
+ uptr func, uptr wrapper) {
+ void *addr = GetFuncAddr(name, ver);
+ *ptr_to_real = (uptr)addr;
+ return addr && (func == wrapper);
+}
+#endif // !SANITIZER_ANDROID
+
+} // namespace __interception
+
+#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
+ // SANITIZER_OPENBSD || SANITIZER_SOLARIS
diff --git a/libsanitizer/interception/interception_linux.h b/libsanitizer/interception/interception_linux.h
index 37e6386..e578da0 100644
--- a/libsanitizer/interception/interception_linux.h
+++ b/libsanitizer/interception/interception_linux.h
@@ -1,7 +1,8 @@
//===-- interception_linux.h ------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -21,23 +22,27 @@
#define INTERCEPTION_LINUX_H
namespace __interception {
-// returns true if a function with the given name was found.
-bool GetRealFunctionAddress(const char *func_name, uptr *func_addr,
- uptr real, uptr wrapper);
-void *GetFuncAddrVer(const char *func_name, const char *ver);
+bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func,
+ uptr wrapper);
+bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
+ uptr func, uptr wrapper);
} // namespace __interception
-#define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) \
- ::__interception::GetRealFunctionAddress( \
- #func, (::__interception::uptr *)&__interception::PTR_TO_REAL(func), \
- (::__interception::uptr) & (func), \
+#define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) \
+ ::__interception::InterceptFunction( \
+ #func, \
+ (::__interception::uptr *) & REAL(func), \
+ (::__interception::uptr) & (func), \
(::__interception::uptr) & WRAP(func))
// Android, Solaris and OpenBSD do not have dlvsym
#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD
#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
- (::__interception::real_##func = (func##_type)( \
- unsigned long)::__interception::GetFuncAddrVer(#func, symver))
+ ::__interception::InterceptFunction( \
+ #func, symver, \
+ (::__interception::uptr *) & REAL(func), \
+ (::__interception::uptr) & (func), \
+ (::__interception::uptr) & WRAP(func))
#else
#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
diff --git a/libsanitizer/interception/interception_mac.cc b/libsanitizer/interception/interception_mac.cpp
index 1ffc1af..fb6eadc 100644
--- a/libsanitizer/interception/interception_mac.cc
+++ b/libsanitizer/interception/interception_mac.cpp
@@ -1,7 +1,8 @@
-//===-- interception_mac.cc -------------------------------------*- C++ -*-===//
+//===-- interception_mac.cpp ------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/interception/interception_mac.h b/libsanitizer/interception/interception_mac.h
index c3a3eac..eddedb8 100644
--- a/libsanitizer/interception/interception_mac.h
+++ b/libsanitizer/interception/interception_mac.h
@@ -1,7 +1,8 @@
//===-- interception_mac.h --------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/interception/interception_type_test.cc b/libsanitizer/interception/interception_type_test.cpp
index 726cc7b..a611604 100644
--- a/libsanitizer/interception/interception_type_test.cc
+++ b/libsanitizer/interception/interception_type_test.cpp
@@ -1,7 +1,8 @@
-//===-- interception_type_test.cc -------------------------------*- C++ -*-===//
+//===-- interception_type_test.cpp ------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/interception/interception_win.cc b/libsanitizer/interception/interception_win.cpp
index 74f444d..b94e214 100644
--- a/libsanitizer/interception/interception_win.cc
+++ b/libsanitizer/interception/interception_win.cpp
@@ -1,7 +1,8 @@
-//===-- interception_linux.cc -----------------------------------*- C++ -*-===//
+//===-- interception_linux.cpp ----------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -511,10 +512,12 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0xc0854d: // 4d 85 c0 : test r8, r8
case 0xc2b60f: // 0f b6 c2 : movzx eax, dl
case 0xc03345: // 45 33 c0 : xor r8d, r8d
+ case 0xc93345: // 45 33 c9 : xor r9d, r9d
case 0xdb3345: // 45 33 DB : xor r11d, r11d
case 0xd98b4c: // 4c 8b d9 : mov r11, rcx
case 0xd28b4c: // 4c 8b d2 : mov r10, rdx
case 0xc98b4c: // 4C 8B C9 : mov r9, rcx
+ case 0xc18b4c: // 4C 8B C1 : mov r8, rcx
case 0xd2b60f: // 0f b6 d2 : movzx edx, dl
case 0xca2b48: // 48 2b ca : sub rcx, rdx
case 0x10b70f: // 0f b7 10 : movzx edx, WORD PTR [rax]
@@ -522,6 +525,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0xd18b48: // 48 8b d1 : mov rdx, rcx
case 0xdc8b4c: // 4c 8b dc : mov r11, rsp
case 0xd18b4c: // 4c 8b d1 : mov r10, rcx
+ case 0xE0E483: // 83 E4 E0 : and esp, 0xFFFFFFE0
return 3;
case 0xec8348: // 48 83 ec XX : sub rsp, XX
@@ -553,6 +557,9 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0x245c8948: // 48 89 5c 24 XX : mov QWORD PTR [rsp + XX], rbx
case 0x24748948: // 48 89 74 24 XX : mov QWORD PTR [rsp + XX], rsi
case 0x244C8948: // 48 89 4C 24 XX : mov QWORD PTR [rsp + XX], rcx
+ case 0x24548948: // 48 89 54 24 XX : mov QWORD PTR [rsp + XX], rdx
+ case 0x244c894c: // 4c 89 4c 24 XX : mov QWORD PTR [rsp + XX], r9
+ case 0x2444894c: // 4c 89 44 24 XX : mov QWORD PTR [rsp + XX], r8
return 5;
case 0x24648348: // 48 83 64 24 XX : and QWORD PTR [rsp + XX], YY
return 6;
diff --git a/libsanitizer/interception/interception_win.h b/libsanitizer/interception/interception_win.h
index 3202a0e..45900130 100644
--- a/libsanitizer/interception/interception_win.h
+++ b/libsanitizer/interception/interception_win.h
@@ -1,7 +1,8 @@
//===-- interception_linux.h ------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/lsan/Makefile.am b/libsanitizer/lsan/Makefile.am
index 423ffc2..62ea17d 100644
--- a/libsanitizer/lsan/Makefile.am
+++ b/libsanitizer/lsan/Makefile.am
@@ -17,19 +17,19 @@ nodist_toolexeclib_HEADERS = liblsan_preinit.o
endif
sanitizer_lsan_files = \
- lsan_common.cc \
- lsan_common_linux.cc \
- lsan_common_mac.cc
+ lsan_common.cpp \
+ lsan_common_linux.cpp \
+ lsan_common_mac.cpp
lsan_files = \
$(sanitizer_lsan_files) \
- lsan.cc \
- lsan_linux.cc \
- lsan_mac.cc \
- lsan_malloc_mac.cc \
- lsan_allocator.cc \
- lsan_interceptors.cc \
- lsan_thread.cc
+ lsan.cpp \
+ lsan_linux.cpp \
+ lsan_mac.cpp \
+ lsan_malloc_mac.cpp \
+ lsan_allocator.cpp \
+ lsan_interceptors.cpp \
+ lsan_thread.cpp
libsanitizer_lsan_la_SOURCES = $(sanitizer_lsan_files)
diff --git a/libsanitizer/lsan/Makefile.in b/libsanitizer/lsan/Makefile.in
index a11baed..3ebf4ba 100644
--- a/libsanitizer/lsan/Makefile.in
+++ b/libsanitizer/lsan/Makefile.in
@@ -387,19 +387,19 @@ noinst_LTLIBRARIES = libsanitizer_lsan.la
@LSAN_SUPPORTED_TRUE@toolexeclib_LTLIBRARIES = liblsan.la
@LSAN_SUPPORTED_TRUE@nodist_toolexeclib_HEADERS = liblsan_preinit.o
sanitizer_lsan_files = \
- lsan_common.cc \
- lsan_common_linux.cc \
- lsan_common_mac.cc
+ lsan_common.cpp \
+ lsan_common_linux.cpp \
+ lsan_common_mac.cpp
lsan_files = \
$(sanitizer_lsan_files) \
- lsan.cc \
- lsan_linux.cc \
- lsan_mac.cc \
- lsan_malloc_mac.cc \
- lsan_allocator.cc \
- lsan_interceptors.cc \
- lsan_thread.cc
+ lsan.cpp \
+ lsan_linux.cpp \
+ lsan_mac.cpp \
+ lsan_malloc_mac.cpp \
+ lsan_allocator.cpp \
+ lsan_interceptors.cpp \
+ lsan_thread.cpp
libsanitizer_lsan_la_SOURCES = $(sanitizer_lsan_files)
liblsan_la_SOURCES = $(lsan_files)
@@ -451,7 +451,7 @@ MAKEOVERRIDES =
all: all-am
.SUFFIXES:
-.SUFFIXES: .cc .lo .o .obj
+.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
@@ -551,21 +551,21 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_malloc_mac.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_thread.Plo@am__quote@
-.cc.o:
+.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
-.cc.obj:
+.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-.cc.lo:
+.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
diff --git a/libsanitizer/lsan/lsan.cc b/libsanitizer/lsan/lsan.cpp
index e926110..5b5f619 100644
--- a/libsanitizer/lsan/lsan.cc
+++ b/libsanitizer/lsan/lsan.cpp
@@ -1,7 +1,8 @@
-//=-- lsan.cc -------------------------------------------------------------===//
+//=-- lsan.cpp ------------------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -31,6 +32,24 @@ bool WordIsPoisoned(uptr addr) {
} // namespace __lsan
+void __sanitizer::BufferedStackTrace::UnwindImpl(
+ uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
+ using namespace __lsan;
+ uptr stack_top = 0, stack_bottom = 0;
+ ThreadContext *t;
+ if (StackTrace::WillUseFastUnwind(request_fast) &&
+ (t = CurrentThreadContext())) {
+ stack_top = t->stack_end();
+ stack_bottom = t->stack_begin();
+ }
+ if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
+ if (StackTrace::WillUseFastUnwind(request_fast))
+ Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom, true);
+ else
+ Unwind(max_depth, pc, 0, context, 0, 0, false);
+ }
+}
+
using namespace __lsan; // NOLINT
static void InitializeFlags() {
@@ -57,7 +76,7 @@ static void InitializeFlags() {
// Override from user-specified string.
const char *lsan_default_options = MaybeCallLsanDefaultOptions();
parser.ParseString(lsan_default_options);
- parser.ParseString(GetEnv("LSAN_OPTIONS"));
+ parser.ParseStringFromEnv("LSAN_OPTIONS");
SetVerbosity(common_flags()->verbosity);
@@ -70,7 +89,7 @@ static void InitializeFlags() {
static void OnStackUnwind(const SignalContext &sig, const void *,
BufferedStackTrace *stack) {
- GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context,
+ stack->Unwind(sig.pc, sig.bp, sig.context,
common_flags()->fast_unwind_on_fatal);
}
diff --git a/libsanitizer/lsan/lsan.h b/libsanitizer/lsan/lsan.h
index a40493c..9904ada 100644
--- a/libsanitizer/lsan/lsan.h
+++ b/libsanitizer/lsan/lsan.h
@@ -1,7 +1,8 @@
//=-- lsan.h --------------------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -16,8 +17,8 @@
#define GET_STACK_TRACE(max_size, fast) \
__sanitizer::BufferedStackTrace stack; \
- GetStackTrace(&stack, max_size, StackTrace::GetCurrentPc(), \
- GET_CURRENT_FRAME(), nullptr, fast);
+ stack.Unwind(StackTrace::GetCurrentPc(), \
+ GET_CURRENT_FRAME(), nullptr, fast, max_size);
#define GET_STACK_TRACE_FATAL \
GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_fatal)
@@ -39,24 +40,6 @@ void ReplaceSystemMalloc();
__lsan_init(); \
} while (0)
-// Get the stack trace with the given pc and bp.
-// The pc will be in the position 0 of the resulting stack trace.
-// The bp may refer to the current frame or to the caller's frame.
-ALWAYS_INLINE
-void GetStackTrace(__sanitizer::BufferedStackTrace *stack,
- __sanitizer::uptr max_depth, __sanitizer::uptr pc,
- __sanitizer::uptr bp, void *context, bool fast) {
- uptr stack_top = 0, stack_bottom = 0;
- ThreadContext *t;
- if (fast && (t = CurrentThreadContext())) {
- stack_top = t->stack_end();
- stack_bottom = t->stack_begin();
- }
- if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
- stack->Unwind(max_depth, pc, bp, context, stack_top, stack_bottom, fast);
- }
-}
-
} // namespace __lsan
extern bool lsan_inited;
diff --git a/libsanitizer/lsan/lsan_allocator.cc b/libsanitizer/lsan/lsan_allocator.cpp
index 6b57c50..66a81ab 100644
--- a/libsanitizer/lsan/lsan_allocator.cc
+++ b/libsanitizer/lsan/lsan_allocator.cpp
@@ -1,7 +1,8 @@
-//=-- lsan_allocator.cc ---------------------------------------------------===//
+//=-- lsan_allocator.cpp --------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -32,9 +33,6 @@ static const uptr kMaxAllowedMallocSize = 4UL << 30;
#else
static const uptr kMaxAllowedMallocSize = 8UL << 30;
#endif
-typedef LargeMmapAllocator<> SecondaryAllocator;
-typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
- SecondaryAllocator> Allocator;
static Allocator allocator;
@@ -187,6 +185,17 @@ void *lsan_realloc(void *p, uptr size, const StackTrace &stack) {
return SetErrnoOnNull(Reallocate(stack, p, size, 1));
}
+void *lsan_reallocarray(void *ptr, uptr nmemb, uptr size,
+ const StackTrace &stack) {
+ if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
+ errno = errno_ENOMEM;
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportReallocArrayOverflow(nmemb, size, &stack);
+ }
+ return lsan_realloc(ptr, nmemb * size, stack);
+}
+
void *lsan_calloc(uptr nmemb, uptr size, const StackTrace &stack) {
return SetErrnoOnNull(Calloc(nmemb, size, stack));
}
diff --git a/libsanitizer/lsan/lsan_allocator.h b/libsanitizer/lsan/lsan_allocator.h
index 37260c0..e139709 100644
--- a/libsanitizer/lsan/lsan_allocator.h
+++ b/libsanitizer/lsan/lsan_allocator.h
@@ -1,7 +1,8 @@
//=-- lsan_allocator.h ----------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -50,21 +51,20 @@ struct ChunkMetadata {
#if defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \
defined(__arm__)
-static const uptr kRegionSizeLog = 20;
-static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
-typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
-
+template <typename AddressSpaceViewTy>
struct AP32 {
static const uptr kSpaceBeg = 0;
static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
static const uptr kMetadataSize = sizeof(ChunkMetadata);
typedef __sanitizer::CompactSizeClassMap SizeClassMap;
- static const uptr kRegionSizeLog = __lsan::kRegionSizeLog;
- typedef __lsan::ByteMap ByteMap;
+ static const uptr kRegionSizeLog = 20;
+ using AddressSpaceView = AddressSpaceViewTy;
typedef NoOpMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
};
-typedef SizeClassAllocator32<AP32> PrimaryAllocator;
+template <typename AddressSpaceView>
+using PrimaryAllocatorASVT = SizeClassAllocator32<AP32<AddressSpaceView>>;
+using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
#elif defined(__x86_64__) || defined(__powerpc64__)
# if defined(__powerpc64__)
const uptr kAllocatorSpace = 0xa0000000000ULL;
@@ -73,6 +73,7 @@ const uptr kAllocatorSize = 0x20000000000ULL; // 2T.
const uptr kAllocatorSpace = 0x600000000000ULL;
const uptr kAllocatorSize = 0x40000000000ULL; // 4T.
# endif
+template <typename AddressSpaceViewTy>
struct AP64 { // Allocator64 parameters. Deliberately using a short name.
static const uptr kSpaceBeg = kAllocatorSpace;
static const uptr kSpaceSize = kAllocatorSize;
@@ -80,13 +81,20 @@ struct AP64 { // Allocator64 parameters. Deliberately using a short name.
typedef DefaultSizeClassMap SizeClassMap;
typedef NoOpMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
+ using AddressSpaceView = AddressSpaceViewTy;
};
-typedef SizeClassAllocator64<AP64> PrimaryAllocator;
+template <typename AddressSpaceView>
+using PrimaryAllocatorASVT = SizeClassAllocator64<AP64<AddressSpaceView>>;
+using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
#endif
-typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
-AllocatorCache *GetAllocatorCache();
+template <typename AddressSpaceView>
+using AllocatorASVT = CombinedAllocator<PrimaryAllocatorASVT<AddressSpaceView>>;
+using Allocator = AllocatorASVT<LocalAddressSpaceView>;
+using AllocatorCache = Allocator::AllocatorCache;
+
+Allocator::AllocatorCache *GetAllocatorCache();
int lsan_posix_memalign(void **memptr, uptr alignment, uptr size,
const StackTrace &stack);
@@ -95,6 +103,8 @@ void *lsan_memalign(uptr alignment, uptr size, const StackTrace &stack);
void *lsan_malloc(uptr size, const StackTrace &stack);
void lsan_free(void *p);
void *lsan_realloc(void *p, uptr size, const StackTrace &stack);
+void *lsan_reallocarray(void *p, uptr nmemb, uptr size,
+ const StackTrace &stack);
void *lsan_calloc(uptr nmemb, uptr size, const StackTrace &stack);
void *lsan_valloc(uptr size, const StackTrace &stack);
void *lsan_pvalloc(uptr size, const StackTrace &stack);
diff --git a/libsanitizer/lsan/lsan_common.cc b/libsanitizer/lsan/lsan_common.cpp
index a4424a8..c39fab9 100644
--- a/libsanitizer/lsan/lsan_common.cc
+++ b/libsanitizer/lsan/lsan_common.cpp
@@ -1,7 +1,8 @@
-//=-- lsan_common.cc ------------------------------------------------------===//
+//=-- lsan_common.cpp -----------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/lsan/lsan_common.h b/libsanitizer/lsan/lsan_common.h
index b82474a..58dc00f 100644
--- a/libsanitizer/lsan/lsan_common.h
+++ b/libsanitizer/lsan/lsan_common.h
@@ -1,7 +1,8 @@
//=-- lsan_common.h -------------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -20,8 +21,8 @@
#include "sanitizer_common/sanitizer_stoptheworld.h"
#include "sanitizer_common/sanitizer_symbolizer.h"
-// LeakSanitizer relies on some Glibc's internals (e.g. TLS machinery) thus
-// supported for Linux only. Also, LSan doesn't like 32 bit architectures
+// LeakSanitizer relies on some Glibc's internals (e.g. TLS machinery) on Linux.
+// Also, LSan doesn't like 32 bit architectures
// because of "small" (4 bytes) pointer size that leads to high false negative
// ratio on large leaks. But we still want to have it for some 32 bit arches
// (e.g. x86), see https://github.com/google/sanitizers/issues/403.
@@ -39,6 +40,8 @@
#elif defined(__arm__) && \
SANITIZER_LINUX && !SANITIZER_ANDROID
#define CAN_SANITIZE_LEAKS 1
+#elif SANITIZER_NETBSD
+#define CAN_SANITIZE_LEAKS 1
#else
#define CAN_SANITIZE_LEAKS 0
#endif
diff --git a/libsanitizer/lsan/lsan_common_linux.cc b/libsanitizer/lsan/lsan_common_linux.cpp
index cffbfc9..9ce27a9 100644
--- a/libsanitizer/lsan/lsan_common_linux.cc
+++ b/libsanitizer/lsan/lsan_common_linux.cpp
@@ -1,19 +1,21 @@
-//=-- lsan_common_linux.cc ------------------------------------------------===//
+//=-- lsan_common_linux.cpp -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of LeakSanitizer.
-// Implementation of common leak checking functionality. Linux-specific code.
+// Implementation of common leak checking functionality. Linux/NetBSD-specific
+// code.
//
//===----------------------------------------------------------------------===//
#include "sanitizer_common/sanitizer_platform.h"
#include "lsan_common.h"
-#if CAN_SANITIZE_LEAKS && SANITIZER_LINUX
+#if CAN_SANITIZE_LEAKS && (SANITIZER_LINUX || SANITIZER_NETBSD)
#include <link.h>
#include "sanitizer_common/sanitizer_common.h"
@@ -135,4 +137,4 @@ void DoStopTheWorld(StopTheWorldCallback callback, void *argument) {
} // namespace __lsan
-#endif // CAN_SANITIZE_LEAKS && SANITIZER_LINUX
+#endif
diff --git a/libsanitizer/lsan/lsan_common_mac.cc b/libsanitizer/lsan/lsan_common_mac.cpp
index 8337cd2..5204a66 100644
--- a/libsanitizer/lsan/lsan_common_mac.cc
+++ b/libsanitizer/lsan/lsan_common_mac.cpp
@@ -1,7 +1,8 @@
-//=-- lsan_common_mac.cc --------------------------------------------------===//
+//=-- lsan_common_mac.cpp -------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -11,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "sanitizer_common/sanitizer_platform.h"
+#include "sanitizer_common/sanitizer_libc.h"
#include "lsan_common.h"
#if CAN_SANITIZE_LEAKS && SANITIZER_MAC
@@ -114,7 +116,8 @@ static const char *kSkippedSecNames[] = {
// Scans global variables for heap pointers.
void ProcessGlobalRegions(Frontier *frontier) {
- for (auto name : kSkippedSecNames) CHECK(ARRAY_SIZE(name) < kMaxSegName);
+ for (auto name : kSkippedSecNames)
+ CHECK(internal_strnlen(name, kMaxSegName + 1) <= kMaxSegName);
MemoryMappingLayout memory_mapping(false);
InternalMmapVector<LoadedModule> modules;
diff --git a/libsanitizer/lsan/lsan_flags.inc b/libsanitizer/lsan/lsan_flags.inc
index 9861125..9350f4b 100644
--- a/libsanitizer/lsan/lsan_flags.inc
+++ b/libsanitizer/lsan/lsan_flags.inc
@@ -1,7 +1,8 @@
//===-- lsan_flags.inc ------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/lsan/lsan_interceptors.cc b/libsanitizer/lsan/lsan_interceptors.cpp
index 7c594e5..f06d5ff 100644
--- a/libsanitizer/lsan/lsan_interceptors.cc
+++ b/libsanitizer/lsan/lsan_interceptors.cpp
@@ -1,7 +1,8 @@
-//=-- lsan_interceptors.cc ------------------------------------------------===//
+//=-- lsan_interceptors.cpp -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -82,6 +83,12 @@ INTERCEPTOR(void*, realloc, void *q, uptr size) {
return lsan_realloc(q, size, stack);
}
+INTERCEPTOR(void*, reallocarray, void *q, uptr nmemb, uptr size) {
+ ENSURE_LSAN_INITED;
+ GET_STACK_TRACE_MALLOC;
+ return lsan_reallocarray(q, nmemb, size, stack);
+}
+
INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {
ENSURE_LSAN_INITED;
GET_STACK_TRACE_MALLOC;
@@ -151,7 +158,7 @@ INTERCEPTOR(struct fake_mallinfo, mallinfo, void) {
#define LSAN_MAYBE_INTERCEPT_MALLINFO INTERCEPT_FUNCTION(mallinfo)
INTERCEPTOR(int, mallopt, int cmd, int value) {
- return -1;
+ return 0;
}
#define LSAN_MAYBE_INTERCEPT_MALLOPT INTERCEPT_FUNCTION(mallopt)
#else
diff --git a/libsanitizer/lsan/lsan_linux.cc b/libsanitizer/lsan/lsan_linux.cpp
index aa6445a..14a42b7 100644
--- a/libsanitizer/lsan/lsan_linux.cc
+++ b/libsanitizer/lsan/lsan_linux.cpp
@@ -1,17 +1,18 @@
-//=-- lsan_linux.cc -------------------------------------------------------===//
+//=-- lsan_linux.cpp ------------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
-// This file is a part of LeakSanitizer. Linux-specific code.
+// This file is a part of LeakSanitizer. Linux/NetBSD-specific code.
//
//===----------------------------------------------------------------------===//
#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_LINUX
+#if SANITIZER_LINUX || SANITIZER_NETBSD
#include "lsan_allocator.h"
@@ -28,4 +29,4 @@ void ReplaceSystemMalloc() {}
} // namespace __lsan
-#endif // SANITIZER_LINUX
+#endif // SANITIZER_LINUX || SANITIZER_NETBSD
diff --git a/libsanitizer/lsan/lsan_mac.cc b/libsanitizer/lsan/lsan_mac.cpp
index ca38c1c..7bcd9c8 100644
--- a/libsanitizer/lsan/lsan_mac.cc
+++ b/libsanitizer/lsan/lsan_mac.cpp
@@ -1,7 +1,8 @@
-//===-- lsan_mac.cc -------------------------------------------------------===//
+//===-- lsan_mac.cpp ------------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/lsan/lsan_malloc_mac.cc b/libsanitizer/lsan/lsan_malloc_mac.cpp
index 2458b50..d03eb2e 100644
--- a/libsanitizer/lsan/lsan_malloc_mac.cc
+++ b/libsanitizer/lsan/lsan_malloc_mac.cpp
@@ -1,7 +1,8 @@
-//===-- lsan_malloc_mac.cc ------------------------------------------------===//
+//===-- lsan_malloc_mac.cpp -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -50,6 +51,8 @@ using namespace __lsan;
(void)zone_name; \
Report("mz_realloc(%p) -- attempting to realloc unallocated memory.\n", ptr);
#define COMMON_MALLOC_NAMESPACE __lsan
+#define COMMON_MALLOC_HAS_ZONE_ENUMERATOR 0
+#define COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT 0
#include "sanitizer_common/sanitizer_malloc_mac.inc"
diff --git a/libsanitizer/lsan/lsan_preinit.cc b/libsanitizer/lsan/lsan_preinit.cpp
index d1efd31..cd94e1e 100644
--- a/libsanitizer/lsan/lsan_preinit.cc
+++ b/libsanitizer/lsan/lsan_preinit.cpp
@@ -1,7 +1,8 @@
-//===-- lsan_preinit.cc ---------------------------------------------------===//
+//===-- lsan_preinit.cpp --------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/lsan/lsan_thread.cc b/libsanitizer/lsan/lsan_thread.cpp
index 388990b..84e7ce6 100644
--- a/libsanitizer/lsan/lsan_thread.cc
+++ b/libsanitizer/lsan/lsan_thread.cpp
@@ -1,7 +1,8 @@
-//=-- lsan_thread.cc ------------------------------------------------------===//
+//=-- lsan_thread.cpp -----------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -75,7 +76,7 @@ u32 ThreadCreate(u32 parent_tid, uptr user_id, bool detached) {
/* arg */ nullptr);
}
-void ThreadStart(u32 tid, tid_t os_id, bool workerthread) {
+void ThreadStart(u32 tid, tid_t os_id, ThreadType thread_type) {
OnStartedArgs args;
uptr stack_size = 0;
uptr tls_size = 0;
@@ -85,7 +86,7 @@ void ThreadStart(u32 tid, tid_t os_id, bool workerthread) {
args.tls_end = args.tls_begin + tls_size;
GetAllocatorCacheRange(&args.cache_begin, &args.cache_end);
args.dtls = DTLS_Get();
- thread_registry->StartThread(tid, os_id, workerthread, &args);
+ thread_registry->StartThread(tid, os_id, thread_type, &args);
}
void ThreadFinish() {
diff --git a/libsanitizer/lsan/lsan_thread.h b/libsanitizer/lsan/lsan_thread.h
index 8675834..b869d06 100644
--- a/libsanitizer/lsan/lsan_thread.h
+++ b/libsanitizer/lsan/lsan_thread.h
@@ -1,7 +1,8 @@
//=-- lsan_thread.h -------------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -43,7 +44,8 @@ class ThreadContext : public ThreadContextBase {
void InitializeThreadRegistry();
-void ThreadStart(u32 tid, tid_t os_id, bool workerthread = false);
+void ThreadStart(u32 tid, tid_t os_id,
+ ThreadType thread_type = ThreadType::Regular);
void ThreadFinish();
u32 ThreadCreate(u32 tid, uptr uid, bool detached);
void ThreadJoin(u32 tid);
diff --git a/libsanitizer/merge.sh b/libsanitizer/merge.sh
index fa340be..168fbbc 100755
--- a/libsanitizer/merge.sh
+++ b/libsanitizer/merge.sh
@@ -18,7 +18,7 @@ get_current_rev() {
}
list_files() {
- (cd $1; ls *.{cc,h,inc,S} 2> /dev/null)
+ (cd $1; ls *.{cc,cpp,h,inc,S} 2> /dev/null)
}
@@ -74,6 +74,7 @@ merge lib/tsan/rtl tsan
merge lib/sanitizer_common sanitizer_common
merge lib/interception interception
merge lib/ubsan ubsan
+merge lib/BlocksRuntime/ BlocksRuntime
# Need to merge lib/builtins/assembly.h file:
mkdir -p builtins
diff --git a/libsanitizer/sanitizer_common/Makefile.am b/libsanitizer/sanitizer_common/Makefile.am
index b04e755..df9c294 100644
--- a/libsanitizer/sanitizer_common/Makefile.am
+++ b/libsanitizer/sanitizer_common/Makefile.am
@@ -1,4 +1,4 @@
-AM_CPPFLAGS = -I $(top_srcdir)/include -isystem $(top_srcdir)/include/system
+AM_CPPFLAGS = -I $(top_srcdir)/include -I $(top_srcdir) -isystem $(top_srcdir)/include/system
# May be used by toolexeclibdir.
gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
@@ -21,68 +21,67 @@ ACLOCAL_AMFLAGS = -I m4
noinst_LTLIBRARIES = libsanitizer_common.la
sanitizer_common_files = \
- sancov_flags.cc \
- sanitizer_allocator.cc \
- sanitizer_allocator_checks.cc \
- sanitizer_allocator_report.cc \
- sanitizer_common.cc \
- sanitizer_common_libcdep.cc \
- sanitizer_coverage_libcdep_new.cc \
- sanitizer_deadlock_detector1.cc \
- sanitizer_deadlock_detector2.cc \
- sanitizer_errno.cc \
- sanitizer_file.cc \
- sanitizer_flags.cc \
- sanitizer_flag_parser.cc \
- sanitizer_libc.cc \
- sanitizer_libignore.cc \
- sanitizer_linux.cc \
- sanitizer_linux_libcdep.cc \
- sanitizer_linux_s390.cc \
- sanitizer_mac.cc \
- sanitizer_mac_libcdep.cc \
- sanitizer_netbsd.cc \
- sanitizer_openbsd.cc \
- sanitizer_persistent_allocator.cc \
- sanitizer_platform_limits_linux.cc \
- sanitizer_platform_limits_openbsd.cc \
- sanitizer_platform_limits_posix.cc \
- sanitizer_platform_limits_solaris.cc \
- sanitizer_posix.cc \
- sanitizer_posix_libcdep.cc \
- sanitizer_printf.cc \
- sanitizer_procmaps_bsd.cc \
- sanitizer_procmaps_common.cc \
- sanitizer_procmaps_linux.cc \
- sanitizer_procmaps_mac.cc \
- sanitizer_procmaps_solaris.cc \
- sanitizer_rtems.cc \
- sanitizer_solaris.cc \
- sanitizer_stackdepot.cc \
- sanitizer_stacktrace.cc \
- sanitizer_stacktrace_libcdep.cc \
- sanitizer_stacktrace_sparc.cc \
- sanitizer_symbolizer_mac.cc \
- sanitizer_symbolizer_report.cc \
- sanitizer_stacktrace_printer.cc \
- sanitizer_stoptheworld_linux_libcdep.cc \
- sanitizer_stoptheworld_mac.cc \
- sanitizer_suppressions.cc \
- sanitizer_symbolizer.cc \
- sanitizer_symbolizer_libbacktrace.cc \
- sanitizer_symbolizer_libcdep.cc \
- sanitizer_symbolizer_posix_libcdep.cc \
- sanitizer_symbolizer_win.cc \
- sanitizer_termination.cc \
- sanitizer_thread_registry.cc \
- sanitizer_tls_get_addr.cc \
- sanitizer_unwind_linux_libcdep.cc \
- sanitizer_unwind_win.cc \
- sanitizer_win.cc
+ sancov_flags.cpp \
+ sanitizer_allocator.cpp \
+ sanitizer_allocator_checks.cpp \
+ sanitizer_allocator_report.cpp \
+ sanitizer_common.cpp \
+ sanitizer_common_libcdep.cpp \
+ sanitizer_coverage_libcdep_new.cpp \
+ sanitizer_deadlock_detector1.cpp \
+ sanitizer_deadlock_detector2.cpp \
+ sanitizer_errno.cpp \
+ sanitizer_file.cpp \
+ sanitizer_flags.cpp \
+ sanitizer_flag_parser.cpp \
+ sanitizer_libc.cpp \
+ sanitizer_libignore.cpp \
+ sanitizer_linux.cpp \
+ sanitizer_linux_libcdep.cpp \
+ sanitizer_linux_s390.cpp \
+ sanitizer_mac.cpp \
+ sanitizer_mac_libcdep.cpp \
+ sanitizer_netbsd.cpp \
+ sanitizer_openbsd.cpp \
+ sanitizer_persistent_allocator.cpp \
+ sanitizer_platform_limits_linux.cpp \
+ sanitizer_platform_limits_openbsd.cpp \
+ sanitizer_platform_limits_posix.cpp \
+ sanitizer_platform_limits_solaris.cpp \
+ sanitizer_posix.cpp \
+ sanitizer_posix_libcdep.cpp \
+ sanitizer_printf.cpp \
+ sanitizer_procmaps_bsd.cpp \
+ sanitizer_procmaps_common.cpp \
+ sanitizer_procmaps_linux.cpp \
+ sanitizer_procmaps_mac.cpp \
+ sanitizer_procmaps_solaris.cpp \
+ sanitizer_rtems.cpp \
+ sanitizer_solaris.cpp \
+ sanitizer_stackdepot.cpp \
+ sanitizer_stacktrace.cpp \
+ sanitizer_stacktrace_libcdep.cpp \
+ sanitizer_stacktrace_sparc.cpp \
+ sanitizer_symbolizer_mac.cpp \
+ sanitizer_symbolizer_report.cpp \
+ sanitizer_stacktrace_printer.cpp \
+ sanitizer_stoptheworld_linux_libcdep.cpp \
+ sanitizer_stoptheworld_mac.cpp \
+ sanitizer_suppressions.cpp \
+ sanitizer_symbolizer.cpp \
+ sanitizer_symbolizer_libbacktrace.cpp \
+ sanitizer_symbolizer_libcdep.cpp \
+ sanitizer_symbolizer_posix_libcdep.cpp \
+ sanitizer_symbolizer_win.cpp \
+ sanitizer_termination.cpp \
+ sanitizer_thread_registry.cpp \
+ sanitizer_tls_get_addr.cpp \
+ sanitizer_unwind_linux_libcdep.cpp \
+ sanitizer_unwind_win.cpp \
+ sanitizer_win.cpp
libsanitizer_common_la_SOURCES = $(sanitizer_common_files)
-EXTRA_libsanitizer_common_la_SOURCES = sanitizer_linux_mips64.S sanitizer_linux_x86_64.S
libsanitizer_common_la_LIBADD = $(SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS)
libsanitizer_common_la_DEPENDENCIES = $(SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS)
diff --git a/libsanitizer/sanitizer_common/Makefile.in b/libsanitizer/sanitizer_common/Makefile.in
index d33d222..0fcebc8 100644
--- a/libsanitizer/sanitizer_common/Makefile.in
+++ b/libsanitizer/sanitizer_common/Makefile.in
@@ -172,16 +172,6 @@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/../depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
-CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
-LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \
- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
- $(AM_CCASFLAGS) $(CCASFLAGS)
-AM_V_CPPAS = $(am__v_CPPAS_@AM_V@)
-am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@)
-am__v_CPPAS_0 = @echo " CPPAS " $@;
-am__v_CPPAS_1 =
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
@@ -200,26 +190,7 @@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
- $(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_@AM_V@)
-am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
-am__v_CC_0 = @echo " CC " $@;
-am__v_CC_1 =
-CCLD = $(CC)
-LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CCLD = $(am__v_CCLD_@AM_V@)
-am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
-am__v_CCLD_0 = @echo " CCLD " $@;
-am__v_CCLD_1 =
-SOURCES = $(libsanitizer_common_la_SOURCES) \
- $(EXTRA_libsanitizer_common_la_SOURCES)
+SOURCES = $(libsanitizer_common_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -393,7 +364,7 @@ toolexeclibdir = @toolexeclibdir@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-AM_CPPFLAGS = -I $(top_srcdir)/include -isystem $(top_srcdir)/include/system
+AM_CPPFLAGS = -I $(top_srcdir)/include -I $(top_srcdir) -isystem $(top_srcdir)/include/system
# May be used by toolexeclibdir.
gcc_version := $(shell @get_gcc_base_ver@ $(top_srcdir)/../gcc/BASE-VER)
@@ -406,67 +377,66 @@ AM_CCASFLAGS = $(EXTRA_ASFLAGS)
ACLOCAL_AMFLAGS = -I m4
noinst_LTLIBRARIES = libsanitizer_common.la
sanitizer_common_files = \
- sancov_flags.cc \
- sanitizer_allocator.cc \
- sanitizer_allocator_checks.cc \
- sanitizer_allocator_report.cc \
- sanitizer_common.cc \
- sanitizer_common_libcdep.cc \
- sanitizer_coverage_libcdep_new.cc \
- sanitizer_deadlock_detector1.cc \
- sanitizer_deadlock_detector2.cc \
- sanitizer_errno.cc \
- sanitizer_file.cc \
- sanitizer_flags.cc \
- sanitizer_flag_parser.cc \
- sanitizer_libc.cc \
- sanitizer_libignore.cc \
- sanitizer_linux.cc \
- sanitizer_linux_libcdep.cc \
- sanitizer_linux_s390.cc \
- sanitizer_mac.cc \
- sanitizer_mac_libcdep.cc \
- sanitizer_netbsd.cc \
- sanitizer_openbsd.cc \
- sanitizer_persistent_allocator.cc \
- sanitizer_platform_limits_linux.cc \
- sanitizer_platform_limits_openbsd.cc \
- sanitizer_platform_limits_posix.cc \
- sanitizer_platform_limits_solaris.cc \
- sanitizer_posix.cc \
- sanitizer_posix_libcdep.cc \
- sanitizer_printf.cc \
- sanitizer_procmaps_bsd.cc \
- sanitizer_procmaps_common.cc \
- sanitizer_procmaps_linux.cc \
- sanitizer_procmaps_mac.cc \
- sanitizer_procmaps_solaris.cc \
- sanitizer_rtems.cc \
- sanitizer_solaris.cc \
- sanitizer_stackdepot.cc \
- sanitizer_stacktrace.cc \
- sanitizer_stacktrace_libcdep.cc \
- sanitizer_stacktrace_sparc.cc \
- sanitizer_symbolizer_mac.cc \
- sanitizer_symbolizer_report.cc \
- sanitizer_stacktrace_printer.cc \
- sanitizer_stoptheworld_linux_libcdep.cc \
- sanitizer_stoptheworld_mac.cc \
- sanitizer_suppressions.cc \
- sanitizer_symbolizer.cc \
- sanitizer_symbolizer_libbacktrace.cc \
- sanitizer_symbolizer_libcdep.cc \
- sanitizer_symbolizer_posix_libcdep.cc \
- sanitizer_symbolizer_win.cc \
- sanitizer_termination.cc \
- sanitizer_thread_registry.cc \
- sanitizer_tls_get_addr.cc \
- sanitizer_unwind_linux_libcdep.cc \
- sanitizer_unwind_win.cc \
- sanitizer_win.cc
+ sancov_flags.cpp \
+ sanitizer_allocator.cpp \
+ sanitizer_allocator_checks.cpp \
+ sanitizer_allocator_report.cpp \
+ sanitizer_common.cpp \
+ sanitizer_common_libcdep.cpp \
+ sanitizer_coverage_libcdep_new.cpp \
+ sanitizer_deadlock_detector1.cpp \
+ sanitizer_deadlock_detector2.cpp \
+ sanitizer_errno.cpp \
+ sanitizer_file.cpp \
+ sanitizer_flags.cpp \
+ sanitizer_flag_parser.cpp \
+ sanitizer_libc.cpp \
+ sanitizer_libignore.cpp \
+ sanitizer_linux.cpp \
+ sanitizer_linux_libcdep.cpp \
+ sanitizer_linux_s390.cpp \
+ sanitizer_mac.cpp \
+ sanitizer_mac_libcdep.cpp \
+ sanitizer_netbsd.cpp \
+ sanitizer_openbsd.cpp \
+ sanitizer_persistent_allocator.cpp \
+ sanitizer_platform_limits_linux.cpp \
+ sanitizer_platform_limits_openbsd.cpp \
+ sanitizer_platform_limits_posix.cpp \
+ sanitizer_platform_limits_solaris.cpp \
+ sanitizer_posix.cpp \
+ sanitizer_posix_libcdep.cpp \
+ sanitizer_printf.cpp \
+ sanitizer_procmaps_bsd.cpp \
+ sanitizer_procmaps_common.cpp \
+ sanitizer_procmaps_linux.cpp \
+ sanitizer_procmaps_mac.cpp \
+ sanitizer_procmaps_solaris.cpp \
+ sanitizer_rtems.cpp \
+ sanitizer_solaris.cpp \
+ sanitizer_stackdepot.cpp \
+ sanitizer_stacktrace.cpp \
+ sanitizer_stacktrace_libcdep.cpp \
+ sanitizer_stacktrace_sparc.cpp \
+ sanitizer_symbolizer_mac.cpp \
+ sanitizer_symbolizer_report.cpp \
+ sanitizer_stacktrace_printer.cpp \
+ sanitizer_stoptheworld_linux_libcdep.cpp \
+ sanitizer_stoptheworld_mac.cpp \
+ sanitizer_suppressions.cpp \
+ sanitizer_symbolizer.cpp \
+ sanitizer_symbolizer_libbacktrace.cpp \
+ sanitizer_symbolizer_libcdep.cpp \
+ sanitizer_symbolizer_posix_libcdep.cpp \
+ sanitizer_symbolizer_win.cpp \
+ sanitizer_termination.cpp \
+ sanitizer_thread_registry.cpp \
+ sanitizer_tls_get_addr.cpp \
+ sanitizer_unwind_linux_libcdep.cpp \
+ sanitizer_unwind_win.cpp \
+ sanitizer_win.cpp
libsanitizer_common_la_SOURCES = $(sanitizer_common_files)
-EXTRA_libsanitizer_common_la_SOURCES = sanitizer_linux_mips64.S sanitizer_linux_x86_64.S
libsanitizer_common_la_LIBADD = $(SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS)
libsanitizer_common_la_DEPENDENCIES = $(SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS)
@@ -512,7 +482,7 @@ MAKEOVERRIDES =
all: all-am
.SUFFIXES:
-.SUFFIXES: .S .cc .lo .o .obj
+.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
@@ -580,9 +550,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_libignore.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux_libcdep.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux_mips64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux_s390.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux_x86_64.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_mac.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_mac_libcdep.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_netbsd.Plo@am__quote@
@@ -624,42 +592,21 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_unwind_win.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_win.Plo@am__quote@
-.S.o:
-@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $<
-
-.S.obj:
-@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-
-.S.lo:
-@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $<
-
-.cc.o:
+.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
-.cc.obj:
+.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-.cc.lo:
+.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
diff --git a/libsanitizer/sanitizer_common/sancov_begin.S b/libsanitizer/sanitizer_common/sancov_begin.S
deleted file mode 100644
index c8ad0a0..0000000
--- a/libsanitizer/sanitizer_common/sancov_begin.S
+++ /dev/null
@@ -1,5 +0,0 @@
- .type __start___sancov_guards,@object
- .globl __start___sancov_guards
- .section __sancov_guards,"aw",@progbits
- .p2align 2
-__start___sancov_guards:
diff --git a/libsanitizer/sanitizer_common/sancov_end.S b/libsanitizer/sanitizer_common/sancov_end.S
deleted file mode 100644
index 31117b1..0000000
--- a/libsanitizer/sanitizer_common/sancov_end.S
+++ /dev/null
@@ -1,5 +0,0 @@
- .type __stop___sancov_guards,@object
- .globl __stop___sancov_guards
- .section __sancov_guards,"aw",@progbits
- .p2align 2
-__stop___sancov_guards:
diff --git a/libsanitizer/sanitizer_common/sancov_flags.cc b/libsanitizer/sanitizer_common/sancov_flags.cpp
index e600cda..ed46e88 100644
--- a/libsanitizer/sanitizer_common/sancov_flags.cc
+++ b/libsanitizer/sanitizer_common/sancov_flags.cpp
@@ -1,7 +1,8 @@
-//===-- sancov_flags.cc -----------------------------------------*- C++ -*-===//
+//===-- sancov_flags.cpp ----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -48,7 +49,7 @@ void InitializeSancovFlags() {
RegisterSancovFlags(&parser, f);
parser.ParseString(MaybeCallSancovDefaultOptions());
- parser.ParseString(GetEnv("SANCOV_OPTIONS"));
+ parser.ParseStringFromEnv("SANCOV_OPTIONS");
ReportUnrecognizedFlags();
if (f->help) parser.PrintFlagDescriptions();
diff --git a/libsanitizer/sanitizer_common/sancov_flags.h b/libsanitizer/sanitizer_common/sancov_flags.h
index f7e0186..95d4ee5 100644
--- a/libsanitizer/sanitizer_common/sancov_flags.h
+++ b/libsanitizer/sanitizer_common/sancov_flags.h
@@ -1,7 +1,8 @@
//===-- sancov_flags.h ------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sancov_flags.inc b/libsanitizer/sanitizer_common/sancov_flags.inc
index a6107cc..cca33fc 100644
--- a/libsanitizer/sanitizer_common/sancov_flags.inc
+++ b/libsanitizer/sanitizer_common/sancov_flags.inc
@@ -1,7 +1,8 @@
//===-- sancov_flags.inc ----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_addrhashmap.h b/libsanitizer/sanitizer_common/sanitizer_addrhashmap.h
index a67ec84..a033e78 100644
--- a/libsanitizer/sanitizer_common/sanitizer_addrhashmap.h
+++ b/libsanitizer/sanitizer_common/sanitizer_addrhashmap.h
@@ -1,7 +1,8 @@
//===-- sanitizer_addrhashmap.h ---------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator.cc b/libsanitizer/sanitizer_common/sanitizer_allocator.cpp
index 2fd6e8a..8d07906 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_allocator.cc --------------------------------------------===//
+//===-- sanitizer_allocator.cpp -------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -169,6 +170,18 @@ void *InternalRealloc(void *addr, uptr size, InternalAllocatorCache *cache) {
return (char*)p + sizeof(u64);
}
+void *InternalReallocArray(void *addr, uptr count, uptr size,
+ InternalAllocatorCache *cache) {
+ if (UNLIKELY(CheckForCallocOverflow(count, size))) {
+ Report(
+ "FATAL: %s: reallocarray parameters overflow: count * size (%zd * %zd) "
+ "cannot be represented in type size_t\n",
+ SanitizerToolName, count, size);
+ Die();
+ }
+ return InternalRealloc(addr, count * size, cache);
+}
+
void *InternalCalloc(uptr count, uptr size, InternalAllocatorCache *cache) {
if (UNLIKELY(CheckForCallocOverflow(count, size))) {
Report("FATAL: %s: calloc parameters overflow: count * size (%zd * %zd) "
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator.h b/libsanitizer/sanitizer_common/sanitizer_allocator.h
index 7dbb9f7..23d5898 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator.h
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator.h
@@ -1,7 +1,8 @@
//===-- sanitizer_allocator.h -----------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -12,13 +13,15 @@
#ifndef SANITIZER_ALLOCATOR_H
#define SANITIZER_ALLOCATOR_H
-#include "sanitizer_internal_defs.h"
#include "sanitizer_common.h"
+#include "sanitizer_internal_defs.h"
+#include "sanitizer_lfstack.h"
#include "sanitizer_libc.h"
#include "sanitizer_list.h"
+#include "sanitizer_local_address_space_view.h"
#include "sanitizer_mutex.h"
-#include "sanitizer_lfstack.h"
#include "sanitizer_procmaps.h"
+#include "sanitizer_type_traits.h"
namespace __sanitizer {
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_bytemap.h b/libsanitizer/sanitizer_common/sanitizer_allocator_bytemap.h
index 3a3f222..0084bb6 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_bytemap.h
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_bytemap.h
@@ -1,7 +1,8 @@
//===-- sanitizer_allocator_bytemap.h ---------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -13,9 +14,10 @@
#endif
// Maps integers in rage [0, kSize) to u8 values.
-template<u64 kSize>
+template <u64 kSize, typename AddressSpaceViewTy = LocalAddressSpaceView>
class FlatByteMap {
public:
+ using AddressSpaceView = AddressSpaceViewTy;
void Init() {
internal_memset(map_, 0, sizeof(map_));
}
@@ -39,9 +41,12 @@ class FlatByteMap {
// to kSize2-byte arrays. The secondary arrays are mmaped on demand.
// Each value is initially zero and can be set to something else only once.
// Setting and getting values from multiple threads is safe w/o extra locking.
-template <u64 kSize1, u64 kSize2, class MapUnmapCallback = NoOpMapUnmapCallback>
+template <u64 kSize1, u64 kSize2,
+ typename AddressSpaceViewTy = LocalAddressSpaceView,
+ class MapUnmapCallback = NoOpMapUnmapCallback>
class TwoLevelByteMap {
public:
+ using AddressSpaceView = AddressSpaceViewTy;
void Init() {
internal_memset(map1_, 0, sizeof(map1_));
mu_.Init();
@@ -71,7 +76,8 @@ class TwoLevelByteMap {
CHECK_LT(idx, kSize1 * kSize2);
u8 *map2 = Get(idx / kSize2);
if (!map2) return 0;
- return map2[idx % kSize2];
+ auto value_ptr = AddressSpaceView::Load(&map2[idx % kSize2]);
+ return *value_ptr;
}
private:
@@ -98,3 +104,4 @@ class TwoLevelByteMap {
atomic_uintptr_t map1_[kSize1];
StaticSpinMutex mu_;
};
+
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_checks.cc b/libsanitizer/sanitizer_common/sanitizer_allocator_checks.cpp
index 3e6eb61..9d67f67 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_checks.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_checks.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_allocator_checks.cc ---------------------------*- C++ -*-===//
+//===-- sanitizer_allocator_checks.cpp --------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_checks.h b/libsanitizer/sanitizer_common/sanitizer_allocator_checks.h
index 9056ed5..f436ce9 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_checks.h
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_checks.h
@@ -1,7 +1,8 @@
//===-- sanitizer_allocator_checks.h ----------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h b/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h
index ec6c0da..33f89d6 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h
@@ -1,7 +1,8 @@
//===-- sanitizer_allocator_combined.h --------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -18,20 +19,26 @@
// When allocating 2^x bytes it should return 2^x aligned chunk.
// PrimaryAllocator is used via a local AllocatorCache.
// SecondaryAllocator can allocate anything, but is not efficient.
-template <class PrimaryAllocator, class AllocatorCache,
- class SecondaryAllocator> // NOLINT
+template <class PrimaryAllocator,
+ class LargeMmapAllocatorPtrArray = DefaultLargeMmapAllocatorPtrArray>
class CombinedAllocator {
public:
+ using AllocatorCache = typename PrimaryAllocator::AllocatorCache;
+ using SecondaryAllocator =
+ LargeMmapAllocator<typename PrimaryAllocator::MapUnmapCallback,
+ LargeMmapAllocatorPtrArray,
+ typename PrimaryAllocator::AddressSpaceView>;
+
void InitLinkerInitialized(s32 release_to_os_interval_ms) {
+ stats_.InitLinkerInitialized();
primary_.Init(release_to_os_interval_ms);
secondary_.InitLinkerInitialized();
- stats_.InitLinkerInitialized();
}
void Init(s32 release_to_os_interval_ms) {
+ stats_.Init();
primary_.Init(release_to_os_interval_ms);
secondary_.Init();
- stats_.Init();
}
void *Allocate(AllocatorCache *cache, uptr size, uptr alignment) {
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_interface.h b/libsanitizer/sanitizer_common/sanitizer_allocator_interface.h
index 35213c7..c1b2756 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_interface.h
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_interface.h
@@ -1,7 +1,8 @@
//===-- sanitizer_allocator_interface.h ------------------------- C++ -----===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_internal.h b/libsanitizer/sanitizer_common/sanitizer_allocator_internal.h
index 05aed0e..3284903 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_internal.h
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_internal.h
@@ -1,7 +1,8 @@
//===-- sanitizer_allocator_internal.h --------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -21,41 +22,30 @@ namespace __sanitizer {
// purposes.
typedef CompactSizeClassMap InternalSizeClassMap;
-static const uptr kInternalAllocatorRegionSizeLog = 20;
-static const uptr kInternalAllocatorNumRegions =
- SANITIZER_MMAP_RANGE_SIZE >> kInternalAllocatorRegionSizeLog;
-#if SANITIZER_WORDSIZE == 32
-typedef FlatByteMap<kInternalAllocatorNumRegions> ByteMap;
-#else
-typedef TwoLevelByteMap<(kInternalAllocatorNumRegions >> 12), 1 << 12> ByteMap;
-#endif
struct AP32 {
static const uptr kSpaceBeg = 0;
static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
static const uptr kMetadataSize = 0;
typedef InternalSizeClassMap SizeClassMap;
- static const uptr kRegionSizeLog = kInternalAllocatorRegionSizeLog;
- typedef __sanitizer::ByteMap ByteMap;
+ static const uptr kRegionSizeLog = 20;
+ using AddressSpaceView = LocalAddressSpaceView;
typedef NoOpMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
};
typedef SizeClassAllocator32<AP32> PrimaryInternalAllocator;
-typedef SizeClassAllocatorLocalCache<PrimaryInternalAllocator>
- InternalAllocatorCache;
-
-typedef LargeMmapAllocator<NoOpMapUnmapCallback,
- LargeMmapAllocatorPtrArrayStatic>
- SecondaryInternalAllocator;
-
-typedef CombinedAllocator<PrimaryInternalAllocator, InternalAllocatorCache,
- SecondaryInternalAllocator> InternalAllocator;
+typedef CombinedAllocator<PrimaryInternalAllocator,
+ LargeMmapAllocatorPtrArrayStatic>
+ InternalAllocator;
+typedef InternalAllocator::AllocatorCache InternalAllocatorCache;
void *InternalAlloc(uptr size, InternalAllocatorCache *cache = nullptr,
uptr alignment = 0);
void *InternalRealloc(void *p, uptr size,
InternalAllocatorCache *cache = nullptr);
-void *InternalCalloc(uptr countr, uptr size,
+void *InternalReallocArray(void *p, uptr count, uptr size,
+ InternalAllocatorCache *cache = nullptr);
+void *InternalCalloc(uptr count, uptr size,
InternalAllocatorCache *cache = nullptr);
void InternalFree(void *p, InternalAllocatorCache *cache = nullptr);
InternalAllocator *internal_allocator();
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_local_cache.h b/libsanitizer/sanitizer_common/sanitizer_allocator_local_cache.h
index d23c59a..108dfc2 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_local_cache.h
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_local_cache.h
@@ -1,7 +1,8 @@
//===-- sanitizer_allocator_local_cache.h -----------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -12,13 +13,6 @@
#error This file must be included inside sanitizer_allocator.h
#endif
-// Objects of this type should be used as local caches for SizeClassAllocator64
-// or SizeClassAllocator32. Since the typical use of this class is to have one
-// object per thread in TLS, is has to be POD.
-template<class SizeClassAllocator>
-struct SizeClassAllocatorLocalCache
- : SizeClassAllocator::AllocatorCache {};
-
// Cache used by SizeClassAllocator64.
template <class SizeClassAllocator>
struct SizeClassAllocator64LocalCache {
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_primary32.h b/libsanitizer/sanitizer_common/sanitizer_allocator_primary32.h
index de16cf2..3b1838b 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_primary32.h
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_primary32.h
@@ -1,7 +1,8 @@
//===-- sanitizer_allocator_primary32.h -------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -45,14 +46,24 @@ struct SizeClassAllocator32FlagMasks { // Bit masks.
template <class Params>
class SizeClassAllocator32 {
+ private:
+ static const u64 kTwoLevelByteMapSize1 =
+ (Params::kSpaceSize >> Params::kRegionSizeLog) >> 12;
+ static const u64 kMinFirstMapSizeTwoLevelByteMap = 4;
+
public:
+ using AddressSpaceView = typename Params::AddressSpaceView;
static const uptr kSpaceBeg = Params::kSpaceBeg;
static const u64 kSpaceSize = Params::kSpaceSize;
static const uptr kMetadataSize = Params::kMetadataSize;
typedef typename Params::SizeClassMap SizeClassMap;
static const uptr kRegionSizeLog = Params::kRegionSizeLog;
- typedef typename Params::ByteMap ByteMap;
typedef typename Params::MapUnmapCallback MapUnmapCallback;
+ using ByteMap = typename conditional<
+ (kTwoLevelByteMapSize1 < kMinFirstMapSizeTwoLevelByteMap),
+ FlatByteMap<(Params::kSpaceSize >> Params::kRegionSizeLog),
+ AddressSpaceView>,
+ TwoLevelByteMap<kTwoLevelByteMapSize1, 1 << 12, AddressSpaceView>>::type;
COMPILER_CHECK(!SANITIZER_SIGN_EXTENDED_ADDRESSES ||
(kSpaceSize & (kSpaceSize - 1)) == 0);
@@ -205,7 +216,7 @@ class SizeClassAllocator32 {
return ClassIdToSize(GetSizeClass(p));
}
- uptr ClassID(uptr size) { return SizeClassMap::ClassID(size); }
+ static uptr ClassID(uptr size) { return SizeClassMap::ClassID(size); }
uptr TotalMemoryUsed() {
// No need to lock here.
@@ -271,7 +282,7 @@ class SizeClassAllocator32 {
};
COMPILER_CHECK(sizeof(SizeClassInfo) % kCacheLineSize == 0);
- uptr ComputeRegionId(uptr mem) {
+ uptr ComputeRegionId(uptr mem) const {
if (SANITIZER_SIGN_EXTENDED_ADDRESSES)
mem &= (kSpaceSize - 1);
const uptr res = mem >> kRegionSizeLog;
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h b/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h
index 119443b..9060328 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h
@@ -1,7 +1,8 @@
//===-- sanitizer_allocator_primary64.h -------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -44,6 +45,7 @@ struct SizeClassAllocator64FlagMasks { // Bit masks.
template <class Params>
class SizeClassAllocator64 {
public:
+ using AddressSpaceView = typename Params::AddressSpaceView;
static const uptr kSpaceBeg = Params::kSpaceBeg;
static const uptr kSpaceSize = Params::kSpaceSize;
static const uptr kMetadataSize = Params::kMetadataSize;
@@ -78,7 +80,8 @@ class SizeClassAllocator64 {
CHECK_NE(NonConstSpaceBeg, ~(uptr)0);
}
SetReleaseToOSIntervalMs(release_to_os_interval_ms);
- MapWithCallbackOrDie(SpaceEnd(), AdditionalSize());
+ MapWithCallbackOrDie(SpaceEnd(), AdditionalSize(),
+ "SizeClassAllocator: region info");
// Check that the RegionInfo array is aligned on the CacheLine size.
DCHECK_EQ(SpaceEnd() % kCacheLineSize, 0);
}
@@ -151,7 +154,7 @@ class SizeClassAllocator64 {
return true;
}
- bool PointerIsMine(const void *p) {
+ bool PointerIsMine(const void *p) const {
uptr P = reinterpret_cast<uptr>(p);
if (kUsingConstantSpaceBeg && (kSpaceBeg % kSpaceSize) == 0)
return P / kSpaceSize == kSpaceBeg / kSpaceSize;
@@ -186,7 +189,7 @@ class SizeClassAllocator64 {
uptr beg = chunk_idx * size;
uptr next_beg = beg + size;
if (class_id >= kNumClasses) return nullptr;
- RegionInfo *region = GetRegionInfo(class_id);
+ const RegionInfo *region = AddressSpaceView::Load(GetRegionInfo(class_id));
if (region->mapped_user >= next_beg)
return reinterpret_cast<void*>(reg_beg + beg);
return nullptr;
@@ -197,7 +200,7 @@ class SizeClassAllocator64 {
return ClassIdToSize(GetSizeClass(p));
}
- uptr ClassID(uptr size) { return SizeClassMap::ClassID(size); }
+ static uptr ClassID(uptr size) { return SizeClassMap::ClassID(size); }
void *GetMetaData(const void *p) {
uptr class_id = GetSizeClass(p);
@@ -292,8 +295,10 @@ class SizeClassAllocator64 {
RegionInfo *region = GetRegionInfo(class_id);
uptr chunk_size = ClassIdToSize(class_id);
uptr region_beg = SpaceBeg() + class_id * kRegionSize;
+ uptr region_allocated_user_size =
+ AddressSpaceView::Load(region)->allocated_user;
for (uptr chunk = region_beg;
- chunk < region_beg + region->allocated_user;
+ chunk < region_beg + region_allocated_user_size;
chunk += chunk_size) {
// Too slow: CHECK_EQ((void *)chunk, GetBlockBegin((void *)chunk));
callback(chunk, arg);
@@ -629,8 +634,8 @@ class SizeClassAllocator64 {
return reinterpret_cast<CompactPtrT *>(GetMetadataEnd(region_beg));
}
- bool MapWithCallback(uptr beg, uptr size) {
- uptr mapped = address_range.Map(beg, size);
+ bool MapWithCallback(uptr beg, uptr size, const char *name) {
+ uptr mapped = address_range.Map(beg, size, name);
if (UNLIKELY(!mapped))
return false;
CHECK_EQ(beg, mapped);
@@ -638,8 +643,8 @@ class SizeClassAllocator64 {
return true;
}
- void MapWithCallbackOrDie(uptr beg, uptr size) {
- CHECK_EQ(beg, address_range.MapOrDie(beg, size));
+ void MapWithCallbackOrDie(uptr beg, uptr size, const char *name) {
+ CHECK_EQ(beg, address_range.MapOrDie(beg, size, name));
MapUnmapCallback().OnMap(beg, size);
}
@@ -657,7 +662,8 @@ class SizeClassAllocator64 {
uptr current_map_end = reinterpret_cast<uptr>(GetFreeArray(region_beg)) +
region->mapped_free_array;
uptr new_map_size = new_mapped_free_array - region->mapped_free_array;
- if (UNLIKELY(!MapWithCallback(current_map_end, new_map_size)))
+ if (UNLIKELY(!MapWithCallback(current_map_end, new_map_size,
+ "SizeClassAllocator: freearray")))
return false;
region->mapped_free_array = new_mapped_free_array;
}
@@ -708,7 +714,8 @@ class SizeClassAllocator64 {
if (UNLIKELY(IsRegionExhausted(region, class_id, user_map_size)))
return false;
if (UNLIKELY(!MapWithCallback(region_beg + region->mapped_user,
- user_map_size)))
+ user_map_size,
+ "SizeClassAllocator: region data")))
return false;
stat->Add(AllocatorStatMapped, user_map_size);
region->mapped_user += user_map_size;
@@ -728,7 +735,7 @@ class SizeClassAllocator64 {
return false;
if (UNLIKELY(!MapWithCallback(
GetMetadataEnd(region_beg) - region->mapped_meta - meta_map_size,
- meta_map_size)))
+ meta_map_size, "SizeClassAllocator: region metadata")))
return false;
region->mapped_meta += meta_map_size;
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_report.cc b/libsanitizer/sanitizer_common/sanitizer_allocator_report.cpp
index a09fb91..dbcf2b7 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_report.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_report.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_allocator_report.cc ---------------------------*- C++ -*-===//
+//===-- sanitizer_allocator_report.cpp --------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
@@ -50,6 +51,18 @@ void NORETURN ReportCallocOverflow(uptr count, uptr size,
Die();
}
+void NORETURN ReportReallocArrayOverflow(uptr count, uptr size,
+ const StackTrace *stack) {
+ {
+ ScopedAllocatorErrorReport report("reallocarray-overflow", stack);
+ Report(
+ "ERROR: %s: reallocarray parameters overflow: count * size (%zd * %zd) "
+ "cannot be represented in type size_t\n",
+ SanitizerToolName, count, size);
+ }
+ Die();
+}
+
void NORETURN ReportPvallocOverflow(uptr size, const StackTrace *stack) {
{
ScopedAllocatorErrorReport report("pvalloc-overflow", stack);
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_report.h b/libsanitizer/sanitizer_common/sanitizer_allocator_report.h
index 892f7ff..0653c36 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_report.h
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_report.h
@@ -1,7 +1,8 @@
//===-- sanitizer_allocator_report.h ----------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
@@ -20,6 +21,8 @@ namespace __sanitizer {
void NORETURN ReportCallocOverflow(uptr count, uptr size,
const StackTrace *stack);
+void NORETURN ReportReallocArrayOverflow(uptr count, uptr size,
+ const StackTrace *stack);
void NORETURN ReportPvallocOverflow(uptr size, const StackTrace *stack);
void NORETURN ReportInvalidAllocationAlignment(uptr alignment,
const StackTrace *stack);
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_secondary.h b/libsanitizer/sanitizer_common/sanitizer_allocator_secondary.h
index 1dbca60..1d128f5 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_secondary.h
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_secondary.h
@@ -1,7 +1,8 @@
//===-- sanitizer_allocator_secondary.h -------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -66,9 +67,11 @@ typedef LargeMmapAllocatorPtrArrayDynamic DefaultLargeMmapAllocatorPtrArray;
// The main purpose of this allocator is to cover large and rare allocation
// sizes not covered by more efficient allocators (e.g. SizeClassAllocator64).
template <class MapUnmapCallback = NoOpMapUnmapCallback,
- class PtrArrayT = DefaultLargeMmapAllocatorPtrArray>
+ class PtrArrayT = DefaultLargeMmapAllocatorPtrArray,
+ class AddressSpaceViewTy = LocalAddressSpaceView>
class LargeMmapAllocator {
public:
+ using AddressSpaceView = AddressSpaceViewTy;
void InitLinkerInitialized() {
page_size_ = GetPageSizeCached();
chunks_ = reinterpret_cast<Header**>(ptr_array_.Init());
@@ -180,29 +183,33 @@ class LargeMmapAllocator {
uptr p = reinterpret_cast<uptr>(ptr);
SpinMutexLock l(&mutex_);
uptr nearest_chunk = 0;
+ Header *const *chunks = AddressSpaceView::Load(chunks_, n_chunks_);
// Cache-friendly linear search.
for (uptr i = 0; i < n_chunks_; i++) {
- uptr ch = reinterpret_cast<uptr>(chunks_[i]);
+ uptr ch = reinterpret_cast<uptr>(chunks[i]);
if (p < ch) continue; // p is at left to this chunk, skip it.
if (p - ch < p - nearest_chunk)
nearest_chunk = ch;
}
if (!nearest_chunk)
return nullptr;
- Header *h = reinterpret_cast<Header *>(nearest_chunk);
+ const Header *h =
+ AddressSpaceView::Load(reinterpret_cast<Header *>(nearest_chunk));
+ Header *h_ptr = reinterpret_cast<Header *>(nearest_chunk);
CHECK_GE(nearest_chunk, h->map_beg);
CHECK_LT(nearest_chunk, h->map_beg + h->map_size);
CHECK_LE(nearest_chunk, p);
if (h->map_beg + h->map_size <= p)
return nullptr;
- return GetUser(h);
+ return GetUser(h_ptr);
}
void EnsureSortedChunks() {
if (chunks_sorted_) return;
- Sort(reinterpret_cast<uptr *>(chunks_), n_chunks_);
+ Header **chunks = AddressSpaceView::LoadWritable(chunks_, n_chunks_);
+ Sort(reinterpret_cast<uptr *>(chunks), n_chunks_);
for (uptr i = 0; i < n_chunks_; i++)
- chunks_[i]->chunk_idx = i;
+ AddressSpaceView::LoadWritable(chunks[i])->chunk_idx = i;
chunks_sorted_ = true;
}
@@ -214,9 +221,10 @@ class LargeMmapAllocator {
uptr n = n_chunks_;
if (!n) return nullptr;
EnsureSortedChunks();
- auto min_mmap_ = reinterpret_cast<uptr>(chunks_[0]);
- auto max_mmap_ =
- reinterpret_cast<uptr>(chunks_[n - 1]) + chunks_[n - 1]->map_size;
+ Header *const *chunks = AddressSpaceView::Load(chunks_, n_chunks_);
+ auto min_mmap_ = reinterpret_cast<uptr>(chunks[0]);
+ auto max_mmap_ = reinterpret_cast<uptr>(chunks[n - 1]) +
+ AddressSpaceView::Load(chunks[n - 1])->map_size;
if (p < min_mmap_ || p >= max_mmap_)
return nullptr;
uptr beg = 0, end = n - 1;
@@ -224,23 +232,24 @@ class LargeMmapAllocator {
// to avoid expensive cache-thrashing loads.
while (end - beg >= 2) {
uptr mid = (beg + end) / 2; // Invariant: mid >= beg + 1
- if (p < reinterpret_cast<uptr>(chunks_[mid]))
- end = mid - 1; // We are not interested in chunks_[mid].
+ if (p < reinterpret_cast<uptr>(chunks[mid]))
+ end = mid - 1; // We are not interested in chunks[mid].
else
- beg = mid; // chunks_[mid] may still be what we want.
+ beg = mid; // chunks[mid] may still be what we want.
}
if (beg < end) {
CHECK_EQ(beg + 1, end);
// There are 2 chunks left, choose one.
- if (p >= reinterpret_cast<uptr>(chunks_[end]))
+ if (p >= reinterpret_cast<uptr>(chunks[end]))
beg = end;
}
- Header *h = chunks_[beg];
+ const Header *h = AddressSpaceView::Load(chunks[beg]);
+ Header *h_ptr = chunks[beg];
if (h->map_beg + h->map_size <= p || p < h->map_beg)
return nullptr;
- return GetUser(h);
+ return GetUser(h_ptr);
}
void PrintStats() {
@@ -270,12 +279,13 @@ class LargeMmapAllocator {
// The allocator must be locked when calling this function.
void ForEachChunk(ForEachChunkCallback callback, void *arg) {
EnsureSortedChunks(); // Avoid doing the sort while iterating.
+ const Header *const *chunks = AddressSpaceView::Load(chunks_, n_chunks_);
for (uptr i = 0; i < n_chunks_; i++) {
- auto t = chunks_[i];
+ const Header *t = chunks[i];
callback(reinterpret_cast<uptr>(GetUser(t)), arg);
// Consistency check: verify that the array did not change.
- CHECK_EQ(chunks_[i], t);
- CHECK_EQ(chunks_[i]->chunk_idx, i);
+ CHECK_EQ(chunks[i], t);
+ CHECK_EQ(AddressSpaceView::Load(chunks[i])->chunk_idx, i);
}
}
@@ -295,7 +305,7 @@ class LargeMmapAllocator {
return GetHeader(reinterpret_cast<uptr>(p));
}
- void *GetUser(Header *h) {
+ void *GetUser(const Header *h) {
CHECK(IsAligned((uptr)h, page_size_));
return reinterpret_cast<void*>(reinterpret_cast<uptr>(h) + page_size_);
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h b/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h
index cfe6299..12d8c89 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h
@@ -1,7 +1,8 @@
//===-- sanitizer_allocator_size_class_map.h --------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -235,3 +236,6 @@ typedef SizeClassMap<2, 5, 9, 16, 64, 14> VeryCompactSizeClassMap;
// allowing for denser per-class arrays, smaller memory footprint and usually
// better performances in threaded environments.
typedef SizeClassMap<3, 4, 8, 17, 8, 10> DenseSizeClassMap;
+// Similar to VeryCompact map above, this one has a small number of different
+// size classes, and also reduced thread-local caches.
+typedef SizeClassMap<2, 5, 9, 16, 8, 10> VeryDenseSizeClassMap;
diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_stats.h b/libsanitizer/sanitizer_common/sanitizer_allocator_stats.h
index 9336091..6f14e38 100644
--- a/libsanitizer/sanitizer_common/sanitizer_allocator_stats.h
+++ b/libsanitizer/sanitizer_common/sanitizer_allocator_stats.h
@@ -1,7 +1,8 @@
//===-- sanitizer_allocator_stats.h -----------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -101,3 +102,5 @@ class AllocatorGlobalStats : public AllocatorStats {
private:
mutable StaticSpinMutex mu_;
};
+
+
diff --git a/libsanitizer/sanitizer_common/sanitizer_asm.h b/libsanitizer/sanitizer_common/sanitizer_asm.h
index 4c75b41..184d118 100644
--- a/libsanitizer/sanitizer_common/sanitizer_asm.h
+++ b/libsanitizer/sanitizer_common/sanitizer_asm.h
@@ -1,7 +1,8 @@
//===-- sanitizer_asm.h -----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -43,14 +44,23 @@
#if !defined(__APPLE__)
# define ASM_HIDDEN(symbol) .hidden symbol
-# define ASM_TYPE_FUNCTION(symbol) .type symbol, @function
+# define ASM_TYPE_FUNCTION(symbol) .type symbol, %function
# define ASM_SIZE(symbol) .size symbol, .-symbol
# define ASM_SYMBOL(symbol) symbol
# define ASM_SYMBOL_INTERCEPTOR(symbol) symbol
+# define ASM_WRAPPER_NAME(symbol) __interceptor_##symbol
#else
# define ASM_HIDDEN(symbol)
# define ASM_TYPE_FUNCTION(symbol)
# define ASM_SIZE(symbol)
# define ASM_SYMBOL(symbol) _##symbol
# define ASM_SYMBOL_INTERCEPTOR(symbol) _wrap_##symbol
+# define ASM_WRAPPER_NAME(symbol) __interceptor_##symbol
+#endif
+
+#if defined(__ELF__) && (defined(__GNU__) || defined(__FreeBSD__) || \
+ defined(__Fuchsia__) || defined(__linux__))
+#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits // NOLINT
+#else
+#define NO_EXEC_STACK_DIRECTIVE
#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic.h b/libsanitizer/sanitizer_common/sanitizer_atomic.h
index 82de0c6..a798a0c 100644
--- a/libsanitizer/sanitizer_common/sanitizer_atomic.h
+++ b/libsanitizer/sanitizer_common/sanitizer_atomic.h
@@ -1,7 +1,8 @@
//===-- sanitizer_atomic.h --------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_clang.h b/libsanitizer/sanitizer_common/sanitizer_atomic_clang.h
index 89fb748..c40461e 100644
--- a/libsanitizer/sanitizer_common/sanitizer_atomic_clang.h
+++ b/libsanitizer/sanitizer_common/sanitizer_atomic_clang.h
@@ -1,7 +1,8 @@
//===-- sanitizer_atomic_clang.h --------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h
index 41e58dc..d369aeb 100644
--- a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h
+++ b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h
@@ -1,7 +1,8 @@
//===-- sanitizer_atomic_clang_mips.h ---------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -113,3 +114,4 @@ INLINE void atomic_store(volatile atomic_uint64_t *ptr, atomic_uint64_t::Type v,
} // namespace __sanitizer
#endif // SANITIZER_ATOMIC_CLANG_MIPS_H
+
diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h
index b11efcc..b8685a8 100644
--- a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h
+++ b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h
@@ -1,7 +1,8 @@
//===-- sanitizer_atomic_clang_other.h --------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_x86.h b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_x86.h
index aab9935..f2ce553 100644
--- a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_x86.h
+++ b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_x86.h
@@ -1,7 +1,8 @@
//===-- sanitizer_atomic_clang_x86.h ----------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h b/libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h
index 4ae8714..a249657 100644
--- a/libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h
+++ b/libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h
@@ -1,7 +1,8 @@
//===-- sanitizer_atomic_msvc.h ---------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_bitvector.h b/libsanitizer/sanitizer_common/sanitizer_bitvector.h
index 6ecac81..07a59ab 100644
--- a/libsanitizer/sanitizer_common/sanitizer_bitvector.h
+++ b/libsanitizer/sanitizer_common/sanitizer_bitvector.h
@@ -1,7 +1,8 @@
//===-- sanitizer_bitvector.h -----------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_bvgraph.h b/libsanitizer/sanitizer_common/sanitizer_bvgraph.h
index a7f76bf..e724905 100644
--- a/libsanitizer/sanitizer_common/sanitizer_bvgraph.h
+++ b/libsanitizer/sanitizer_common/sanitizer_bvgraph.h
@@ -1,7 +1,8 @@
//===-- sanitizer_bvgraph.h -------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_common.cc b/libsanitizer/sanitizer_common/sanitizer_common.cpp
index 7f0f47c..451c9e5 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_common.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_common.cc -----------------------------------------------===//
+//===-- sanitizer_common.cpp ----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_common.h b/libsanitizer/sanitizer_common/sanitizer_common.h
index 603d922..4f0f16d 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common.h
+++ b/libsanitizer/sanitizer_common/sanitizer_common.h
@@ -1,7 +1,8 @@
//===-- sanitizer_common.h --------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -59,6 +60,15 @@ INLINE int Verbosity() {
return atomic_load(&current_verbosity, memory_order_relaxed);
}
+#if SANITIZER_ANDROID
+INLINE uptr GetPageSize() {
+// Android post-M sysconf(_SC_PAGESIZE) crashes if called from .preinit_array.
+ return 4096;
+}
+INLINE uptr GetPageSizeCached() {
+ return 4096;
+}
+#else
uptr GetPageSize();
extern uptr PageSizeCached;
INLINE uptr GetPageSizeCached() {
@@ -66,6 +76,7 @@ INLINE uptr GetPageSizeCached() {
PageSizeCached = GetPageSize();
return PageSizeCached;
}
+#endif
uptr GetMmapGranularity();
uptr GetMaxVirtualAddress();
uptr GetMaxUserVirtualAddress();
@@ -90,10 +101,11 @@ void *MmapOrDieOnFatalError(uptr size, const char *mem_type);
bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name = nullptr)
WARN_UNUSED_RESULT;
void *MmapNoReserveOrDie(uptr size, const char *mem_type);
-void *MmapFixedOrDie(uptr fixed_addr, uptr size);
+void *MmapFixedOrDie(uptr fixed_addr, uptr size, const char *name = nullptr);
// Behaves just like MmapFixedOrDie, but tolerates out of memory condition, in
// that case returns nullptr.
-void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size);
+void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size,
+ const char *name = nullptr);
void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name = nullptr);
void *MmapNoAccess(uptr size);
// Map aligned chunk of address space; size and alignment are powers of two.
@@ -119,7 +131,7 @@ void ReleaseMemoryPagesToOS(uptr beg, uptr end);
void IncreaseTotalMmap(uptr size);
void DecreaseTotalMmap(uptr size);
uptr GetRSS();
-bool NoHugePagesInRegion(uptr addr, uptr length);
+void SetShadowRegionHugePageMode(uptr addr, uptr length);
bool DontDumpShadowMemory(uptr addr, uptr length);
// Check if the built VMA size matches the runtime one.
void CheckVMASize();
@@ -129,8 +141,8 @@ void RunFreeHooks(const void *ptr);
class ReservedAddressRange {
public:
uptr Init(uptr size, const char *name = nullptr, uptr fixed_addr = 0);
- uptr Map(uptr fixed_addr, uptr size);
- uptr MapOrDie(uptr fixed_addr, uptr size);
+ uptr Map(uptr fixed_addr, uptr size, const char *name = nullptr);
+ uptr MapOrDie(uptr fixed_addr, uptr size, const char *name = nullptr);
void Unmap(uptr addr, uptr size);
void *base() const { return base_; }
uptr size() const { return size_; }
@@ -221,10 +233,11 @@ bool SetEnv(const char *name, const char *value);
u32 GetUid();
void ReExec();
void CheckASLR();
+void CheckMPROTECT();
char **GetArgv();
+char **GetEnviron();
void PrintCmdline();
bool StackSizeIsUnlimited();
-uptr GetStackSizeLimitInBytes();
void SetStackSizeLimitInBytes(uptr limit);
bool AddressSpaceIsUnlimited();
void SetAddressSpaceUnlimited();
@@ -656,7 +669,7 @@ bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size,
error_t *errno_p = nullptr);
// When adding a new architecture, don't forget to also update
-// script/asan_symbolize.py and sanitizer_symbolizer_libcdep.cc.
+// script/asan_symbolize.py and sanitizer_symbolizer_libcdep.cpp.
inline const char *ModuleArchToString(ModuleArch arch) {
switch (arch) {
case kModuleArchUnknown:
@@ -790,7 +803,13 @@ enum AndroidApiLevel {
void WriteToSyslog(const char *buffer);
-#if SANITIZER_MAC
+#if defined(SANITIZER_WINDOWS) && defined(_MSC_VER) && !defined(__clang__)
+#define SANITIZER_WIN_TRACE 1
+#else
+#define SANITIZER_WIN_TRACE 0
+#endif
+
+#if SANITIZER_MAC || SANITIZER_WIN_TRACE
void LogFullErrorReport(const char *buffer);
#else
INLINE void LogFullErrorReport(const char *buffer) {}
@@ -804,7 +823,7 @@ INLINE void WriteOneLineToSyslog(const char *s) {}
INLINE void LogMessageOnPrintf(const char *str) {}
#endif
-#if SANITIZER_LINUX
+#if SANITIZER_LINUX || SANITIZER_WIN_TRACE
// Initialize Android logging. Any writes before this are silently lost.
void AndroidLogInit();
void SetAbortMessage(const char *);
@@ -895,6 +914,7 @@ struct SignalContext {
bool IsMemoryAccess() const;
};
+void InitializePlatformEarly();
void MaybeReexec();
template <typename Fn>
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
index c810e65..9975f53 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -75,7 +76,15 @@
#define ctime __ctime50
#define ctime_r __ctime_r50
#define devname __devname50
+#define fgetpos __fgetpos50
+#define fsetpos __fsetpos50
+#define fts_children __fts_children60
+#define fts_close __fts_close60
+#define fts_open __fts_open60
+#define fts_read __fts_read60
+#define fts_set __fts_set60
#define getitimer __getitimer50
+#define getmntinfo __getmntinfo13
#define getpwent __getpwent50
#define getpwnam __getpwnam50
#define getpwnam_r __getpwnam_r50
@@ -85,6 +94,7 @@
#define getutxent __getutxent50
#define getutxid __getutxid50
#define getutxline __getutxline50
+#define pututxline __pututxline50
#define glob __glob30
#define gmtime __gmtime50
#define gmtime_r __gmtime_r50
@@ -107,6 +117,7 @@
#define stat __stat50
#define time __time50
#define times __times13
+#define unvis __unvis50
#define wait3 __wait350
#define wait4 __wait450
extern const unsigned short *_ctype_tab_;
@@ -306,11 +317,11 @@ struct CommonInterceptorMetadata {
};
};
+#if SI_POSIX
typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap;
static MetadataHashMap *interceptor_metadata_map;
-#if SI_POSIX
UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr,
const FileMetadata &file) {
MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr);
@@ -808,16 +819,14 @@ INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) {
#endif
#if SANITIZER_INTERCEPT_MEMCMP
-
DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,
const void *s1, const void *s2, uptr n,
int result)
-INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
- if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
- return internal_memcmp(a1, a2, size);
- void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);
+// Common code for `memcmp` and `bcmp`.
+int MemcmpInterceptorCommon(void *ctx,
+ int (*real_fn)(const void *, const void *, uptr),
+ const void *a1, const void *a2, uptr size) {
if (common_flags()->intercept_memcmp) {
if (common_flags()->strict_memcmp) {
// Check the entire regions even if the first bytes of the buffers are
@@ -843,17 +852,39 @@ INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
return r;
}
}
- int result = REAL(memcmp(a1, a2, size));
+ int result = real_fn(a1, a2, size);
CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,
a2, size, result);
return result;
}
+INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
+ if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
+ return internal_memcmp(a1, a2, size);
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);
+ return MemcmpInterceptorCommon(ctx, REAL(memcmp), a1, a2, size);
+}
+
#define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp)
#else
#define INIT_MEMCMP
#endif
+#if SANITIZER_INTERCEPT_BCMP
+INTERCEPTOR(int, bcmp, const void *a1, const void *a2, uptr size) {
+ if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
+ return internal_memcmp(a1, a2, size);
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, bcmp, a1, a2, size);
+ return MemcmpInterceptorCommon(ctx, REAL(bcmp), a1, a2, size);
+}
+
+#define INIT_BCMP COMMON_INTERCEPT_FUNCTION(bcmp)
+#else
+#define INIT_BCMP
+#endif
+
#if SANITIZER_INTERCEPT_MEMCHR
INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {
if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
@@ -1210,7 +1241,9 @@ INTERCEPTOR_WITH_SUFFIX(int, fputs, char *s, void *file) {
// libc file streams can call user-supplied functions, see fopencookie.
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, fputs, s, file);
- COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
+ if (!SANITIZER_MAC || s) { // `fputs(NULL, file)` is supported on Darwin.
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
+ }
return REAL(fputs)(s, file);
}
#define INIT_FPUTS COMMON_INTERCEPT_FUNCTION(fputs)
@@ -1223,7 +1256,9 @@ INTERCEPTOR(int, puts, char *s) {
// libc file streams can call user-supplied functions, see fopencookie.
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, puts, s);
- COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
+ if (!SANITIZER_MAC || s) { // `puts(NULL)` is supported on Darwin.
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
+ }
return REAL(puts)(s);
}
#define INIT_PUTS COMMON_INTERCEPT_FUNCTION(puts)
@@ -1806,58 +1841,53 @@ INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) {
#define INIT_IOCTL
#endif
-#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || \
- SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT || \
- SANITIZER_INTERCEPT_GETPWENT_R || SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
-static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
+#if SANITIZER_POSIX
+UNUSED static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
if (pwd) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));
if (pwd->pw_name)
- COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_name,
- REAL(strlen)(pwd->pw_name) + 1);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_name,
+ REAL(strlen)(pwd->pw_name) + 1);
if (pwd->pw_passwd)
- COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_passwd,
- REAL(strlen)(pwd->pw_passwd) + 1);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_passwd,
+ REAL(strlen)(pwd->pw_passwd) + 1);
#if !SANITIZER_ANDROID
if (pwd->pw_gecos)
- COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_gecos,
- REAL(strlen)(pwd->pw_gecos) + 1);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_gecos,
+ REAL(strlen)(pwd->pw_gecos) + 1);
#endif
-#if SANITIZER_MAC
+#if SANITIZER_MAC || SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
if (pwd->pw_class)
- COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_class,
- REAL(strlen)(pwd->pw_class) + 1);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_class,
+ REAL(strlen)(pwd->pw_class) + 1);
#endif
if (pwd->pw_dir)
- COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_dir,
- REAL(strlen)(pwd->pw_dir) + 1);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_dir,
+ REAL(strlen)(pwd->pw_dir) + 1);
if (pwd->pw_shell)
- COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_shell,
- REAL(strlen)(pwd->pw_shell) + 1);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_shell,
+ REAL(strlen)(pwd->pw_shell) + 1);
}
}
-static void unpoison_group(void *ctx, __sanitizer_group *grp) {
+UNUSED static void unpoison_group(void *ctx, __sanitizer_group *grp) {
if (grp) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));
if (grp->gr_name)
- COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_name,
- REAL(strlen)(grp->gr_name) + 1);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_name,
+ REAL(strlen)(grp->gr_name) + 1);
if (grp->gr_passwd)
- COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_passwd,
- REAL(strlen)(grp->gr_passwd) + 1);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_passwd,
+ REAL(strlen)(grp->gr_passwd) + 1);
char **p = grp->gr_mem;
for (; *p; ++p) {
- COMMON_INTERCEPTOR_INITIALIZE_RANGE(*p, REAL(strlen)(*p) + 1);
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
}
- COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_mem,
- (p - grp->gr_mem + 1) * sizeof(*p));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_mem,
+ (p - grp->gr_mem + 1) * sizeof(*p));
}
}
-#endif // SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS ||
- // SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT ||
- // SANITIZER_INTERCEPT_GETPWENT_R ||
- // SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
+#endif // SANITIZER_POSIX
#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {
@@ -1866,14 +1896,14 @@ INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {
if (name)
COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
__sanitizer_passwd *res = REAL(getpwnam)(name);
- if (res) unpoison_passwd(ctx, res);
+ unpoison_passwd(ctx, res);
return res;
}
INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
__sanitizer_passwd *res = REAL(getpwuid)(uid);
- if (res) unpoison_passwd(ctx, res);
+ unpoison_passwd(ctx, res);
return res;
}
INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {
@@ -1881,14 +1911,14 @@ INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {
COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
__sanitizer_group *res = REAL(getgrnam)(name);
- if (res) unpoison_group(ctx, res);
+ unpoison_group(ctx, res);
return res;
}
INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
__sanitizer_group *res = REAL(getgrgid)(gid);
- if (res) unpoison_group(ctx, res);
+ unpoison_group(ctx, res);
return res;
}
#define INIT_GETPWNAM_AND_FRIENDS \
@@ -1910,10 +1940,8 @@ INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,
// its metadata. See
// https://github.com/google/sanitizers/issues/321.
int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
- if (!res) {
- if (result && *result) unpoison_passwd(ctx, *result);
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
- }
+ if (!res && result)
+ unpoison_passwd(ctx, *result);
if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
return res;
}
@@ -1925,10 +1953,8 @@ INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,
// its metadata. See
// https://github.com/google/sanitizers/issues/321.
int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
- if (!res) {
- if (result && *result) unpoison_passwd(ctx, *result);
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
- }
+ if (!res && result)
+ unpoison_passwd(ctx, *result);
if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
return res;
}
@@ -1941,10 +1967,8 @@ INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,
// its metadata. See
// https://github.com/google/sanitizers/issues/321.
int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
- if (!res) {
- if (result && *result) unpoison_group(ctx, *result);
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
- }
+ if (!res && result)
+ unpoison_group(ctx, *result);
if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
return res;
}
@@ -1956,10 +1980,8 @@ INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,
// its metadata. See
// https://github.com/google/sanitizers/issues/321.
int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
- if (!res) {
- if (result && *result) unpoison_group(ctx, *result);
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
- }
+ if (!res && result)
+ unpoison_group(ctx, *result);
if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
return res;
}
@@ -1977,14 +1999,14 @@ INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);
__sanitizer_passwd *res = REAL(getpwent)(dummy);
- if (res) unpoison_passwd(ctx, res);
+ unpoison_passwd(ctx, res);
return res;
}
INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);
__sanitizer_group *res = REAL(getgrent)(dummy);
- if (res) unpoison_group(ctx, res);;
+ unpoison_group(ctx, res);
return res;
}
#define INIT_GETPWENT \
@@ -1999,14 +2021,14 @@ INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);
__sanitizer_passwd *res = REAL(fgetpwent)(fp);
- if (res) unpoison_passwd(ctx, res);
+ unpoison_passwd(ctx, res);
return res;
}
INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);
__sanitizer_group *res = REAL(fgetgrent)(fp);
- if (res) unpoison_group(ctx, res);
+ unpoison_group(ctx, res);
return res;
}
#define INIT_FGETPWENT \
@@ -2025,43 +2047,52 @@ INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,
// its metadata. See
// https://github.com/google/sanitizers/issues/321.
int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);
- if (!res) {
- if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
- }
+ if (!res && pwbufp)
+ unpoison_passwd(ctx, *pwbufp);
if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
return res;
}
-INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,
- SIZE_T buflen, __sanitizer_passwd **pwbufp) {
+INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,
+ __sanitizer_group **pwbufp) {
void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
+ COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
// FIXME: under ASan the call below may write to freed memory and corrupt
// its metadata. See
// https://github.com/google/sanitizers/issues/321.
- int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
- if (!res) {
- if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
- }
+ int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
+ if (!res && pwbufp)
+ unpoison_group(ctx, *pwbufp);
if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
return res;
}
-INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,
- __sanitizer_group **pwbufp) {
+#define INIT_GETPWENT_R \
+ COMMON_INTERCEPT_FUNCTION(getpwent_r); \
+ COMMON_INTERCEPT_FUNCTION(getgrent_r);
+#else
+#define INIT_GETPWENT_R
+#endif
+
+#if SANITIZER_INTERCEPT_FGETPWENT_R
+INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,
+ SIZE_T buflen, __sanitizer_passwd **pwbufp) {
void *ctx;
- COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
+ COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
// FIXME: under ASan the call below may write to freed memory and corrupt
// its metadata. See
// https://github.com/google/sanitizers/issues/321.
- int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
- if (!res) {
- if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
- }
+ int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
+ if (!res && pwbufp)
+ unpoison_passwd(ctx, *pwbufp);
if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
return res;
}
+#define INIT_FGETPWENT_R \
+ COMMON_INTERCEPT_FUNCTION(fgetpwent_r);
+#else
+#define INIT_FGETPWENT_R
+#endif
+
+#if SANITIZER_INTERCEPT_FGETGRENT_R
INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,
SIZE_T buflen, __sanitizer_group **pwbufp) {
void *ctx;
@@ -2070,20 +2101,15 @@ INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,
// its metadata. See
// https://github.com/google/sanitizers/issues/321.
int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);
- if (!res) {
- if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
- }
+ if (!res && pwbufp)
+ unpoison_group(ctx, *pwbufp);
if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
return res;
}
-#define INIT_GETPWENT_R \
- COMMON_INTERCEPT_FUNCTION(getpwent_r); \
- COMMON_INTERCEPT_FUNCTION(fgetpwent_r); \
- COMMON_INTERCEPT_FUNCTION(getgrent_r); \
+#define INIT_FGETGRENT_R \
COMMON_INTERCEPT_FUNCTION(fgetgrent_r);
#else
-#define INIT_GETPWENT_R
+#define INIT_FGETGRENT_R
#endif
#if SANITIZER_INTERCEPT_SETPWENT
@@ -2147,6 +2173,8 @@ INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
namespace __sanitizer {
extern "C" {
int real_clock_gettime(u32 clk_id, void *tp) {
+ if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
+ return internal_clock_gettime(clk_id, tp);
return REAL(clock_gettime)(clk_id, tp);
}
} // extern "C"
@@ -3500,13 +3528,16 @@ INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps);
if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
- // FIXME: under ASan the call below may write to freed memory and corrupt
- // its metadata. See
- // https://github.com/google/sanitizers/issues/321.
- SIZE_T res = REAL(wcrtomb)(dest, src, ps);
- if (res != ((SIZE_T)-1) && dest) {
- SIZE_T write_cnt = res;
- COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
+
+ if (!dest)
+ return REAL(wcrtomb)(dest, src, ps);
+
+ char local_dest[32];
+ SIZE_T res = REAL(wcrtomb)(local_dest, src, ps);
+ if (res != ((SIZE_T)-1)) {
+ CHECK_LE(res, sizeof(local_dest));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
+ REAL(memcpy)(dest, local_dest, res);
}
return res;
}
@@ -3516,6 +3547,28 @@ INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
#define INIT_WCRTOMB
#endif
+#if SANITIZER_INTERCEPT_WCTOMB
+INTERCEPTOR(int, wctomb, char *dest, wchar_t src) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, wctomb, dest, src);
+ if (!dest)
+ return REAL(wctomb)(dest, src);
+
+ char local_dest[32];
+ int res = REAL(wctomb)(local_dest, src);
+ if (res != -1) {
+ CHECK_LE(res, sizeof(local_dest));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
+ REAL(memcpy)(dest, local_dest, res);
+ }
+ return res;
+}
+
+#define INIT_WCTOMB COMMON_INTERCEPT_FUNCTION(wctomb);
+#else
+#define INIT_WCTOMB
+#endif
+
#if SANITIZER_INTERCEPT_TCGETATTR
INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
void *ctx;
@@ -4012,6 +4065,25 @@ INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
#define INIT_SIGPROCMASK
#endif
+#if SANITIZER_INTERCEPT_PTHREAD_SIGMASK
+INTERCEPTOR(int, pthread_sigmask, int how, __sanitizer_sigset_t *set,
+ __sanitizer_sigset_t *oldset) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, pthread_sigmask, how, set, oldset);
+ if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
+ // FIXME: under ASan the call below may write to freed memory and corrupt
+ // its metadata. See
+ // https://github.com/google/sanitizers/issues/321.
+ int res = REAL(pthread_sigmask)(how, set, oldset);
+ if (!res && oldset)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
+ return res;
+}
+#define INIT_PTHREAD_SIGMASK COMMON_INTERCEPT_FUNCTION(pthread_sigmask);
+#else
+#define INIT_PTHREAD_SIGMASK
+#endif
+
#if SANITIZER_INTERCEPT_BACKTRACE
INTERCEPTOR(int, backtrace, void **buffer, int size) {
void *ctx;
@@ -4252,11 +4324,16 @@ INTERCEPTOR(int, statvfs, char *path, void *buf) {
INTERCEPTOR(int, fstatvfs, int fd, void *buf) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
// FIXME: under ASan the call below may write to freed memory and corrupt
// its metadata. See
// https://github.com/google/sanitizers/issues/321.
int res = REAL(fstatvfs)(fd, buf);
- if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
+ if (!res) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
+ if (fd >= 0)
+ COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
+ }
return res;
}
#define INIT_STATVFS \
@@ -4690,6 +4767,20 @@ INTERCEPTOR(char *, tmpnam_r, char *s) {
#define INIT_TMPNAM_R
#endif
+#if SANITIZER_INTERCEPT_TTYNAME
+INTERCEPTOR(char *, ttyname, int fd) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, ttyname, fd);
+ char *res = REAL(ttyname)(fd);
+ if (res != nullptr)
+ COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
+ return res;
+}
+#define INIT_TTYNAME COMMON_INTERCEPT_FUNCTION(ttyname);
+#else
+#define INIT_TTYNAME
+#endif
+
#if SANITIZER_INTERCEPT_TTYNAME_R
INTERCEPTOR(int, ttyname_r, int fd, char *name, SIZE_T namesize) {
void *ctx;
@@ -4817,6 +4908,14 @@ INTERCEPTOR(float, remquof, float x, float y, int *quo) {
if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
return res;
}
+#define INIT_REMQUO \
+ COMMON_INTERCEPT_FUNCTION(remquo); \
+ COMMON_INTERCEPT_FUNCTION(remquof);
+#else
+#define INIT_REMQUO
+#endif
+
+#if SANITIZER_INTERCEPT_REMQUOL
INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);
@@ -4827,12 +4926,10 @@ INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
return res;
}
-#define INIT_REMQUO \
- COMMON_INTERCEPT_FUNCTION(remquo); \
- COMMON_INTERCEPT_FUNCTION(remquof); \
+#define INIT_REMQUOL \
COMMON_INTERCEPT_FUNCTION_LDBL(remquol);
#else
-#define INIT_REMQUO
+#define INIT_REMQUOL
#endif
#if SANITIZER_INTERCEPT_LGAMMA
@@ -4851,6 +4948,14 @@ INTERCEPTOR(float, lgammaf, float x) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
return res;
}
+#define INIT_LGAMMA \
+ COMMON_INTERCEPT_FUNCTION(lgamma); \
+ COMMON_INTERCEPT_FUNCTION(lgammaf);
+#else
+#define INIT_LGAMMA
+#endif
+
+#if SANITIZER_INTERCEPT_LGAMMAL
INTERCEPTOR(long double, lgammal, long double x) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);
@@ -4858,12 +4963,10 @@ INTERCEPTOR(long double, lgammal, long double x) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
return res;
}
-#define INIT_LGAMMA \
- COMMON_INTERCEPT_FUNCTION(lgamma); \
- COMMON_INTERCEPT_FUNCTION(lgammaf); \
+#define INIT_LGAMMAL \
COMMON_INTERCEPT_FUNCTION_LDBL(lgammal);
#else
-#define INIT_LGAMMA
+#define INIT_LGAMMAL
#endif
#if SANITIZER_INTERCEPT_LGAMMA_R
@@ -5455,12 +5558,21 @@ INTERCEPTOR(void *, __bzero, void *block, uptr size) {
void *ctx;
COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
}
-
#define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero);
#else
#define INIT___BZERO
#endif // SANITIZER_INTERCEPT___BZERO
+#if SANITIZER_INTERCEPT_BZERO
+INTERCEPTOR(void *, bzero, void *block, uptr size) {
+ void *ctx;
+ COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
+}
+#define INIT_BZERO COMMON_INTERCEPT_FUNCTION(bzero);
+#else
+#define INIT_BZERO
+#endif // SANITIZER_INTERCEPT_BZERO
+
#if SANITIZER_INTERCEPT_FTIME
INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {
void *ctx;
@@ -5649,9 +5761,15 @@ INTERCEPTOR(void *, tsearch, void *key, void **rootp,
void unpoison_file(__sanitizer_FILE *fp) {
#if SANITIZER_HAS_STRUCT_FILE
COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));
+#if SANITIZER_NETBSD
+ if (fp->_bf._base && fp->_bf._size > 0)
+ COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_bf._base,
+ fp->_bf._size);
+#else
if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)
COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,
fp->_IO_read_end - fp->_IO_read_base);
+#endif
#endif // SANITIZER_HAS_STRUCT_FILE
}
#endif
@@ -6521,10 +6639,21 @@ INTERCEPTOR(void *, getutxline, void *ut) {
COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
return res;
}
+INTERCEPTOR(void *, pututxline, const void *ut) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, pututxline, ut);
+ if (ut)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, ut, __sanitizer::struct_utmpx_sz);
+ void *res = REAL(pututxline)(ut);
+ if (res)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_utmpx_sz);
+ return res;
+}
#define INIT_UTMPX \
COMMON_INTERCEPT_FUNCTION(getutxent); \
COMMON_INTERCEPT_FUNCTION(getutxid); \
- COMMON_INTERCEPT_FUNCTION(getutxline);
+ COMMON_INTERCEPT_FUNCTION(getutxline); \
+ COMMON_INTERCEPT_FUNCTION(pututxline);
#else
#define INIT_UTMPX
#endif
@@ -6609,6 +6738,23 @@ INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) {
#define INIT_WCSCAT
#endif
+#if SANITIZER_INTERCEPT_WCSDUP
+INTERCEPTOR(wchar_t *, wcsdup, wchar_t *s) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, wcsdup, s);
+ SIZE_T len = REAL(wcslen)(s);
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (len + 1));
+ wchar_t *result = REAL(wcsdup)(s);
+ if (result)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(wchar_t) * (len + 1));
+ return result;
+}
+
+#define INIT_WCSDUP COMMON_INTERCEPT_FUNCTION(wcsdup);
+#else
+#define INIT_WCSDUP
+#endif
+
#if SANITIZER_INTERCEPT_STRXFRM
static SIZE_T RealStrLen(const char *str) { return REAL(strlen)(str); }
@@ -7016,12 +7162,19 @@ INTERCEPTOR(char *, devname, u64 dev, u32 type) {
#endif
#if SANITIZER_INTERCEPT_DEVNAME_R
-INTERCEPTOR(int, devname_r, u64 dev, u32 type, char *path, uptr len) {
+#if SANITIZER_NETBSD
+#define DEVNAME_R_RETTYPE int
+#define DEVNAME_R_SUCCESS(x) (!(x))
+#else
+#define DEVNAME_R_RETTYPE char*
+#define DEVNAME_R_SUCCESS(x) (x)
+#endif
+INTERCEPTOR(DEVNAME_R_RETTYPE, devname_r, u64 dev, u32 type, char *path,
+ uptr len) {
void *ctx;
- int res;
COMMON_INTERCEPTOR_ENTER(ctx, devname_r, dev, type, path, len);
- res = REAL(devname_r)(dev, type, path, len);
- if (!res)
+ DEVNAME_R_RETTYPE res = REAL(devname_r)(dev, type, path, len);
+ if (DEVNAME_R_SUCCESS(res))
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, REAL(strlen)(path) + 1);
return res;
}
@@ -7233,9 +7386,2191 @@ INTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) {
#define INIT_NETENT
#endif
+#if SANITIZER_INTERCEPT_GETMNTINFO
+INTERCEPTOR(int, getmntinfo, void **mntbufp, int flags) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getmntinfo, mntbufp, flags);
+ int cnt = REAL(getmntinfo)(mntbufp, flags);
+ if (cnt > 0 && mntbufp) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mntbufp, sizeof(void *));
+ if (*mntbufp)
+#if SANITIZER_NETBSD
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statvfs_sz);
+#else
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statfs_sz);
+#endif
+ }
+ return cnt;
+}
+#define INIT_GETMNTINFO COMMON_INTERCEPT_FUNCTION(getmntinfo)
+#else
+#define INIT_GETMNTINFO
+#endif
+
+#if SANITIZER_INTERCEPT_MI_VECTOR_HASH
+INTERCEPTOR(void, mi_vector_hash, const void *key, SIZE_T len, u32 seed,
+ u32 hashes[3]) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, mi_vector_hash, key, len, seed, hashes);
+ if (key)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, key, len);
+ REAL(mi_vector_hash)(key, len, seed, hashes);
+ if (hashes)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hashes, sizeof(hashes[0]) * 3);
+}
+#define INIT_MI_VECTOR_HASH COMMON_INTERCEPT_FUNCTION(mi_vector_hash)
+#else
+#define INIT_MI_VECTOR_HASH
+#endif
+
+#if SANITIZER_INTERCEPT_SETVBUF
+INTERCEPTOR(int, setvbuf, __sanitizer_FILE *stream, char *buf, int mode,
+ SIZE_T size) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, setvbuf, stream, buf, mode, size);
+ int ret = REAL(setvbuf)(stream, buf, mode, size);
+ if (buf)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size);
+ if (stream)
+ unpoison_file(stream);
+ return ret;
+}
+
+INTERCEPTOR(void, setbuf, __sanitizer_FILE *stream, char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, setbuf, stream, buf);
+ REAL(setbuf)(stream, buf);
+ if (buf) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz);
+ }
+ if (stream)
+ unpoison_file(stream);
+}
+
+INTERCEPTOR(void, setbuffer, __sanitizer_FILE *stream, char *buf, int mode) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, setbuffer, stream, buf, mode);
+ REAL(setbuffer)(stream, buf, mode);
+ if (buf) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz);
+ }
+ if (stream)
+ unpoison_file(stream);
+}
+
+INTERCEPTOR(void, setlinebuf, __sanitizer_FILE *stream) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, setlinebuf, stream);
+ REAL(setlinebuf)(stream);
+ if (stream)
+ unpoison_file(stream);
+}
+#define INIT_SETVBUF COMMON_INTERCEPT_FUNCTION(setvbuf); \
+ COMMON_INTERCEPT_FUNCTION(setbuf); \
+ COMMON_INTERCEPT_FUNCTION(setbuffer); \
+ COMMON_INTERCEPT_FUNCTION(setlinebuf)
+#else
+#define INIT_SETVBUF
+#endif
+
+#if SANITIZER_INTERCEPT_GETVFSSTAT
+INTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getvfsstat, buf, bufsize, flags);
+ int ret = REAL(getvfsstat)(buf, bufsize, flags);
+ if (buf && ret > 0)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, ret * struct_statvfs_sz);
+ return ret;
+}
+#define INIT_GETVFSSTAT COMMON_INTERCEPT_FUNCTION(getvfsstat)
+#else
+#define INIT_GETVFSSTAT
+#endif
+
+#if SANITIZER_INTERCEPT_REGEX
+INTERCEPTOR(int, regcomp, void *preg, const char *pattern, int cflags) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, regcomp, preg, pattern, cflags);
+ if (pattern)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, pattern, REAL(strlen)(pattern) + 1);
+ int res = REAL(regcomp)(preg, pattern, cflags);
+ if (!res)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, preg, struct_regex_sz);
+ return res;
+}
+INTERCEPTOR(int, regexec, const void *preg, const char *string, SIZE_T nmatch,
+ struct __sanitizer_regmatch *pmatch[], int eflags) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, regexec, preg, string, nmatch, pmatch, eflags);
+ if (preg)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
+ if (string)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, string, REAL(strlen)(string) + 1);
+ int res = REAL(regexec)(preg, string, nmatch, pmatch, eflags);
+ if (!res && pmatch)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pmatch, nmatch * struct_regmatch_sz);
+ return res;
+}
+INTERCEPTOR(SIZE_T, regerror, int errcode, const void *preg, char *errbuf,
+ SIZE_T errbuf_size) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, regerror, errcode, preg, errbuf, errbuf_size);
+ if (preg)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
+ SIZE_T res = REAL(regerror)(errcode, preg, errbuf, errbuf_size);
+ if (errbuf)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errbuf, REAL(strlen)(errbuf) + 1);
+ return res;
+}
+INTERCEPTOR(void, regfree, const void *preg) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, regfree, preg);
+ if (preg)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
+ REAL(regfree)(preg);
+}
+#define INIT_REGEX \
+ COMMON_INTERCEPT_FUNCTION(regcomp); \
+ COMMON_INTERCEPT_FUNCTION(regexec); \
+ COMMON_INTERCEPT_FUNCTION(regerror); \
+ COMMON_INTERCEPT_FUNCTION(regfree);
+#else
+#define INIT_REGEX
+#endif
+
+#if SANITIZER_INTERCEPT_REGEXSUB
+INTERCEPTOR(SSIZE_T, regnsub, char *buf, SIZE_T bufsiz, const char *sub,
+ const struct __sanitizer_regmatch *rm, const char *str) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, regnsub, buf, bufsiz, sub, rm, str);
+ if (sub)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, REAL(strlen)(sub) + 1);
+ // The implementation demands and hardcodes 10 elements
+ if (rm)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);
+ if (str)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1);
+ SSIZE_T res = REAL(regnsub)(buf, bufsiz, sub, rm, str);
+ if (res > 0 && buf)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
+ return res;
+}
+INTERCEPTOR(SSIZE_T, regasub, char **buf, const char *sub,
+ const struct __sanitizer_regmatch *rm, const char *sstr) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, regasub, buf, sub, rm, sstr);
+ if (sub)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, REAL(strlen)(sub) + 1);
+ // Hardcode 10 elements as this is hardcoded size
+ if (rm)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);
+ if (sstr)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, sstr, REAL(strlen)(sstr) + 1);
+ SSIZE_T res = REAL(regasub)(buf, sub, rm, sstr);
+ if (res > 0 && buf) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sizeof(char *));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *buf, REAL(strlen)(*buf) + 1);
+ }
+ return res;
+}
+
+#define INIT_REGEXSUB \
+ COMMON_INTERCEPT_FUNCTION(regnsub); \
+ COMMON_INTERCEPT_FUNCTION(regasub);
+#else
+#define INIT_REGEXSUB
+#endif
+
+#if SANITIZER_INTERCEPT_FTS
+INTERCEPTOR(void *, fts_open, char *const *path_argv, int options,
+ int (*compar)(void **, void **)) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, fts_open, path_argv, options, compar);
+ if (path_argv) {
+ for (char *const *pa = path_argv; ; ++pa) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
+ if (!*pa)
+ break;
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1);
+ }
+ }
+ // TODO(kamil): handle compar callback
+ void *fts = REAL(fts_open)(path_argv, options, compar);
+ if (fts)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, fts, struct_FTS_sz);
+ return fts;
+}
+
+INTERCEPTOR(void *, fts_read, void *ftsp) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, fts_read, ftsp);
+ if (ftsp)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
+ void *ftsent = REAL(fts_read)(ftsp);
+ if (ftsent)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);
+ return ftsent;
+}
+
+INTERCEPTOR(void *, fts_children, void *ftsp, int options) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, fts_children, ftsp, options);
+ if (ftsp)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
+ void *ftsent = REAL(fts_children)(ftsp, options);
+ if (ftsent)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);
+ return ftsent;
+}
+
+INTERCEPTOR(int, fts_set, void *ftsp, void *f, int options) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, fts_set, ftsp, f, options);
+ if (ftsp)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
+ if (f)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, f, struct_FTSENT_sz);
+ return REAL(fts_set)(ftsp, f, options);
+}
+
+INTERCEPTOR(int, fts_close, void *ftsp) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, fts_close, ftsp);
+ if (ftsp)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
+ return REAL(fts_close)(ftsp);
+}
+#define INIT_FTS \
+ COMMON_INTERCEPT_FUNCTION(fts_open); \
+ COMMON_INTERCEPT_FUNCTION(fts_read); \
+ COMMON_INTERCEPT_FUNCTION(fts_children); \
+ COMMON_INTERCEPT_FUNCTION(fts_set); \
+ COMMON_INTERCEPT_FUNCTION(fts_close);
+#else
+#define INIT_FTS
+#endif
+
+#if SANITIZER_INTERCEPT_SYSCTL
+INTERCEPTOR(int, sysctl, int *name, unsigned int namelen, void *oldp,
+ SIZE_T *oldlenp, void *newp, SIZE_T newlen) {
+ void *ctx;
+ if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
+ return internal_sysctl(name, namelen, oldp, oldlenp, newp, newlen);
+ COMMON_INTERCEPTOR_ENTER(ctx, sysctl, name, namelen, oldp, oldlenp, newp,
+ newlen);
+ if (name)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, name, namelen * sizeof(*name));
+ if (oldlenp)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));
+ if (newp && newlen)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);
+ int res = REAL(sysctl)(name, namelen, oldp, oldlenp, newp, newlen);
+ if (!res) {
+ if (oldlenp) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));
+ if (oldp)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);
+ }
+ }
+ return res;
+}
+
+INTERCEPTOR(int, sysctlbyname, char *sname, void *oldp, SIZE_T *oldlenp,
+ void *newp, SIZE_T newlen) {
+ void *ctx;
+ if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
+ return internal_sysctlbyname(sname, oldp, oldlenp, newp, newlen);
+ COMMON_INTERCEPTOR_ENTER(ctx, sysctlbyname, sname, oldp, oldlenp, newp,
+ newlen);
+ if (sname)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
+ if (oldlenp)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));
+ if (newp && newlen)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);
+ int res = REAL(sysctlbyname)(sname, oldp, oldlenp, newp, newlen);
+ if (!res) {
+ if (oldlenp) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));
+ if (oldp)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);
+ }
+ }
+ return res;
+}
+
+INTERCEPTOR(int, sysctlnametomib, const char *sname, int *name,
+ SIZE_T *namelenp) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, sysctlnametomib, sname, name, namelenp);
+ if (sname)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
+ if (namelenp)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));
+ int res = REAL(sysctlnametomib)(sname, name, namelenp);
+ if (!res) {
+ if (namelenp) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));
+ if (name)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));
+ }
+ }
+ return res;
+}
+
+#define INIT_SYSCTL \
+ COMMON_INTERCEPT_FUNCTION(sysctl); \
+ COMMON_INTERCEPT_FUNCTION(sysctlbyname); \
+ COMMON_INTERCEPT_FUNCTION(sysctlnametomib);
+#else
+#define INIT_SYSCTL
+#endif
+
+#if SANITIZER_INTERCEPT_ASYSCTL
+INTERCEPTOR(void *, asysctl, const int *name, SIZE_T namelen, SIZE_T *len) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, asysctl, name, namelen, len);
+ if (name)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, name, sizeof(*name) * namelen);
+ void *res = REAL(asysctl)(name, namelen, len);
+ if (res && len) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
+ }
+ return res;
+}
+
+INTERCEPTOR(void *, asysctlbyname, const char *sname, SIZE_T *len) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, asysctlbyname, sname, len);
+ if (sname)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
+ void *res = REAL(asysctlbyname)(sname, len);
+ if (res && len) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
+ }
+ return res;
+}
+#define INIT_ASYSCTL \
+ COMMON_INTERCEPT_FUNCTION(asysctl); \
+ COMMON_INTERCEPT_FUNCTION(asysctlbyname);
+#else
+#define INIT_ASYSCTL
+#endif
+
+#if SANITIZER_INTERCEPT_SYSCTLGETMIBINFO
+INTERCEPTOR(int, sysctlgetmibinfo, char *sname, int *name,
+ unsigned int *namelenp, char *cname, SIZE_T *csz, void **rnode,
+ int v) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, sysctlgetmibinfo, sname, name, namelenp, cname,
+ csz, rnode, v);
+ if (sname)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
+ if (namelenp)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));
+ if (csz)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, csz, sizeof(*csz));
+ // Skip rnode, it's rarely used and not trivial to sanitize
+ // It's also used mostly internally
+ int res = REAL(sysctlgetmibinfo)(sname, name, namelenp, cname, csz, rnode, v);
+ if (!res) {
+ if (namelenp) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));
+ if (name)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));
+ }
+ if (csz) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, csz, sizeof(*csz));
+ if (cname)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cname, *csz);
+ }
+ }
+ return res;
+}
+#define INIT_SYSCTLGETMIBINFO \
+ COMMON_INTERCEPT_FUNCTION(sysctlgetmibinfo);
+#else
+#define INIT_SYSCTLGETMIBINFO
+#endif
+
+#if SANITIZER_INTERCEPT_NL_LANGINFO
+INTERCEPTOR(char *, nl_langinfo, long item) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, nl_langinfo, item);
+ char *ret = REAL(nl_langinfo)(item);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, REAL(strlen)(ret) + 1);
+ return ret;
+}
+#define INIT_NL_LANGINFO COMMON_INTERCEPT_FUNCTION(nl_langinfo)
+#else
+#define INIT_NL_LANGINFO
+#endif
+
+#if SANITIZER_INTERCEPT_MODCTL
+INTERCEPTOR(int, modctl, int operation, void *argp) {
+ void *ctx;
+ int ret;
+ COMMON_INTERCEPTOR_ENTER(ctx, modctl, operation, argp);
+
+ if (operation == modctl_load) {
+ if (argp) {
+ __sanitizer_modctl_load_t *ml = (__sanitizer_modctl_load_t *)argp;
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, ml, sizeof(*ml));
+ if (ml->ml_filename)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_filename,
+ REAL(strlen)(ml->ml_filename) + 1);
+ if (ml->ml_props)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_props, ml->ml_propslen);
+ }
+ ret = REAL(modctl)(operation, argp);
+ } else if (operation == modctl_unload) {
+ if (argp) {
+ const char *name = (const char *)argp;
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
+ }
+ ret = REAL(modctl)(operation, argp);
+ } else if (operation == modctl_stat) {
+ uptr iov_len;
+ struct __sanitizer_iovec *iov = (struct __sanitizer_iovec *)argp;
+ if (iov) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, iov, sizeof(*iov));
+ iov_len = iov->iov_len;
+ }
+ ret = REAL(modctl)(operation, argp);
+ if (iov)
+ COMMON_INTERCEPTOR_WRITE_RANGE(
+ ctx, iov->iov_base, Min(iov_len, iov->iov_len));
+ } else if (operation == modctl_exists)
+ ret = REAL(modctl)(operation, argp);
+ else
+ ret = REAL(modctl)(operation, argp);
+
+ return ret;
+}
+#define INIT_MODCTL COMMON_INTERCEPT_FUNCTION(modctl)
+#else
+#define INIT_MODCTL
+#endif
+
+#if SANITIZER_INTERCEPT_STRTONUM
+INTERCEPTOR(long long, strtonum, const char *nptr, long long minval,
+ long long maxval, const char **errstr) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strtonum, nptr, minval, maxval, errstr);
+
+ // TODO(kamil): Implement strtoll as a common inteceptor
+ char *real_endptr;
+ long long ret = (long long)REAL(strtoimax)(nptr, &real_endptr, 10);
+ StrtolFixAndCheck(ctx, nptr, nullptr, real_endptr, 10);
+
+ ret = REAL(strtonum)(nptr, minval, maxval, errstr);
+ if (errstr) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errstr, sizeof(const char *));
+ if (*errstr)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *errstr, REAL(strlen)(*errstr) + 1);
+ }
+ return ret;
+}
+#define INIT_STRTONUM COMMON_INTERCEPT_FUNCTION(strtonum)
+#else
+#define INIT_STRTONUM
+#endif
+
+#if SANITIZER_INTERCEPT_FPARSELN
+INTERCEPTOR(char *, fparseln, __sanitizer_FILE *stream, SIZE_T *len,
+ SIZE_T *lineno, const char delim[3], int flags) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, fparseln, stream, len, lineno, delim, flags);
+ if (lineno)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, lineno, sizeof(*lineno));
+ if (delim)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, delim, sizeof(delim[0]) * 3);
+ char *ret = REAL(fparseln)(stream, len, lineno, delim, flags);
+ if (ret) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, REAL(strlen)(ret) + 1);
+ if (len)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
+ if (lineno)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineno, sizeof(*lineno));
+ }
+ return ret;
+}
+#define INIT_FPARSELN COMMON_INTERCEPT_FUNCTION(fparseln)
+#else
+#define INIT_FPARSELN
+#endif
+
+#if SANITIZER_INTERCEPT_STATVFS1
+INTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags);
+ if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
+ int res = REAL(statvfs1)(path, buf, flags);
+ if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
+ return res;
+}
+INTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs1, fd, buf, flags);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ int res = REAL(fstatvfs1)(fd, buf, flags);
+ if (!res) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
+ if (fd >= 0)
+ COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
+ }
+ return res;
+}
+#define INIT_STATVFS1 \
+ COMMON_INTERCEPT_FUNCTION(statvfs1); \
+ COMMON_INTERCEPT_FUNCTION(fstatvfs1);
+#else
+#define INIT_STATVFS1
+#endif
+
+#if SANITIZER_INTERCEPT_STRTOI
+INTERCEPTOR(INTMAX_T, strtoi, const char *nptr, char **endptr, int base,
+ INTMAX_T low, INTMAX_T high, int *rstatus) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strtoi, nptr, endptr, base, low, high, rstatus);
+ char *real_endptr;
+ INTMAX_T ret = REAL(strtoi)(nptr, &real_endptr, base, low, high, rstatus);
+ StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
+ if (rstatus)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));
+ return ret;
+}
+
+INTERCEPTOR(UINTMAX_T, strtou, const char *nptr, char **endptr, int base,
+ UINTMAX_T low, UINTMAX_T high, int *rstatus) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strtou, nptr, endptr, base, low, high, rstatus);
+ char *real_endptr;
+ UINTMAX_T ret = REAL(strtou)(nptr, &real_endptr, base, low, high, rstatus);
+ StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
+ if (rstatus)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));
+ return ret;
+}
+#define INIT_STRTOI \
+ COMMON_INTERCEPT_FUNCTION(strtoi); \
+ COMMON_INTERCEPT_FUNCTION(strtou)
+#else
+#define INIT_STRTOI
+#endif
+
+#if SANITIZER_INTERCEPT_CAPSICUM
+#define CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights, ...) \
+ { \
+ void *ctx; \
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_init, rights, ##__VA_ARGS__); \
+ if (rights) \
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \
+ __sanitizer_cap_rights_t *ret = \
+ REAL(cap_rights_init)(rights, ##__VA_ARGS__); \
+ if (ret) \
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \
+ return ret; \
+ }
+
+#define CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights, ...) \
+ { \
+ void *ctx; \
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_set, rights, ##__VA_ARGS__); \
+ if (rights) \
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \
+ __sanitizer_cap_rights_t *ret = \
+ REAL(cap_rights_set)(rights, ##__VA_ARGS__); \
+ if (ret) \
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \
+ return ret; \
+ }
+
+#define CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights, ...) \
+ { \
+ void *ctx; \
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_clear, rights, ##__VA_ARGS__); \
+ if (rights) \
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \
+ __sanitizer_cap_rights_t *ret = \
+ REAL(cap_rights_clear)(rights, ##__VA_ARGS__); \
+ if (ret) \
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \
+ return ret; \
+ }
+
+#define CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights, ...) \
+ { \
+ void *ctx; \
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_set, rights, ##__VA_ARGS__); \
+ if (rights) \
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \
+ return REAL(cap_rights_is_set)(rights, ##__VA_ARGS__); \
+ }
+
+INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_init,
+ __sanitizer_cap_rights_t *rights) {
+ CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights);
+}
+
+INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_set,
+ __sanitizer_cap_rights_t *rights) {
+ CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights);
+}
+
+INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_clear,
+ __sanitizer_cap_rights_t *rights) {
+ CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights);
+}
+
+INTERCEPTOR(bool, cap_rights_is_set,
+ __sanitizer_cap_rights_t *rights) {
+ CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights);
+}
+
+INTERCEPTOR(int, cap_rights_limit, int fd,
+ const __sanitizer_cap_rights_t *rights) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_limit, fd, rights);
+ if (rights)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));
+
+ return REAL(cap_rights_limit)(fd, rights);
+}
+
+INTERCEPTOR(int, cap_rights_get, int fd, __sanitizer_cap_rights_t *rights) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_get, fd, rights);
+ int ret = REAL(cap_rights_get)(fd, rights);
+ if (!ret && rights)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rights, sizeof(*rights));
+
+ return ret;
+}
+
+INTERCEPTOR(bool, cap_rights_is_valid, const __sanitizer_cap_rights_t *rights) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_valid, rights);
+ if (rights)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));
+
+ return REAL(cap_rights_is_valid(rights));
+}
+
+INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_merge,
+ __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_merge, dst, src);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
+
+ __sanitizer_cap_rights *ret = REAL(cap_rights_merge)(dst, src);
+ if (dst)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
+
+ return ret;
+}
+
+INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_remove,
+ __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_remove, dst, src);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
+
+ __sanitizer_cap_rights *ret = REAL(cap_rights_remove)(dst, src);
+ if (dst)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
+
+ return ret;
+}
+
+INTERCEPTOR(bool, cap_rights_contains, const __sanitizer_cap_rights *big,
+ const __sanitizer_cap_rights *little) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_contains, big, little);
+ if (little)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, little, sizeof(*little));
+ if (big)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, big, sizeof(*big));
+
+ return REAL(cap_rights_contains)(big, little);
+}
+
+INTERCEPTOR(int, cap_ioctls_limit, int fd, const uptr *cmds, SIZE_T ncmds) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_limit, fd, cmds, ncmds);
+ if (cmds)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cmds, sizeof(*cmds) * ncmds);
+
+ return REAL(cap_ioctls_limit)(fd, cmds, ncmds);
+}
+
+INTERCEPTOR(int, cap_ioctls_get, int fd, uptr *cmds, SIZE_T maxcmds) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_get, fd, cmds, maxcmds);
+ int ret = REAL(cap_ioctls_get)(fd, cmds, maxcmds);
+ if (!ret && cmds)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cmds, sizeof(*cmds) * maxcmds);
+
+ return ret;
+}
+#define INIT_CAPSICUM \
+ COMMON_INTERCEPT_FUNCTION(cap_rights_init); \
+ COMMON_INTERCEPT_FUNCTION(cap_rights_set); \
+ COMMON_INTERCEPT_FUNCTION(cap_rights_clear); \
+ COMMON_INTERCEPT_FUNCTION(cap_rights_is_set); \
+ COMMON_INTERCEPT_FUNCTION(cap_rights_get); \
+ COMMON_INTERCEPT_FUNCTION(cap_rights_limit); \
+ COMMON_INTERCEPT_FUNCTION(cap_rights_contains); \
+ COMMON_INTERCEPT_FUNCTION(cap_rights_remove); \
+ COMMON_INTERCEPT_FUNCTION(cap_rights_merge); \
+ COMMON_INTERCEPT_FUNCTION(cap_rights_is_valid); \
+ COMMON_INTERCEPT_FUNCTION(cap_ioctls_get); \
+ COMMON_INTERCEPT_FUNCTION(cap_ioctls_limit)
+#else
+#define INIT_CAPSICUM
+#endif
+
+#if SANITIZER_INTERCEPT_SHA1
+INTERCEPTOR(void, SHA1Init, void *context) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, SHA1Init, context);
+ REAL(SHA1Init)(context);
+ if (context)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);
+}
+INTERCEPTOR(void, SHA1Update, void *context, const u8 *data, unsigned len) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, SHA1Update, context, data, len);
+ if (data && len > 0)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
+ if (context)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
+ REAL(SHA1Update)(context, data, len);
+ if (context)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);
+}
+INTERCEPTOR(void, SHA1Final, u8 digest[20], void *context) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, SHA1Final, digest, context);
+ if (context)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
+ REAL(SHA1Final)(digest, context);
+ if (digest)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);
+}
+INTERCEPTOR(void, SHA1Transform, u32 state[5], u8 buffer[64]) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, SHA1Transform, state, buffer);
+ if (state)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);
+ if (buffer)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u8) * 64);
+ REAL(SHA1Transform)(state, buffer);
+ if (state)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);
+}
+INTERCEPTOR(char *, SHA1End, void *context, char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, SHA1End, context, buf);
+ if (context)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
+ char *ret = REAL(SHA1End)(context, buf);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
+ return ret;
+}
+INTERCEPTOR(char *, SHA1File, char *filename, char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, SHA1File, filename, buf);
+ if (filename)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
+ char *ret = REAL(SHA1File)(filename, buf);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
+ return ret;
+}
+INTERCEPTOR(char *, SHA1FileChunk, char *filename, char *buf, OFF_T offset,
+ OFF_T length) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, SHA1FileChunk, filename, buf, offset, length);
+ if (filename)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
+ char *ret = REAL(SHA1FileChunk)(filename, buf, offset, length);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
+ return ret;
+}
+INTERCEPTOR(char *, SHA1Data, u8 *data, SIZE_T len, char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, SHA1Data, data, len, buf);
+ if (data)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
+ char *ret = REAL(SHA1Data)(data, len, buf);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
+ return ret;
+}
+#define INIT_SHA1 \
+ COMMON_INTERCEPT_FUNCTION(SHA1Init); \
+ COMMON_INTERCEPT_FUNCTION(SHA1Update); \
+ COMMON_INTERCEPT_FUNCTION(SHA1Final); \
+ COMMON_INTERCEPT_FUNCTION(SHA1Transform); \
+ COMMON_INTERCEPT_FUNCTION(SHA1End); \
+ COMMON_INTERCEPT_FUNCTION(SHA1File); \
+ COMMON_INTERCEPT_FUNCTION(SHA1FileChunk); \
+ COMMON_INTERCEPT_FUNCTION(SHA1Data)
+#else
+#define INIT_SHA1
+#endif
+
+#if SANITIZER_INTERCEPT_MD4
+INTERCEPTOR(void, MD4Init, void *context) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD4Init, context);
+ REAL(MD4Init)(context);
+ if (context)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);
+}
+
+INTERCEPTOR(void, MD4Update, void *context, const unsigned char *data,
+ unsigned int len) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD4Update, context, data, len);
+ if (data && len > 0)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
+ if (context)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
+ REAL(MD4Update)(context, data, len);
+ if (context)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);
+}
+
+INTERCEPTOR(void, MD4Final, unsigned char digest[16], void *context) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD4Final, digest, context);
+ if (context)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
+ REAL(MD4Final)(digest, context);
+ if (digest)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
+}
+
+INTERCEPTOR(char *, MD4End, void *context, char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD4End, context, buf);
+ if (context)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
+ char *ret = REAL(MD4End)(context, buf);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
+ return ret;
+}
+
+INTERCEPTOR(char *, MD4File, const char *filename, char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD4File, filename, buf);
+ if (filename)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
+ char *ret = REAL(MD4File)(filename, buf);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
+ return ret;
+}
+
+INTERCEPTOR(char *, MD4Data, const unsigned char *data, unsigned int len,
+ char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD4Data, data, len, buf);
+ if (data && len > 0)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
+ char *ret = REAL(MD4Data)(data, len, buf);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
+ return ret;
+}
+
+#define INIT_MD4 \
+ COMMON_INTERCEPT_FUNCTION(MD4Init); \
+ COMMON_INTERCEPT_FUNCTION(MD4Update); \
+ COMMON_INTERCEPT_FUNCTION(MD4Final); \
+ COMMON_INTERCEPT_FUNCTION(MD4End); \
+ COMMON_INTERCEPT_FUNCTION(MD4File); \
+ COMMON_INTERCEPT_FUNCTION(MD4Data)
+#else
+#define INIT_MD4
+#endif
+
+#if SANITIZER_INTERCEPT_RMD160
+INTERCEPTOR(void, RMD160Init, void *context) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, RMD160Init, context);
+ REAL(RMD160Init)(context);
+ if (context)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);
+}
+INTERCEPTOR(void, RMD160Update, void *context, const u8 *data, unsigned len) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, RMD160Update, context, data, len);
+ if (data && len > 0)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
+ if (context)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
+ REAL(RMD160Update)(context, data, len);
+ if (context)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);
+}
+INTERCEPTOR(void, RMD160Final, u8 digest[20], void *context) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, RMD160Final, digest, context);
+ if (context)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
+ REAL(RMD160Final)(digest, context);
+ if (digest)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);
+}
+INTERCEPTOR(void, RMD160Transform, u32 state[5], u16 buffer[16]) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, RMD160Transform, state, buffer);
+ if (state)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);
+ if (buffer)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u32) * 16);
+ REAL(RMD160Transform)(state, buffer);
+ if (state)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);
+}
+INTERCEPTOR(char *, RMD160End, void *context, char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, RMD160End, context, buf);
+ if (context)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
+ char *ret = REAL(RMD160End)(context, buf);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
+ return ret;
+}
+INTERCEPTOR(char *, RMD160File, char *filename, char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, RMD160File, filename, buf);
+ if (filename)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
+ char *ret = REAL(RMD160File)(filename, buf);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
+ return ret;
+}
+INTERCEPTOR(char *, RMD160FileChunk, char *filename, char *buf, OFF_T offset,
+ OFF_T length) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, RMD160FileChunk, filename, buf, offset, length);
+ if (filename)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
+ char *ret = REAL(RMD160FileChunk)(filename, buf, offset, length);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
+ return ret;
+}
+INTERCEPTOR(char *, RMD160Data, u8 *data, SIZE_T len, char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, RMD160Data, data, len, buf);
+ if (data && len > 0)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
+ char *ret = REAL(RMD160Data)(data, len, buf);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
+ return ret;
+}
+#define INIT_RMD160 \
+ COMMON_INTERCEPT_FUNCTION(RMD160Init); \
+ COMMON_INTERCEPT_FUNCTION(RMD160Update); \
+ COMMON_INTERCEPT_FUNCTION(RMD160Final); \
+ COMMON_INTERCEPT_FUNCTION(RMD160Transform); \
+ COMMON_INTERCEPT_FUNCTION(RMD160End); \
+ COMMON_INTERCEPT_FUNCTION(RMD160File); \
+ COMMON_INTERCEPT_FUNCTION(RMD160FileChunk); \
+ COMMON_INTERCEPT_FUNCTION(RMD160Data)
+#else
+#define INIT_RMD160
+#endif
+
+#if SANITIZER_INTERCEPT_MD5
+INTERCEPTOR(void, MD5Init, void *context) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD5Init, context);
+ REAL(MD5Init)(context);
+ if (context)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz);
+}
+
+INTERCEPTOR(void, MD5Update, void *context, const unsigned char *data,
+ unsigned int len) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD5Update, context, data, len);
+ if (data && len > 0)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
+ if (context)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz);
+ REAL(MD5Update)(context, data, len);
+ if (context)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz);
+}
+
+INTERCEPTOR(void, MD5Final, unsigned char digest[16], void *context) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD5Final, digest, context);
+ if (context)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz);
+ REAL(MD5Final)(digest, context);
+ if (digest)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
+}
+
+INTERCEPTOR(char *, MD5End, void *context, char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD5End, context, buf);
+ if (context)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz);
+ char *ret = REAL(MD5End)(context, buf);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length);
+ return ret;
+}
+
+INTERCEPTOR(char *, MD5File, const char *filename, char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD5File, filename, buf);
+ if (filename)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
+ char *ret = REAL(MD5File)(filename, buf);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length);
+ return ret;
+}
+
+INTERCEPTOR(char *, MD5Data, const unsigned char *data, unsigned int len,
+ char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD5Data, data, len, buf);
+ if (data && len > 0)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
+ char *ret = REAL(MD5Data)(data, len, buf);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length);
+ return ret;
+}
+
+#define INIT_MD5 \
+ COMMON_INTERCEPT_FUNCTION(MD5Init); \
+ COMMON_INTERCEPT_FUNCTION(MD5Update); \
+ COMMON_INTERCEPT_FUNCTION(MD5Final); \
+ COMMON_INTERCEPT_FUNCTION(MD5End); \
+ COMMON_INTERCEPT_FUNCTION(MD5File); \
+ COMMON_INTERCEPT_FUNCTION(MD5Data)
+#else
+#define INIT_MD5
+#endif
+
+#if SANITIZER_INTERCEPT_FSEEK
+INTERCEPTOR(int, fseek, __sanitizer_FILE *stream, long int offset, int whence) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, fseek, stream, offset, whence);
+ return REAL(fseek)(stream, offset, whence);
+}
+INTERCEPTOR(int, fseeko, __sanitizer_FILE *stream, OFF_T offset, int whence) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, fseeko, stream, offset, whence);
+ return REAL(fseeko)(stream, offset, whence);
+}
+INTERCEPTOR(long int, ftell, __sanitizer_FILE *stream) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, ftell, stream);
+ return REAL(ftell)(stream);
+}
+INTERCEPTOR(OFF_T, ftello, __sanitizer_FILE *stream) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, ftello, stream);
+ return REAL(ftello)(stream);
+}
+INTERCEPTOR(void, rewind, __sanitizer_FILE *stream) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, rewind, stream);
+ return REAL(rewind)(stream);
+}
+INTERCEPTOR(int, fgetpos, __sanitizer_FILE *stream, void *pos) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, fgetpos, stream, pos);
+ int ret = REAL(fgetpos)(stream, pos);
+ if (pos && !ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pos, fpos_t_sz);
+ return ret;
+}
+INTERCEPTOR(int, fsetpos, __sanitizer_FILE *stream, const void *pos) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, fsetpos, stream, pos);
+ if (pos)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, pos, fpos_t_sz);
+ return REAL(fsetpos)(stream, pos);
+}
+#define INIT_FSEEK \
+ COMMON_INTERCEPT_FUNCTION(fseek); \
+ COMMON_INTERCEPT_FUNCTION(fseeko); \
+ COMMON_INTERCEPT_FUNCTION(ftell); \
+ COMMON_INTERCEPT_FUNCTION(ftello); \
+ COMMON_INTERCEPT_FUNCTION(rewind); \
+ COMMON_INTERCEPT_FUNCTION(fgetpos); \
+ COMMON_INTERCEPT_FUNCTION(fsetpos)
+#else
+#define INIT_FSEEK
+#endif
+
+#if SANITIZER_INTERCEPT_MD2
+INTERCEPTOR(void, MD2Init, void *context) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD2Init, context);
+ REAL(MD2Init)(context);
+ if (context)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);
+}
+
+INTERCEPTOR(void, MD2Update, void *context, const unsigned char *data,
+ unsigned int len) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD2Update, context, data, len);
+ if (data && len > 0)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
+ if (context)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
+ REAL(MD2Update)(context, data, len);
+ if (context)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);
+}
+
+INTERCEPTOR(void, MD2Final, unsigned char digest[16], void *context) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD2Final, digest, context);
+ if (context)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
+ REAL(MD2Final)(digest, context);
+ if (digest)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
+}
+
+INTERCEPTOR(char *, MD2End, void *context, char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD2End, context, buf);
+ if (context)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
+ char *ret = REAL(MD2End)(context, buf);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
+ return ret;
+}
+
+INTERCEPTOR(char *, MD2File, const char *filename, char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD2File, filename, buf);
+ if (filename)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
+ char *ret = REAL(MD2File)(filename, buf);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
+ return ret;
+}
+
+INTERCEPTOR(char *, MD2Data, const unsigned char *data, unsigned int len,
+ char *buf) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, MD2Data, data, len, buf);
+ if (data && len > 0)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
+ char *ret = REAL(MD2Data)(data, len, buf);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
+ return ret;
+}
+
+#define INIT_MD2 \
+ COMMON_INTERCEPT_FUNCTION(MD2Init); \
+ COMMON_INTERCEPT_FUNCTION(MD2Update); \
+ COMMON_INTERCEPT_FUNCTION(MD2Final); \
+ COMMON_INTERCEPT_FUNCTION(MD2End); \
+ COMMON_INTERCEPT_FUNCTION(MD2File); \
+ COMMON_INTERCEPT_FUNCTION(MD2Data)
+#else
+#define INIT_MD2
+#endif
+
+#if SANITIZER_INTERCEPT_SHA2
+#define SHA2_INTERCEPTORS(LEN, SHA2_STATE_T) \
+ INTERCEPTOR(void, SHA##LEN##_Init, void *context) { \
+ void *ctx; \
+ COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Init, context); \
+ REAL(SHA##LEN##_Init)(context); \
+ if (context) \
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
+ } \
+ INTERCEPTOR(void, SHA##LEN##_Update, void *context, \
+ const u8 *data, SIZE_T len) { \
+ void *ctx; \
+ COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Update, context, data, len); \
+ if (data && len > 0) \
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \
+ if (context) \
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
+ REAL(SHA##LEN##_Update)(context, data, len); \
+ if (context) \
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
+ } \
+ INTERCEPTOR(void, SHA##LEN##_Final, u8 digest[LEN/8], \
+ void *context) { \
+ void *ctx; \
+ CHECK_EQ(SHA##LEN##_digest_length, LEN/8); \
+ COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Final, digest, context); \
+ if (context) \
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
+ REAL(SHA##LEN##_Final)(digest, context); \
+ if (digest) \
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, \
+ sizeof(digest[0]) * \
+ SHA##LEN##_digest_length); \
+ } \
+ INTERCEPTOR(char *, SHA##LEN##_End, void *context, char *buf) { \
+ void *ctx; \
+ COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_End, context, buf); \
+ if (context) \
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
+ char *ret = REAL(SHA##LEN##_End)(context, buf); \
+ if (ret) \
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
+ return ret; \
+ } \
+ INTERCEPTOR(char *, SHA##LEN##_File, const char *filename, char *buf) { \
+ void *ctx; \
+ COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_File, filename, buf); \
+ if (filename) \
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\
+ char *ret = REAL(SHA##LEN##_File)(filename, buf); \
+ if (ret) \
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
+ return ret; \
+ } \
+ INTERCEPTOR(char *, SHA##LEN##_FileChunk, const char *filename, char *buf, \
+ OFF_T offset, OFF_T length) { \
+ void *ctx; \
+ COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_FileChunk, filename, buf, offset, \
+ length); \
+ if (filename) \
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\
+ char *ret = REAL(SHA##LEN##_FileChunk)(filename, buf, offset, length); \
+ if (ret) \
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
+ return ret; \
+ } \
+ INTERCEPTOR(char *, SHA##LEN##_Data, u8 *data, SIZE_T len, char *buf) { \
+ void *ctx; \
+ COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Data, data, len, buf); \
+ if (data && len > 0) \
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \
+ char *ret = REAL(SHA##LEN##_Data)(data, len, buf); \
+ if (ret) \
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
+ return ret; \
+ }
+
+SHA2_INTERCEPTORS(224, u32);
+SHA2_INTERCEPTORS(256, u32);
+SHA2_INTERCEPTORS(384, u64);
+SHA2_INTERCEPTORS(512, u64);
+
+#define INIT_SHA2_INTECEPTORS(LEN) \
+ COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Init); \
+ COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Update); \
+ COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Final); \
+ COMMON_INTERCEPT_FUNCTION(SHA##LEN##_End); \
+ COMMON_INTERCEPT_FUNCTION(SHA##LEN##_File); \
+ COMMON_INTERCEPT_FUNCTION(SHA##LEN##_FileChunk); \
+ COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Data)
+
+#define INIT_SHA2 \
+ INIT_SHA2_INTECEPTORS(224); \
+ INIT_SHA2_INTECEPTORS(256); \
+ INIT_SHA2_INTECEPTORS(384); \
+ INIT_SHA2_INTECEPTORS(512)
+#undef SHA2_INTERCEPTORS
+#else
+#define INIT_SHA2
+#endif
+
+#if SANITIZER_INTERCEPT_VIS
+INTERCEPTOR(char *, vis, char *dst, int c, int flag, int nextc) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, vis, dst, c, flag, nextc);
+ char *end = REAL(vis)(dst, c, flag, nextc);
+ // dst is NULL terminated and end points to the NULL char
+ if (dst && end)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
+ return end;
+}
+INTERCEPTOR(char *, nvis, char *dst, SIZE_T dlen, int c, int flag, int nextc) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, nvis, dst, dlen, c, flag, nextc);
+ char *end = REAL(nvis)(dst, dlen, c, flag, nextc);
+ // nvis cannot make sure the dst is NULL terminated
+ if (dst && end)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
+ return end;
+}
+INTERCEPTOR(int, strvis, char *dst, const char *src, int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strvis, dst, src, flag);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ int len = REAL(strvis)(dst, src, flag);
+ if (dst)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
+ return len;
+}
+INTERCEPTOR(int, stravis, char **dst, const char *src, int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, stravis, dst, src, flag);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ int len = REAL(stravis)(dst, src, flag);
+ if (dst) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(char *));
+ if (*dst)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *dst, len + 1);
+ }
+ return len;
+}
+INTERCEPTOR(int, strnvis, char *dst, SIZE_T dlen, const char *src, int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strnvis, dst, dlen, src, flag);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ int len = REAL(strnvis)(dst, dlen, src, flag);
+ // The interface will be valid even if there is no space for NULL char
+ if (dst && len > 0)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
+ return len;
+}
+INTERCEPTOR(int, strvisx, char *dst, const char *src, SIZE_T len, int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strvisx, dst, src, len, flag);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
+ int ret = REAL(strvisx)(dst, src, len, flag);
+ if (dst)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+INTERCEPTOR(int, strnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
+ int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strnvisx, dst, dlen, src, len, flag);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
+ int ret = REAL(strnvisx)(dst, dlen, src, len, flag);
+ if (dst && ret >= 0)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+INTERCEPTOR(int, strenvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
+ int flag, int *cerr_ptr) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strenvisx, dst, dlen, src, len, flag, cerr_ptr);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
+ // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold
+ // according to the implementation
+ if (cerr_ptr)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));
+ int ret = REAL(strenvisx)(dst, dlen, src, len, flag, cerr_ptr);
+ if (dst && ret >= 0)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ if (cerr_ptr)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));
+ return ret;
+}
+INTERCEPTOR(char *, svis, char *dst, int c, int flag, int nextc,
+ const char *extra) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, svis, dst, c, flag, nextc, extra);
+ if (extra)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
+ char *end = REAL(svis)(dst, c, flag, nextc, extra);
+ if (dst && end)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
+ return end;
+}
+INTERCEPTOR(char *, snvis, char *dst, SIZE_T dlen, int c, int flag, int nextc,
+ const char *extra) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, snvis, dst, dlen, c, flag, nextc, extra);
+ if (extra)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
+ char *end = REAL(snvis)(dst, dlen, c, flag, nextc, extra);
+ if (dst && end)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst,
+ Min((SIZE_T)(end - dst + 1), dlen));
+ return end;
+}
+INTERCEPTOR(int, strsvis, char *dst, const char *src, int flag,
+ const char *extra) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strsvis, dst, src, flag, extra);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ if (extra)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
+ int len = REAL(strsvis)(dst, src, flag, extra);
+ if (dst)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
+ return len;
+}
+INTERCEPTOR(int, strsnvis, char *dst, SIZE_T dlen, const char *src, int flag,
+ const char *extra) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strsnvis, dst, dlen, src, flag, extra);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ if (extra)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
+ int len = REAL(strsnvis)(dst, dlen, src, flag, extra);
+ // The interface will be valid even if there is no space for NULL char
+ if (dst && len >= 0)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
+ return len;
+}
+INTERCEPTOR(int, strsvisx, char *dst, const char *src, SIZE_T len, int flag,
+ const char *extra) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strsvisx, dst, src, len, flag, extra);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
+ if (extra)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
+ int ret = REAL(strsvisx)(dst, src, len, flag, extra);
+ if (dst)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+INTERCEPTOR(int, strsnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
+ int flag, const char *extra) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strsnvisx, dst, dlen, src, len, flag, extra);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
+ if (extra)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
+ int ret = REAL(strsnvisx)(dst, dlen, src, len, flag, extra);
+ if (dst && ret >= 0)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+INTERCEPTOR(int, strsenvisx, char *dst, SIZE_T dlen, const char *src,
+ SIZE_T len, int flag, const char *extra, int *cerr_ptr) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strsenvisx, dst, dlen, src, len, flag, extra,
+ cerr_ptr);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
+ if (extra)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
+ // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold
+ // according to the implementation
+ if (cerr_ptr)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));
+ int ret = REAL(strsenvisx)(dst, dlen, src, len, flag, extra, cerr_ptr);
+ if (dst && ret >= 0)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ if (cerr_ptr)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));
+ return ret;
+}
+INTERCEPTOR(int, unvis, char *cp, int c, int *astate, int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, unvis, cp, c, astate, flag);
+ if (astate)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, astate, sizeof(*astate));
+ int ret = REAL(unvis)(cp, c, astate, flag);
+ if (ret == unvis_valid || ret == unvis_validpush) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cp, sizeof(*cp));
+ }
+ return ret;
+}
+INTERCEPTOR(int, strunvis, char *dst, const char *src) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strunvis, dst, src);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ int ret = REAL(strunvis)(dst, src);
+ if (ret != -1)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+INTERCEPTOR(int, strnunvis, char *dst, SIZE_T dlen, const char *src) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strnunvis, dst, dlen, src);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ int ret = REAL(strnunvis)(dst, dlen, src);
+ if (ret != -1)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+INTERCEPTOR(int, strunvisx, char *dst, const char *src, int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strunvisx, dst, src, flag);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ int ret = REAL(strunvisx)(dst, src, flag);
+ if (ret != -1)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+INTERCEPTOR(int, strnunvisx, char *dst, SIZE_T dlen, const char *src,
+ int flag) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, strnunvisx, dst, dlen, src, flag);
+ if (src)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
+ int ret = REAL(strnunvisx)(dst, dlen, src, flag);
+ if (ret != -1)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
+ return ret;
+}
+#define INIT_VIS \
+ COMMON_INTERCEPT_FUNCTION(vis); \
+ COMMON_INTERCEPT_FUNCTION(nvis); \
+ COMMON_INTERCEPT_FUNCTION(strvis); \
+ COMMON_INTERCEPT_FUNCTION(stravis); \
+ COMMON_INTERCEPT_FUNCTION(strnvis); \
+ COMMON_INTERCEPT_FUNCTION(strvisx); \
+ COMMON_INTERCEPT_FUNCTION(strnvisx); \
+ COMMON_INTERCEPT_FUNCTION(strenvisx); \
+ COMMON_INTERCEPT_FUNCTION(svis); \
+ COMMON_INTERCEPT_FUNCTION(snvis); \
+ COMMON_INTERCEPT_FUNCTION(strsvis); \
+ COMMON_INTERCEPT_FUNCTION(strsnvis); \
+ COMMON_INTERCEPT_FUNCTION(strsvisx); \
+ COMMON_INTERCEPT_FUNCTION(strsnvisx); \
+ COMMON_INTERCEPT_FUNCTION(strsenvisx); \
+ COMMON_INTERCEPT_FUNCTION(unvis); \
+ COMMON_INTERCEPT_FUNCTION(strunvis); \
+ COMMON_INTERCEPT_FUNCTION(strnunvis); \
+ COMMON_INTERCEPT_FUNCTION(strunvisx); \
+ COMMON_INTERCEPT_FUNCTION(strnunvisx)
+#else
+#define INIT_VIS
+#endif
+
+#if SANITIZER_INTERCEPT_CDB
+INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open, const char *path, int flags) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open, path, flags);
+ if (path)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
+ struct __sanitizer_cdbr *cdbr = REAL(cdbr_open)(path, flags);
+ if (cdbr)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));
+ return cdbr;
+}
+
+INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open_mem, void *base, SIZE_T size,
+ int flags, void (*unmap)(void *, void *, SIZE_T), void *cookie) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open_mem, base, size, flags, unmap,
+ cookie);
+ if (base && size)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, base, size);
+ struct __sanitizer_cdbr *cdbr =
+ REAL(cdbr_open_mem)(base, size, flags, unmap, cookie);
+ if (cdbr)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));
+ return cdbr;
+}
+
+INTERCEPTOR(u32, cdbr_entries, struct __sanitizer_cdbr *cdbr) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cdbr_entries, cdbr);
+ if (cdbr)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
+ return REAL(cdbr_entries)(cdbr);
+}
+
+INTERCEPTOR(int, cdbr_get, struct __sanitizer_cdbr *cdbr, u32 index,
+ const void **data, SIZE_T *datalen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cdbr_get, cdbr, index, data, datalen);
+ if (cdbr)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
+ int ret = REAL(cdbr_get)(cdbr, index, data, datalen);
+ if (!ret) {
+ if (data)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));
+ if (datalen)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));
+ if (data && datalen)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);
+ }
+ return ret;
+}
+
+INTERCEPTOR(int, cdbr_find, struct __sanitizer_cdbr *cdbr, const void *key,
+ SIZE_T keylen, const void **data, SIZE_T *datalen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cdbr_find, cdbr, key, keylen, data, datalen);
+ if (cdbr)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
+ if (key)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
+ int ret = REAL(cdbr_find)(cdbr, key, keylen, data, datalen);
+ if (!ret) {
+ if (data)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));
+ if (datalen)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));
+ if (data && datalen)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);
+ }
+ return ret;
+}
+
+INTERCEPTOR(void, cdbr_close, struct __sanitizer_cdbr *cdbr) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cdbr_close, cdbr);
+ if (cdbr)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
+ REAL(cdbr_close)(cdbr);
+}
+
+INTERCEPTOR(struct __sanitizer_cdbw *, cdbw_open) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cdbw_open);
+ struct __sanitizer_cdbw *ret = REAL(cdbw_open)();
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));
+ return ret;
+}
+
+INTERCEPTOR(int, cdbw_put, struct __sanitizer_cdbw *cdbw, const void *key,
+ SIZE_T keylen, const void *data, SIZE_T datalen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put, cdbw, key, keylen, data, datalen);
+ if (cdbw)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
+ if (data && datalen)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);
+ if (key && keylen)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
+ int ret = REAL(cdbw_put)(cdbw, key, keylen, data, datalen);
+ if (!ret && cdbw)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
+ return ret;
+}
+
+INTERCEPTOR(int, cdbw_put_data, struct __sanitizer_cdbw *cdbw, const void *data,
+ SIZE_T datalen, u32 *index) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_data, cdbw, data, datalen, index);
+ if (cdbw)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
+ if (data && datalen)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);
+ int ret = REAL(cdbw_put_data)(cdbw, data, datalen, index);
+ if (!ret) {
+ if (index)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, index, sizeof(*index));
+ if (cdbw)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
+ }
+ return ret;
+}
+
+INTERCEPTOR(int, cdbw_put_key, struct __sanitizer_cdbw *cdbw, const void *key,
+ SIZE_T keylen, u32 index) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_key, cdbw, key, keylen, index);
+ if (cdbw)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
+ if (key && keylen)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
+ int ret = REAL(cdbw_put_key)(cdbw, key, keylen, index);
+ if (!ret && cdbw)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
+ return ret;
+}
+
+INTERCEPTOR(int, cdbw_output, struct __sanitizer_cdbw *cdbw, int output,
+ const char descr[16], u32 (*seedgen)(void)) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cdbw_output, cdbw, output, descr, seedgen);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, output);
+ if (cdbw)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
+ if (descr)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, descr, internal_strnlen(descr, 16));
+ if (seedgen)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)seedgen, sizeof(seedgen));
+ int ret = REAL(cdbw_output)(cdbw, output, descr, seedgen);
+ if (!ret) {
+ if (cdbw)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
+ if (output >= 0)
+ COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, output);
+ }
+ return ret;
+}
+
+INTERCEPTOR(void, cdbw_close, struct __sanitizer_cdbw *cdbw) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, cdbw_close, cdbw);
+ if (cdbw)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
+ REAL(cdbw_close)(cdbw);
+}
+
+#define INIT_CDB \
+ COMMON_INTERCEPT_FUNCTION(cdbr_open); \
+ COMMON_INTERCEPT_FUNCTION(cdbr_open_mem); \
+ COMMON_INTERCEPT_FUNCTION(cdbr_entries); \
+ COMMON_INTERCEPT_FUNCTION(cdbr_get); \
+ COMMON_INTERCEPT_FUNCTION(cdbr_find); \
+ COMMON_INTERCEPT_FUNCTION(cdbr_close); \
+ COMMON_INTERCEPT_FUNCTION(cdbw_open); \
+ COMMON_INTERCEPT_FUNCTION(cdbw_put); \
+ COMMON_INTERCEPT_FUNCTION(cdbw_put_data); \
+ COMMON_INTERCEPT_FUNCTION(cdbw_put_key); \
+ COMMON_INTERCEPT_FUNCTION(cdbw_output); \
+ COMMON_INTERCEPT_FUNCTION(cdbw_close)
+#else
+#define INIT_CDB
+#endif
+
+#if SANITIZER_INTERCEPT_GETFSENT
+INTERCEPTOR(void *, getfsent) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getfsent);
+ void *ret = REAL(getfsent)();
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
+ return ret;
+}
+
+INTERCEPTOR(void *, getfsspec, const char *spec) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getfsspec, spec);
+ if (spec)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, spec, REAL(strlen)(spec) + 1);
+ void *ret = REAL(getfsspec)(spec);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
+ return ret;
+}
+
+INTERCEPTOR(void *, getfsfile, const char *file) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getfsfile, file);
+ if (file)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, file, REAL(strlen)(file) + 1);
+ void *ret = REAL(getfsfile)(file);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
+ return ret;
+}
+
+#define INIT_GETFSENT \
+ COMMON_INTERCEPT_FUNCTION(getfsent); \
+ COMMON_INTERCEPT_FUNCTION(getfsspec); \
+ COMMON_INTERCEPT_FUNCTION(getfsfile);
+#else
+#define INIT_GETFSENT
+#endif
+
+#if SANITIZER_INTERCEPT_ARC4RANDOM
+INTERCEPTOR(void, arc4random_buf, void *buf, SIZE_T len) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, arc4random_buf, buf, len);
+ REAL(arc4random_buf)(buf, len);
+ if (buf && len)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, len);
+}
+
+INTERCEPTOR(void, arc4random_addrandom, u8 *dat, int datlen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, arc4random_addrandom, dat, datlen);
+ if (dat && datlen)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, dat, datlen);
+ REAL(arc4random_addrandom)(dat, datlen);
+}
+
+#define INIT_ARC4RANDOM \
+ COMMON_INTERCEPT_FUNCTION(arc4random_buf); \
+ COMMON_INTERCEPT_FUNCTION(arc4random_addrandom);
+#else
+#define INIT_ARC4RANDOM
+#endif
+
+#if SANITIZER_INTERCEPT_POPEN
+INTERCEPTOR(__sanitizer_FILE *, popen, const char *command, const char *type) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, popen, command, type);
+ if (command)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, command, REAL(strlen)(command) + 1);
+ if (type)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1);
+ __sanitizer_FILE *res = REAL(popen)(command, type);
+ COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
+ if (res) unpoison_file(res);
+ return res;
+}
+#define INIT_POPEN COMMON_INTERCEPT_FUNCTION(popen)
+#else
+#define INIT_POPEN
+#endif
+
+#if SANITIZER_INTERCEPT_POPENVE
+INTERCEPTOR(__sanitizer_FILE *, popenve, const char *path,
+ char *const *argv, char *const *envp, const char *type) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, popenve, path, argv, envp, type);
+ if (path)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
+ if (argv) {
+ for (char *const *pa = argv; ; ++pa) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
+ if (!*pa)
+ break;
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1);
+ }
+ }
+ if (envp) {
+ for (char *const *pa = envp; ; ++pa) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
+ if (!*pa)
+ break;
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1);
+ }
+ }
+ if (type)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1);
+ __sanitizer_FILE *res = REAL(popenve)(path, argv, envp, type);
+ COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
+ if (res) unpoison_file(res);
+ return res;
+}
+#define INIT_POPENVE COMMON_INTERCEPT_FUNCTION(popenve)
+#else
+#define INIT_POPENVE
+#endif
+
+#if SANITIZER_INTERCEPT_PCLOSE
+INTERCEPTOR(int, pclose, __sanitizer_FILE *fp) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, pclose, fp);
+ COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
+ const FileMetadata *m = GetInterceptorMetadata(fp);
+ int res = REAL(pclose)(fp);
+ if (m) {
+ COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
+ DeleteInterceptorMetadata(fp);
+ }
+ return res;
+}
+#define INIT_PCLOSE COMMON_INTERCEPT_FUNCTION(pclose);
+#else
+#define INIT_PCLOSE
+#endif
+
+#if SANITIZER_INTERCEPT_FUNOPEN
+typedef int (*funopen_readfn)(void *cookie, char *buf, int len);
+typedef int (*funopen_writefn)(void *cookie, const char *buf, int len);
+typedef OFF_T (*funopen_seekfn)(void *cookie, OFF_T offset, int whence);
+typedef int (*funopen_closefn)(void *cookie);
+
+struct WrappedFunopenCookie {
+ void *real_cookie;
+ funopen_readfn real_read;
+ funopen_writefn real_write;
+ funopen_seekfn real_seek;
+ funopen_closefn real_close;
+};
+
+static int wrapped_funopen_read(void *cookie, char *buf, int len) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
+ WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
+ funopen_readfn real_read = wrapped_cookie->real_read;
+ return real_read(wrapped_cookie->real_cookie, buf, len);
+}
+
+static int wrapped_funopen_write(void *cookie, const char *buf, int len) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
+ WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
+ funopen_writefn real_write = wrapped_cookie->real_write;
+ return real_write(wrapped_cookie->real_cookie, buf, len);
+}
+
+static OFF_T wrapped_funopen_seek(void *cookie, OFF_T offset, int whence) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
+ WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
+ funopen_seekfn real_seek = wrapped_cookie->real_seek;
+ return real_seek(wrapped_cookie->real_cookie, offset, whence);
+}
+
+static int wrapped_funopen_close(void *cookie) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
+ WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
+ funopen_closefn real_close = wrapped_cookie->real_close;
+ int res = real_close(wrapped_cookie->real_cookie);
+ InternalFree(wrapped_cookie);
+ return res;
+}
+
+INTERCEPTOR(__sanitizer_FILE *, funopen, void *cookie, funopen_readfn readfn,
+ funopen_writefn writefn, funopen_seekfn seekfn,
+ funopen_closefn closefn) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, funopen, cookie, readfn, writefn, seekfn,
+ closefn);
+
+ WrappedFunopenCookie *wrapped_cookie =
+ (WrappedFunopenCookie *)InternalAlloc(sizeof(WrappedFunopenCookie));
+ wrapped_cookie->real_cookie = cookie;
+ wrapped_cookie->real_read = readfn;
+ wrapped_cookie->real_write = writefn;
+ wrapped_cookie->real_seek = seekfn;
+ wrapped_cookie->real_close = closefn;
+
+ __sanitizer_FILE *res =
+ REAL(funopen)(wrapped_cookie,
+ readfn ? wrapped_funopen_read : nullptr,
+ writefn ? wrapped_funopen_write : nullptr,
+ seekfn ? wrapped_funopen_seek : nullptr,
+ closefn ? wrapped_funopen_close : nullptr);
+ if (res)
+ unpoison_file(res);
+ return res;
+}
+#define INIT_FUNOPEN COMMON_INTERCEPT_FUNCTION(funopen)
+#else
+#define INIT_FUNOPEN
+#endif
+
+#if SANITIZER_INTERCEPT_FUNOPEN2
+typedef SSIZE_T (*funopen2_readfn)(void *cookie, void *buf, SIZE_T len);
+typedef SSIZE_T (*funopen2_writefn)(void *cookie, const void *buf, SIZE_T len);
+typedef OFF_T (*funopen2_seekfn)(void *cookie, OFF_T offset, int whence);
+typedef int (*funopen2_flushfn)(void *cookie);
+typedef int (*funopen2_closefn)(void *cookie);
+
+struct WrappedFunopen2Cookie {
+ void *real_cookie;
+ funopen2_readfn real_read;
+ funopen2_writefn real_write;
+ funopen2_seekfn real_seek;
+ funopen2_flushfn real_flush;
+ funopen2_closefn real_close;
+};
+
+static SSIZE_T wrapped_funopen2_read(void *cookie, void *buf, SIZE_T len) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
+ WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
+ funopen2_readfn real_read = wrapped_cookie->real_read;
+ return real_read(wrapped_cookie->real_cookie, buf, len);
+}
+
+static SSIZE_T wrapped_funopen2_write(void *cookie, const void *buf,
+ SIZE_T len) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
+ WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
+ funopen2_writefn real_write = wrapped_cookie->real_write;
+ return real_write(wrapped_cookie->real_cookie, buf, len);
+}
+
+static OFF_T wrapped_funopen2_seek(void *cookie, OFF_T offset, int whence) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
+ WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
+ funopen2_seekfn real_seek = wrapped_cookie->real_seek;
+ return real_seek(wrapped_cookie->real_cookie, offset, whence);
+}
+
+static int wrapped_funopen2_flush(void *cookie) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
+ WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
+ funopen2_flushfn real_flush = wrapped_cookie->real_flush;
+ return real_flush(wrapped_cookie->real_cookie);
+}
+
+static int wrapped_funopen2_close(void *cookie) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
+ WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
+ funopen2_closefn real_close = wrapped_cookie->real_close;
+ int res = real_close(wrapped_cookie->real_cookie);
+ InternalFree(wrapped_cookie);
+ return res;
+}
+
+INTERCEPTOR(__sanitizer_FILE *, funopen2, void *cookie, funopen2_readfn readfn,
+ funopen2_writefn writefn, funopen2_seekfn seekfn,
+ funopen2_flushfn flushfn, funopen2_closefn closefn) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, funopen2, cookie, readfn, writefn, seekfn,
+ flushfn, closefn);
+
+ WrappedFunopen2Cookie *wrapped_cookie =
+ (WrappedFunopen2Cookie *)InternalAlloc(sizeof(WrappedFunopen2Cookie));
+ wrapped_cookie->real_cookie = cookie;
+ wrapped_cookie->real_read = readfn;
+ wrapped_cookie->real_write = writefn;
+ wrapped_cookie->real_seek = seekfn;
+ wrapped_cookie->real_flush = flushfn;
+ wrapped_cookie->real_close = closefn;
+
+ __sanitizer_FILE *res =
+ REAL(funopen2)(wrapped_cookie,
+ readfn ? wrapped_funopen2_read : nullptr,
+ writefn ? wrapped_funopen2_write : nullptr,
+ seekfn ? wrapped_funopen2_seek : nullptr,
+ flushfn ? wrapped_funopen2_flush : nullptr,
+ closefn ? wrapped_funopen2_close : nullptr);
+ if (res)
+ unpoison_file(res);
+ return res;
+}
+#define INIT_FUNOPEN2 COMMON_INTERCEPT_FUNCTION(funopen2)
+#else
+#define INIT_FUNOPEN2
+#endif
+
+#if SANITIZER_INTERCEPT_FDEVNAME
+INTERCEPTOR(char *, fdevname, int fd) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, fdevname, fd);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ char *name = REAL(fdevname)(fd);
+ if (name) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1);
+ if (fd > 0)
+ COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
+ }
+ return name;
+}
+
+INTERCEPTOR(char *, fdevname_r, int fd, char *buf, SIZE_T len) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, fdevname_r, fd, buf, len);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ char *name = REAL(fdevname_r)(fd, buf, len);
+ if (name && buf && len > 0) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
+ if (fd > 0)
+ COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
+ }
+ return name;
+}
+
+#define INIT_FDEVNAME \
+ COMMON_INTERCEPT_FUNCTION(fdevname); \
+ COMMON_INTERCEPT_FUNCTION(fdevname_r);
+#else
+#define INIT_FDEVNAME
+#endif
+
+#if SANITIZER_INTERCEPT_GETUSERSHELL
+INTERCEPTOR(char *, getusershell) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getusershell);
+ char *res = REAL(getusershell)();
+ if (res)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
+ return res;
+}
+
+#define INIT_GETUSERSHELL COMMON_INTERCEPT_FUNCTION(getusershell);
+#else
+#define INIT_GETUSERSHELL
+#endif
+
+#if SANITIZER_INTERCEPT_SL_INIT
+INTERCEPTOR(void *, sl_init) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, sl_init);
+ void *res = REAL(sl_init)();
+ if (res)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_StringList_sz);
+ return res;
+}
+
+INTERCEPTOR(int, sl_add, void *sl, char *item) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, sl_add, sl, item);
+ if (sl)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
+ if (item)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, item, REAL(strlen)(item) + 1);
+ int res = REAL(sl_add)(sl, item);
+ if (!res)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
+ return res;
+}
+
+INTERCEPTOR(char *, sl_find, void *sl, const char *item) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, sl_find, sl, item);
+ if (sl)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
+ if (item)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, item, REAL(strlen)(item) + 1);
+ char *res = REAL(sl_find)(sl, item);
+ if (res)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
+ return res;
+}
+
+INTERCEPTOR(void, sl_free, void *sl, int freeall) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, sl_free, sl, freeall);
+ if (sl)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
+ REAL(sl_free)(sl, freeall);
+}
+
+#define INIT_SL_INIT \
+ COMMON_INTERCEPT_FUNCTION(sl_init); \
+ COMMON_INTERCEPT_FUNCTION(sl_add); \
+ COMMON_INTERCEPT_FUNCTION(sl_find); \
+ COMMON_INTERCEPT_FUNCTION(sl_free);
+#else
+#define INIT_SL_INIT
+#endif
+
+#if SANITIZER_INTERCEPT_GETRANDOM
+INTERCEPTOR(SSIZE_T, getrandom, void *buf, SIZE_T buflen, unsigned int flags) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getrandom, buf, buflen, flags);
+ SSIZE_T n = REAL(getrandom)(buf, buflen, flags);
+ if (n > 0) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, n);
+ }
+ return n;
+}
+#define INIT_GETRANDOM COMMON_INTERCEPT_FUNCTION(getrandom)
+#else
+#define INIT_GETRANDOM
+#endif
+
static void InitializeCommonInterceptors() {
+#if SI_POSIX
static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
- interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
+ interceptor_metadata_map =
+ new ((void *)&metadata_mem) MetadataHashMap(); // NOLINT
+#endif
INIT_MMAP;
INIT_MMAP64;
@@ -7263,6 +9598,7 @@ static void InitializeCommonInterceptors() {
INIT_MEMCPY;
INIT_MEMCHR;
INIT_MEMCMP;
+ INIT_BCMP;
INIT_MEMRCHR;
INIT_MEMMEM;
INIT_READ;
@@ -7297,6 +9633,8 @@ static void InitializeCommonInterceptors() {
INIT_GETPWENT;
INIT_FGETPWENT;
INIT_GETPWENT_R;
+ INIT_FGETPWENT_R;
+ INIT_FGETGRENT_R;
INIT_SETPWENT;
INIT_CLOCK_GETTIME;
INIT_GETITIMER;
@@ -7341,6 +9679,7 @@ static void InitializeCommonInterceptors() {
INIT_WCSTOMBS;
INIT_WCSNRTOMBS;
INIT_WCRTOMB;
+ INIT_WCTOMB;
INIT_TCGETATTR;
INIT_REALPATH;
INIT_CANONICALIZE_FILE_NAME;
@@ -7362,6 +9701,7 @@ static void InitializeCommonInterceptors() {
INIT_SIGSETOPS;
INIT_SIGPENDING;
INIT_SIGPROCMASK;
+ INIT_PTHREAD_SIGMASK;
INIT_BACKTRACE;
INIT__EXIT;
INIT_PTHREAD_MUTEX_LOCK;
@@ -7400,13 +9740,16 @@ static void InitializeCommonInterceptors() {
INIT_PTHREAD_BARRIERATTR_GETPSHARED;
INIT_TMPNAM;
INIT_TMPNAM_R;
+ INIT_TTYNAME;
INIT_TTYNAME_R;
INIT_TEMPNAM;
INIT_PTHREAD_SETNAME_NP;
INIT_PTHREAD_GETNAME_NP;
INIT_SINCOS;
INIT_REMQUO;
+ INIT_REMQUOL;
INIT_LGAMMA;
+ INIT_LGAMMAL;
INIT_LGAMMA_R;
INIT_LGAMMAL_R;
INIT_DRAND48_R;
@@ -7423,6 +9766,7 @@ static void InitializeCommonInterceptors() {
INIT_CAPGET;
INIT_AEABI_MEM;
INIT___BZERO;
+ INIT_BZERO;
INIT_FTIME;
INIT_XDR;
INIT_TSEARCH;
@@ -7459,6 +9803,7 @@ static void InitializeCommonInterceptors() {
INIT_GETLOADAVG;
INIT_WCSLEN;
INIT_WCSCAT;
+ INIT_WCSDUP;
INIT_WCSXFRM;
INIT___WCSXFRM_L;
INIT_ACCT;
@@ -7482,6 +9827,43 @@ static void InitializeCommonInterceptors() {
INIT_TTYENT;
INIT_PROTOENT;
INIT_NETENT;
+ INIT_GETMNTINFO;
+ INIT_MI_VECTOR_HASH;
+ INIT_SETVBUF;
+ INIT_GETVFSSTAT;
+ INIT_REGEX;
+ INIT_REGEXSUB;
+ INIT_FTS;
+ INIT_SYSCTL;
+ INIT_ASYSCTL;
+ INIT_SYSCTLGETMIBINFO;
+ INIT_NL_LANGINFO;
+ INIT_MODCTL;
+ INIT_STRTONUM;
+ INIT_FPARSELN;
+ INIT_STATVFS1;
+ INIT_STRTOI;
+ INIT_CAPSICUM;
+ INIT_SHA1;
+ INIT_MD4;
+ INIT_RMD160;
+ INIT_MD5;
+ INIT_FSEEK;
+ INIT_MD2;
+ INIT_SHA2;
+ INIT_VIS;
+ INIT_CDB;
+ INIT_GETFSENT;
+ INIT_ARC4RANDOM;
+ INIT_POPEN;
+ INIT_POPENVE;
+ INIT_PCLOSE;
+ INIT_FUNOPEN;
+ INIT_FUNOPEN2;
+ INIT_FDEVNAME;
+ INIT_GETUSERSHELL;
+ INIT_SL_INIT;
+ INIT_GETRANDOM;
INIT___PRINTF_CHK;
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_format.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_format.inc
index 30927d2..bbbedda 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_format.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_format.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_common_interceptors_format.inc ----------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_ioctl.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_ioctl.inc
index 5408ea1..490a04b 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_ioctl.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_ioctl.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_common_interceptors_ioctl.inc -----------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S
new file mode 100644
index 0000000..20f42f1
--- /dev/null
+++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S
@@ -0,0 +1,43 @@
+#if defined(__aarch64__) && defined(__linux__)
+
+#include "sanitizer_common/sanitizer_asm.h"
+
+ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA)
+
+.comm _ZN14__interception10real_vforkE,8,8
+.globl ASM_WRAPPER_NAME(vfork)
+ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork))
+ASM_WRAPPER_NAME(vfork):
+ // Save x30 in the off-stack spill area.
+ stp xzr, x30, [sp, #-16]!
+ bl COMMON_INTERCEPTOR_SPILL_AREA
+ ldp xzr, x30, [sp], 16
+ str x30, [x0]
+
+ // Call real vfork. This may return twice. User code that runs between the first and the second return
+ // may clobber the stack frame of the interceptor; that's why it does not have a frame.
+ adrp x0, _ZN14__interception10real_vforkE
+ ldr x0, [x0, :lo12:_ZN14__interception10real_vforkE]
+ blr x0
+
+ stp x0, xzr, [sp, #-16]!
+ cmp x0, #0
+ b.eq .L_exit
+
+ // x0 != 0 => parent process. Clear stack shadow.
+ add x0, sp, #16
+ bl COMMON_INTERCEPTOR_HANDLE_VFORK
+
+.L_exit:
+ // Restore x30.
+ bl COMMON_INTERCEPTOR_SPILL_AREA
+ ldr x30, [x0]
+ ldp x0, xzr, [sp], 16
+
+ ret
+ASM_SIZE(vfork)
+
+.weak vfork
+.set vfork, ASM_WRAPPER_NAME(vfork)
+
+#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S
new file mode 100644
index 0000000..780a9d4
--- /dev/null
+++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S
@@ -0,0 +1,49 @@
+#if defined(__arm__) && defined(__linux__)
+
+#include "sanitizer_common/sanitizer_asm.h"
+
+ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA)
+
+.comm _ZN14__interception10real_vforkE,4,4
+.globl ASM_WRAPPER_NAME(vfork)
+ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork))
+ASM_WRAPPER_NAME(vfork):
+ // Save LR in the off-stack spill area.
+ push {r4, lr}
+ bl COMMON_INTERCEPTOR_SPILL_AREA
+ pop {r4, lr}
+ str lr, [r0]
+
+ // Call real vfork. This may return twice. User code that runs between the first and the second return
+ // may clobber the stack frame of the interceptor; that's why it does not have a frame.
+ ldr r0, .LCPI0_0
+.LPC0_0:
+ ldr r0, [pc, r0]
+ mov lr, pc
+ bx r0
+
+ push {r0, r4}
+ cmp r0, #0
+ beq .L_exit
+
+ // r0 != 0 => parent process. Clear stack shadow.
+ add r0, sp, #8
+ bl COMMON_INTERCEPTOR_HANDLE_VFORK
+
+.L_exit:
+ // Restore LR.
+ bl COMMON_INTERCEPTOR_SPILL_AREA
+ ldr lr, [r0]
+ pop {r0, r4}
+
+ mov pc, lr
+
+.LCPI0_0:
+ .long _ZN14__interception10real_vforkE - (.LPC0_0+8)
+
+ASM_SIZE(vfork)
+
+.weak vfork
+.set vfork, ASM_WRAPPER_NAME(vfork)
+
+#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S
new file mode 100644
index 0000000..ed69381
--- /dev/null
+++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S
@@ -0,0 +1,63 @@
+#if defined(__i386__) && defined(__linux__)
+
+#include "sanitizer_common/sanitizer_asm.h"
+
+.comm _ZN14__interception10real_vforkE,4,4
+.globl ASM_WRAPPER_NAME(vfork)
+ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork))
+ASM_WRAPPER_NAME(vfork):
+ // Store return address in the spill area and tear down the stack frame.
+ sub $12, %esp
+ call COMMON_INTERCEPTOR_SPILL_AREA
+ mov 12(%esp), %ecx
+ mov %ecx, (%eax)
+ add $16, %esp
+
+ call .L0$pb
+.L0$pb:
+ pop %eax
+.Ltmp0:
+ add $_GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb), %eax
+ call *_ZN14__interception10real_vforkE@GOTOFF(%eax)
+
+ // Restore the stack frame.
+ // 12(%esp) return address
+ // 8(%esp) spill %ebx
+ // 4(%esp) spill REAL(vfork) return value
+ // (%esp) call frame (arg0) for __*_handle_vfork
+ sub $16, %esp
+ mov %ebx, 8(%esp)
+ mov %eax, 4(%esp)
+
+ // Form GOT address in %ebx.
+ call .L1$pb
+.L1$pb:
+ pop %ebx
+.Ltmp1:
+ add $_GLOBAL_OFFSET_TABLE_+(.Ltmp1-.L1$pb), %ebx
+
+ // Restore original return address.
+ call COMMON_INTERCEPTOR_SPILL_AREA
+ mov (%eax), %ecx
+ mov %ecx, 12(%esp)
+ mov 4(%esp), %eax
+
+ // Call handle_vfork in the parent process (%rax != 0).
+ test %eax, %eax
+ je .L_exit
+
+ lea 16(%esp), %ecx
+ mov %ecx, (%esp)
+ call COMMON_INTERCEPTOR_HANDLE_VFORK@PLT
+
+.L_exit:
+ mov 4(%esp), %eax
+ mov 8(%esp), %ebx
+ add $12, %esp
+ ret
+ASM_SIZE(vfork)
+
+.weak vfork
+.set vfork, ASM_WRAPPER_NAME(vfork)
+
+#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S
new file mode 100644
index 0000000..8147cdd
--- /dev/null
+++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S
@@ -0,0 +1,41 @@
+#if defined(__x86_64__) && defined(__linux__)
+
+#include "sanitizer_common/sanitizer_asm.h"
+
+.comm _ZN14__interception10real_vforkE,8,8
+.globl ASM_WRAPPER_NAME(vfork)
+ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork))
+ASM_WRAPPER_NAME(vfork):
+ // Store return address in the spill area and tear down the stack frame.
+ push %rcx
+ call COMMON_INTERCEPTOR_SPILL_AREA
+ pop %rcx
+ pop %rdi
+ mov %rdi, (%rax)
+
+ call *_ZN14__interception10real_vforkE(%rip)
+
+ // Restore return address from the spill area.
+ push %rcx
+ push %rax
+ call COMMON_INTERCEPTOR_SPILL_AREA
+ mov (%rax), %rdx
+ mov %rdx, 8(%rsp)
+ mov (%rsp), %rax
+
+ // Call handle_vfork in the parent process (%rax != 0).
+ test %rax, %rax
+ je .L_exit
+
+ lea 16(%rsp), %rdi
+ call COMMON_INTERCEPTOR_HANDLE_VFORK@PLT
+
+.L_exit:
+ pop %rax
+ ret
+ASM_SIZE(vfork)
+
+.weak vfork
+.set vfork, ASM_WRAPPER_NAME(vfork)
+
+#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interface.inc b/libsanitizer/sanitizer_common/sanitizer_common_interface.inc
index 89d47bd..c725549 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common_interface.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_common_interface.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_common_interface.inc ------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Sanitizer Common interface list.
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interface_posix.inc b/libsanitizer/sanitizer_common/sanitizer_common_interface_posix.inc
index d3b72a8..38f9531 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common_interface_posix.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_common_interface_posix.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_common_interface_posix.inc ------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Sanitizer Common interface list only available for Posix systems.
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_common_libcdep.cpp
index 6a63650..27d6a17 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common_libcdep.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_common_libcdep.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_common_libcdep.cc ---------------------------------------===//
+//===-- sanitizer_common_libcdep.cpp --------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -23,7 +24,7 @@ void SetSoftRssLimitExceededCallback(void (*Callback)(bool exceeded)) {
SoftRssLimitExceededCallback = Callback;
}
-#if SANITIZER_LINUX && !SANITIZER_GO
+#if (SANITIZER_LINUX || SANITIZER_NETBSD) && !SANITIZER_GO
// Weak default implementation for when sanitizer_stackdepot is not linked in.
SANITIZER_WEAK_ATTRIBUTE StackDepotStats *StackDepotGetStats() {
return nullptr;
@@ -112,7 +113,7 @@ void WriteToSyslog(const char *msg) {
}
void MaybeStartBackgroudThread() {
-#if SANITIZER_LINUX && \
+#if (SANITIZER_LINUX || SANITIZER_NETBSD) && \
!SANITIZER_GO // Need to implement/test on other platforms.
// Start the background thread if one of the rss limits is given.
if (!common_flags()->hard_rss_limit_mb &&
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cc b/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cpp
index 7f92bdc..3b278e0 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_common_nolibc.cc ----------------------------------------===//
+//===-- sanitizer_common_nolibc.cpp ---------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc b/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc
index 6fd5ef7..31ff48c 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_common_syscalls.inc ---------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -2872,6 +2873,18 @@ POST_SYSCALL(rt_sigaction)(long res, long signum,
POST_WRITE(oldact, oldact_sz);
}
}
+
+PRE_SYSCALL(getrandom)(void *buf, uptr count, long flags) {
+ if (buf) {
+ PRE_WRITE(buf, count);
+ }
+}
+
+POST_SYSCALL(getrandom)(long res, void *buf, uptr count, long flags) {
+ if (res > 0 && buf) {
+ POST_WRITE(buf, res);
+ }
+}
} // extern "C"
#undef PRE_SYSCALL
diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cpp
index 8426aad..5451d1e 100644
--- a/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_coverage_fuchsia.cc -------------------------------------===//
+//===-- sanitizer_coverage_fuchsia.cpp ------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -29,6 +30,7 @@
#include "sanitizer_atomic.h"
#include "sanitizer_common.h"
#include "sanitizer_internal_defs.h"
+#include "sanitizer_symbolizer_fuchsia.h"
#include <zircon/process.h>
#include <zircon/sanitizer.h>
@@ -99,7 +101,7 @@ class TracePcGuardController final {
// uses the `dumpfile` symbolizer markup element to highlight the
// dump. See the explanation for this in:
// https://fuchsia.googlesource.com/zircon/+/master/docs/symbolizer_markup.md
- Printf("SanitizerCoverage: {{{dumpfile:%s:%s}}} with up to %u PCs\n",
+ Printf("SanitizerCoverage: " FORMAT_DUMPFILE " with up to %u PCs\n",
kSancovSinkName, vmo_name_, next_index_ - 1);
}
}
@@ -130,7 +132,7 @@ class TracePcGuardController final {
// The first sample goes at [1] to reserve [0] for the magic number.
next_index_ = 1 + num_guards;
- zx_status_t status = _zx_vmo_create(DataSize(), 0, &vmo_);
+ zx_status_t status = _zx_vmo_create(DataSize(), ZX_VMO_RESIZABLE, &vmo_);
CHECK_EQ(status, ZX_OK);
// Give the VMO a name including our process KOID so it's easy to spot.
diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_interface.inc b/libsanitizer/sanitizer_common/sanitizer_coverage_interface.inc
index fb78cc0..7beeff7 100644
--- a/libsanitizer/sanitizer_common/sanitizer_coverage_interface.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_coverage_interface.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_coverage_interface.inc ----------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Sanitizer Coverage interface list.
diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cpp
index 84db647..ad137f9 100644
--- a/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_coverage_libcdep_new.cc ---------------------------------===//
+//===-- sanitizer_coverage_libcdep_new.cpp --------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Sanitizer Coverage Controller for Trace PC Guard.
diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_win_dll_thunk.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_win_dll_thunk.cpp
index 5aea120..d0bf8a4 100644
--- a/libsanitizer/sanitizer_common/sanitizer_coverage_win_dll_thunk.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_coverage_win_dll_thunk.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_coverage_win_dll_thunk.cc -------------------------------===//
+//===-- sanitizer_coverage_win_dll_thunk.cpp ------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cpp
index 939f395..0bdf0c5 100644
--- a/libsanitizer/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_coverage_win_dynamic_runtime_thunk.cc -------------------===//
+//===-- sanitizer_coverage_win_dynamic_runtime_thunk.cpp ------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -17,3 +18,9 @@
#define INTERFACE_WEAK_FUNCTION(Name) WIN_WEAK_IMPORT_DEF(Name)
#include "sanitizer_coverage_interface.inc"
#endif // SANITIZER_DYNAMIC_RUNTIME_THUNK
+
+namespace __sanitizer {
+// Add one, otherwise unused, external symbol to this object file so that the
+// Visual C++ linker includes it and reads the .drective section.
+void ForceWholeArchiveIncludeForSanCov() {}
+}
diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cpp
index 12832fc..40184bb 100644
--- a/libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_coverage_win_sections.cc --------------------------------===//
+//===-- sanitizer_coverage_win_sections.cpp -------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -25,35 +26,40 @@
#include "sanitizer_platform.h"
#if SANITIZER_WINDOWS
#include <stdint.h>
-extern "C" {
-// The Guard array and counter array should both be merged into the .data
-// section to reduce the number of PE sections However, because PCTable is
-// constant it should be merged with the .rdata section.
-#pragma section(".SCOV$GA", read, write) // NOLINT
-// Use align(1) to avoid adding any padding that will mess up clients trying to
-// determine the start and end of the array.
-__declspec(allocate(".SCOV$GA")) __declspec(align(1)) uint64_t
- __start___sancov_guards = 0;
-#pragma section(".SCOV$GZ", read, write) // NOLINT
-__declspec(allocate(".SCOV$GZ")) __declspec(align(1)) uint64_t
- __stop___sancov_guards = 0;
+extern "C" {
+// Use uint64_t so the linker won't need to add any padding if it tries to word
+// align the start of the 8-bit counters array. The array will always start 8
+// bytes after __start_sancov_cntrs.
#pragma section(".SCOV$CA", read, write) // NOLINT
-__declspec(allocate(".SCOV$CA")) __declspec(align(1)) uint64_t
- __start___sancov_cntrs = 0;
+__declspec(allocate(".SCOV$CA")) uint64_t __start___sancov_cntrs = 0;
+
+// Even though we said not to align __stop__sancov_cntrs (using the "align"
+// declspec), MSVC's linker may try to align the section, .SCOV$CZ, containing
+// it. This can cause a mismatch between the number of PCs and counters since
+// each PCTable element is 8 bytes (unlike counters which are 1 byte) so no
+// padding would be added to align .SCOVP$Z, However, if .SCOV$CZ section is 1
+// byte, the linker won't try to align it on an 8-byte boundary, so use a
+// uint8_t for __stop_sancov_cntrs.
#pragma section(".SCOV$CZ", read, write) // NOLINT
-__declspec(allocate(".SCOV$CZ")) __declspec(align(1)) uint64_t
+__declspec(allocate(".SCOV$CZ")) __declspec(align(1)) uint8_t
__stop___sancov_cntrs = 0;
+#pragma section(".SCOV$GA", read, write) // NOLINT
+__declspec(allocate(".SCOV$GA")) uint64_t __start___sancov_guards = 0;
+#pragma section(".SCOV$GZ", read, write) // NOLINT
+__declspec(allocate(".SCOV$GZ")) __declspec(align(1)) uint8_t
+ __stop___sancov_guards = 0;
+
+// The guard array and counter array should both be merged into the .data
+// section to reduce the number of PE sections. However, because PCTable is
+// constant it should be merged with the .rdata section.
#pragma comment(linker, "/MERGE:.SCOV=.data")
-// Use uint64_t so there won't be any issues if the linker tries to word align
-// the pc array.
#pragma section(".SCOVP$A", read) // NOLINT
-__declspec(allocate(".SCOVP$A")) __declspec(align(1)) uint64_t
- __start___sancov_pcs = 0;
+__declspec(allocate(".SCOVP$A")) uint64_t __start___sancov_pcs = 0;
#pragma section(".SCOVP$Z", read) // NOLINT
-__declspec(allocate(".SCOVP$Z")) __declspec(align(1)) uint64_t
+__declspec(allocate(".SCOVP$Z")) __declspec(align(1)) uint8_t
__stop___sancov_pcs = 0;
#pragma comment(linker, "/MERGE:.SCOVP=.rdata")
diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_win_weak_interception.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_win_weak_interception.cpp
index 64718df..5526398 100644
--- a/libsanitizer/sanitizer_common/sanitizer_coverage_win_weak_interception.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_coverage_win_weak_interception.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_coverage_win_weak_interception.cc -----------------------===//
+//===-- sanitizer_coverage_win_weak_interception.cpp ----------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// This module should be included in Sanitizer Coverage when it implemented as a
diff --git a/libsanitizer/sanitizer_common/sanitizer_dbghelp.h b/libsanitizer/sanitizer_common/sanitizer_dbghelp.h
index bad17a9..00a5399 100644
--- a/libsanitizer/sanitizer_common/sanitizer_dbghelp.h
+++ b/libsanitizer/sanitizer_common/sanitizer_dbghelp.h
@@ -1,7 +1,8 @@
//===-- sanitizer_dbghelp.h ------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector.h b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector.h
index 5c83175..b80cff4 100644
--- a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector.h
+++ b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector.h
@@ -1,7 +1,8 @@
//===-- sanitizer_deadlock_detector.h ---------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -24,8 +25,8 @@
#ifndef SANITIZER_DEADLOCK_DETECTOR_H
#define SANITIZER_DEADLOCK_DETECTOR_H
-#include "sanitizer_common.h"
#include "sanitizer_bvgraph.h"
+#include "sanitizer_common.h"
namespace __sanitizer {
@@ -56,7 +57,6 @@ class DeadlockDetectorTLS {
// Returns true if this is the first (non-recursive) acquisition of this lock.
bool addLock(uptr lock_id, uptr current_epoch, u32 stk) {
- // Printf("addLock: %zx %zx stk %u\n", lock_id, current_epoch, stk);
CHECK_EQ(epoch_, current_epoch);
if (!bv_.setBit(lock_id)) {
// The lock is already held by this thread, it must be recursive.
@@ -82,7 +82,6 @@ class DeadlockDetectorTLS {
}
}
}
- // Printf("remLock: %zx %zx\n", lock_id, epoch_);
if (!bv_.clearBit(lock_id))
return; // probably addLock happened before flush
if (n_all_locks_) {
@@ -156,7 +155,6 @@ class DeadlockDetector {
if (!available_nodes_.empty())
return getAvailableNode(data);
if (!recycled_nodes_.empty()) {
- // Printf("recycling: n_edges_ %zd\n", n_edges_);
for (sptr i = n_edges_ - 1; i >= 0; i--) {
if (recycled_nodes_.getBit(edges_[i].from) ||
recycled_nodes_.getBit(edges_[i].to)) {
@@ -253,8 +251,6 @@ class DeadlockDetector {
unique_tid};
edges_[n_edges_++] = e;
}
- // Printf("Edge%zd: %u %zd=>%zd in T%d\n",
- // n_edges_, stk, added_edges[i], cur_idx, unique_tid);
}
return n_added_edges;
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cc b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cpp
index e2aedc2..d4a325b 100644
--- a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_deadlock_detector1.cc -----------------------------------===//
+//===-- sanitizer_deadlock_detector1.cpp ----------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cc b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cpp
index fb47853..4026739 100644
--- a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_deadlock_detector2.cc -----------------------------------===//
+//===-- sanitizer_deadlock_detector2.cpp ----------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector_interface.h b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector_interface.h
index f8da206..a4722b0 100644
--- a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector_interface.h
+++ b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector_interface.h
@@ -1,7 +1,8 @@
//===-- sanitizer_deadlock_detector_interface.h -----------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_errno.cc b/libsanitizer/sanitizer_common/sanitizer_errno.cpp
index b65f0e7..cbadf4d 100644
--- a/libsanitizer/sanitizer_common/sanitizer_errno.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_errno.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_errno.cc --------------------------------------*- C++ -*-===//
+//===-- sanitizer_errno.cpp -------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_errno.h b/libsanitizer/sanitizer_common/sanitizer_errno.h
index d67cc24..584e66e 100644
--- a/libsanitizer/sanitizer_common/sanitizer_errno.h
+++ b/libsanitizer/sanitizer_common/sanitizer_errno.h
@@ -1,7 +1,8 @@
//===-- sanitizer_errno.h ---------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_errno_codes.h b/libsanitizer/sanitizer_common/sanitizer_errno_codes.h
index 709f43b..f388d0d 100644
--- a/libsanitizer/sanitizer_common/sanitizer_errno_codes.h
+++ b/libsanitizer/sanitizer_common/sanitizer_errno_codes.h
@@ -1,7 +1,8 @@
//===-- sanitizer_errno_codes.h ---------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_file.cc b/libsanitizer/sanitizer_common/sanitizer_file.cpp
index 61fcc9f..c8c0b33 100644
--- a/libsanitizer/sanitizer_common/sanitizer_file.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_file.cpp
@@ -1,13 +1,14 @@
-//===-- sanitizer_file.cc ------------------------------------------------===//
+//===-- sanitizer_file.cpp -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===---------------------------------------------------------------------===//
//
// This file is shared between AddressSanitizer and ThreadSanitizer
// run-time libraries. It defines filesystem-related interfaces. This
-// is separate from sanitizer_common.cc so that it's simpler to disable
+// is separate from sanitizer_common.cpp so that it's simpler to disable
// all the filesystem support code for a port that doesn't use it.
//
//===---------------------------------------------------------------------===//
diff --git a/libsanitizer/sanitizer_common/sanitizer_file.h b/libsanitizer/sanitizer_common/sanitizer_file.h
index 3f9e8ab..4a78a0e 100644
--- a/libsanitizer/sanitizer_common/sanitizer_file.h
+++ b/libsanitizer/sanitizer_common/sanitizer_file.h
@@ -1,7 +1,8 @@
//===-- sanitizer_file.h ---------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===---------------------------------------------------------------------===//
//
@@ -64,9 +65,6 @@ bool ReadFromFile(fd_t fd, void *buff, uptr buff_size,
bool WriteToFile(fd_t fd, const void *buff, uptr buff_size,
uptr *bytes_written = nullptr, error_t *error_p = nullptr);
-bool RenameFile(const char *oldpath, const char *newpath,
- error_t *error_p = nullptr);
-
// Scoped file handle closer.
struct FileCloser {
explicit FileCloser(fd_t fd) : fd(fd) {}
diff --git a/libsanitizer/sanitizer_common/sanitizer_flag_parser.cc b/libsanitizer/sanitizer_common/sanitizer_flag_parser.cpp
index 1fc6b2e..4831814 100644
--- a/libsanitizer/sanitizer_common/sanitizer_flag_parser.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_flag_parser.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_flag_parser.cc ------------------------------------------===//
+//===-- sanitizer_flag_parser.cpp -----------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -61,7 +62,7 @@ void FlagParser::PrintFlagDescriptions() {
}
void FlagParser::fatal_error(const char *err) {
- Printf("ERROR: %s\n", err);
+ Printf("%s: ERROR: %s\n", SanitizerToolName, err);
Die();
}
@@ -74,10 +75,17 @@ void FlagParser::skip_whitespace() {
while (is_space(buf_[pos_])) ++pos_;
}
-void FlagParser::parse_flag() {
+void FlagParser::parse_flag(const char *env_option_name) {
uptr name_start = pos_;
while (buf_[pos_] != 0 && buf_[pos_] != '=' && !is_space(buf_[pos_])) ++pos_;
- if (buf_[pos_] != '=') fatal_error("expected '='");
+ if (buf_[pos_] != '=') {
+ if (env_option_name) {
+ Printf("%s: ERROR: expected '=' in %s\n", SanitizerToolName,
+ env_option_name);
+ Die();
+ } else
+ fatal_error("expected '='");
+ }
char *name = ll_strndup(buf_ + name_start, pos_ - name_start);
uptr value_start = ++pos_;
@@ -99,11 +107,11 @@ void FlagParser::parse_flag() {
if (!res) fatal_error("Flag parsing failed.");
}
-void FlagParser::parse_flags() {
+void FlagParser::parse_flags(const char *env_option_name) {
while (true) {
skip_whitespace();
if (buf_[pos_] == 0) break;
- parse_flag();
+ parse_flag(env_option_name);
}
// Do a sanity check for certain flags.
@@ -111,7 +119,13 @@ void FlagParser::parse_flags() {
common_flags_dont_use.malloc_context_size = 1;
}
-void FlagParser::ParseString(const char *s) {
+void FlagParser::ParseStringFromEnv(const char *env_name) {
+ const char *env = GetEnv(env_name);
+ VPrintf(1, "%s: %s\n", env_name, env ? env : "<empty>");
+ ParseString(env, env_name);
+}
+
+void FlagParser::ParseString(const char *s, const char *env_option_name) {
if (!s) return;
// Backup current parser state to allow nested ParseString() calls.
const char *old_buf_ = buf_;
@@ -119,7 +133,7 @@ void FlagParser::ParseString(const char *s) {
buf_ = s;
pos_ = 0;
- parse_flags();
+ parse_flags(env_option_name);
buf_ = old_buf_;
pos_ = old_pos_;
@@ -138,7 +152,7 @@ bool FlagParser::ParseFile(const char *path, bool ignore_missing) {
Printf("Failed to read options from '%s': error %d\n", path, err);
return false;
}
- ParseString(data);
+ ParseString(data, path);
UnmapOrDie(data, data_mapped_size);
return true;
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_flag_parser.h b/libsanitizer/sanitizer_common/sanitizer_flag_parser.h
index 6bf3fed..8e12700 100644
--- a/libsanitizer/sanitizer_common/sanitizer_flag_parser.h
+++ b/libsanitizer/sanitizer_common/sanitizer_flag_parser.h
@@ -1,7 +1,8 @@
//===-- sanitizer_flag_parser.h ---------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -21,6 +22,9 @@ namespace __sanitizer {
class FlagHandlerBase {
public:
virtual bool Parse(const char *value) { return false; }
+
+ protected:
+ ~FlagHandlerBase() {};
};
template <typename T>
@@ -95,6 +99,15 @@ inline bool FlagHandler<uptr>::Parse(const char *value) {
return ok;
}
+template <>
+inline bool FlagHandler<s64>::Parse(const char *value) {
+ const char *value_end;
+ *t_ = internal_simple_strtoll(value, &value_end, 10);
+ bool ok = *value_end == 0;
+ if (!ok) Printf("ERROR: Invalid value for s64 option: '%s'\n", value);
+ return ok;
+}
+
class FlagParser {
static const int kMaxFlags = 200;
struct Flag {
@@ -111,7 +124,8 @@ class FlagParser {
FlagParser();
void RegisterHandler(const char *name, FlagHandlerBase *handler,
const char *desc);
- void ParseString(const char *s);
+ void ParseString(const char *s, const char *env_name = 0);
+ void ParseStringFromEnv(const char *env_name);
bool ParseFile(const char *path, bool ignore_missing);
void PrintFlagDescriptions();
@@ -121,8 +135,8 @@ class FlagParser {
void fatal_error(const char *err);
bool is_space(char c);
void skip_whitespace();
- void parse_flags();
- void parse_flag();
+ void parse_flags(const char *env_option_name);
+ void parse_flag(const char *env_option_name);
bool run_handler(const char *name, const char *value);
char *ll_strndup(const char *s, uptr n);
};
diff --git a/libsanitizer/sanitizer_common/sanitizer_flags.cc b/libsanitizer/sanitizer_common/sanitizer_flags.cpp
index cbd0002..acc7ed3 100644
--- a/libsanitizer/sanitizer_common/sanitizer_flags.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_flags.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_flags.cc ------------------------------------------------===//
+//===-- sanitizer_flags.cpp -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_flags.h b/libsanitizer/sanitizer_common/sanitizer_flags.h
index 2e3739e..8f5e987 100644
--- a/libsanitizer/sanitizer_common/sanitizer_flags.h
+++ b/libsanitizer/sanitizer_common/sanitizer_flags.h
@@ -1,7 +1,8 @@
//===-- sanitizer_flags.h ---------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_flags.inc b/libsanitizer/sanitizer_common/sanitizer_flags.inc
index a62dbeb..7d592bd 100644
--- a/libsanitizer/sanitizer_common/sanitizer_flags.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_flags.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_flags.h ---------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -101,7 +102,7 @@ COMMON_FLAG(bool, allow_user_segv_handler, true,
"handle_*=1 will be upgraded to handle_*=2.")
COMMON_FLAG(bool, use_sigaltstack, true,
"If set, uses alternate stack for signal handling.")
-COMMON_FLAG(bool, detect_deadlocks, false,
+COMMON_FLAG(bool, detect_deadlocks, true,
"If set, deadlock detection is enabled.")
COMMON_FLAG(
uptr, clear_shadow_mmap_threshold, 64 * 1024,
@@ -217,9 +218,9 @@ COMMON_FLAG(bool, intercept_stat, true,
COMMON_FLAG(bool, intercept_send, true,
"If set, uses custom wrappers for send* functions "
"to find more errors.")
-COMMON_FLAG(bool, decorate_proc_maps, false, "If set, decorate sanitizer "
- "mappings in /proc/self/maps with "
- "user-readable names")
+COMMON_FLAG(bool, decorate_proc_maps, (bool)SANITIZER_ANDROID,
+ "If set, decorate sanitizer mappings in /proc/self/maps with "
+ "user-readable names")
COMMON_FLAG(int, exitcode, 1, "Override the program exit status if the tool "
"found an error")
COMMON_FLAG(
@@ -241,3 +242,6 @@ COMMON_FLAG(bool, dump_registers, true,
COMMON_FLAG(bool, detect_write_exec, false,
"If true, triggers warning when writable-executable pages requests "
"are being made")
+COMMON_FLAG(bool, test_only_emulate_no_memorymap, false,
+ "TEST ONLY fail to read memory mappings to emulate sanitized "
+ "\"init\"")
diff --git a/libsanitizer/sanitizer_common/sanitizer_freebsd.h b/libsanitizer/sanitizer_common/sanitizer_freebsd.h
index 47bb131..64cb21f 100644
--- a/libsanitizer/sanitizer_common/sanitizer_freebsd.h
+++ b/libsanitizer/sanitizer_common/sanitizer_freebsd.h
@@ -1,7 +1,8 @@
//===-- sanitizer_freebsd.h -------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_fuchsia.cc b/libsanitizer/sanitizer_common/sanitizer_fuchsia.cpp
index 6602f97..3dc6863 100644
--- a/libsanitizer/sanitizer_common/sanitizer_fuchsia.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_fuchsia.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_fuchsia.cc ----------------------------------------------===//
+//===-- sanitizer_fuchsia.cpp ---------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -45,9 +46,14 @@ unsigned int internal_sleep(unsigned int seconds) {
return 0;
}
-u64 NanoTime() { return _zx_clock_get(ZX_CLOCK_UTC); }
+u64 NanoTime() {
+ zx_time_t time;
+ zx_status_t status = _zx_clock_get(ZX_CLOCK_UTC, &time);
+ CHECK_EQ(status, ZX_OK);
+ return time;
+}
-u64 MonotonicNanoTime() { return _zx_clock_get(ZX_CLOCK_MONOTONIC); }
+u64 MonotonicNanoTime() { return _zx_clock_get_monotonic(); }
uptr internal_getpid() {
zx_info_handle_basic_t info;
@@ -84,8 +90,10 @@ void GetThreadStackTopAndBottom(bool, uptr *stack_top, uptr *stack_bottom) {
*stack_top = *stack_bottom + size;
}
+void InitializePlatformEarly() {}
void MaybeReexec() {}
void CheckASLR() {}
+void CheckMPROTECT() {}
void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {}
void DisableCoreDumperIfNecessary() {}
void InstallDeadlySignalHandlers(SignalHandlerType handler) {}
@@ -117,8 +125,9 @@ void BlockingMutex::Lock() {
if (atomic_exchange(m, MtxLocked, memory_order_acquire) == MtxUnlocked)
return;
while (atomic_exchange(m, MtxSleeping, memory_order_acquire) != MtxUnlocked) {
- zx_status_t status = _zx_futex_wait(reinterpret_cast<zx_futex_t *>(m),
- MtxSleeping, ZX_TIME_INFINITE);
+ zx_status_t status =
+ _zx_futex_wait(reinterpret_cast<zx_futex_t *>(m), MtxSleeping,
+ ZX_HANDLE_INVALID, ZX_TIME_INFINITE);
if (status != ZX_ERR_BAD_STATE) // Normal race.
CHECK_EQ(status, ZX_OK);
}
@@ -205,10 +214,10 @@ uptr ReservedAddressRange::Init(uptr init_size, const char *name,
uintptr_t base;
zx_handle_t vmar;
zx_status_t status =
- _zx_vmar_allocate_old(_zx_vmar_root_self(), 0, init_size,
- ZX_VM_FLAG_CAN_MAP_READ | ZX_VM_FLAG_CAN_MAP_WRITE |
- ZX_VM_FLAG_CAN_MAP_SPECIFIC,
- &vmar, &base);
+ _zx_vmar_allocate(
+ _zx_vmar_root_self(),
+ ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE | ZX_VM_CAN_MAP_SPECIFIC,
+ 0, init_size, &vmar, &base);
if (status != ZX_OK)
ReportMmapFailureAndDie(init_size, name, "zx_vmar_allocate", status);
base_ = reinterpret_cast<void *>(base);
@@ -248,12 +257,14 @@ static uptr DoMmapFixedOrDie(zx_handle_t vmar, uptr fixed_addr, uptr map_size,
return addr;
}
-uptr ReservedAddressRange::Map(uptr fixed_addr, uptr map_size) {
+uptr ReservedAddressRange::Map(uptr fixed_addr, uptr map_size,
+ const char *name) {
return DoMmapFixedOrDie(os_handle_, fixed_addr, map_size, base_,
name_, false);
}
-uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr map_size) {
+uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr map_size,
+ const char *name) {
return DoMmapFixedOrDie(os_handle_, fixed_addr, map_size, base_,
name_, true);
}
@@ -449,6 +460,7 @@ char **StoredArgv;
char **StoredEnviron;
char **GetArgv() { return StoredArgv; }
+char **GetEnviron() { return StoredEnviron; }
const char *GetEnv(const char *name) {
if (StoredEnviron) {
diff --git a/libsanitizer/sanitizer_common/sanitizer_fuchsia.h b/libsanitizer/sanitizer_common/sanitizer_fuchsia.h
index 59b679d..5a2ad32 100644
--- a/libsanitizer/sanitizer_common/sanitizer_fuchsia.h
+++ b/libsanitizer/sanitizer_common/sanitizer_fuchsia.h
@@ -1,7 +1,8 @@
//===-- sanitizer_fuchsia.h ------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===---------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_getauxval.h b/libsanitizer/sanitizer_common/sanitizer_getauxval.h
index a286861..cbd1af1 100644
--- a/libsanitizer/sanitizer_common/sanitizer_getauxval.h
+++ b/libsanitizer/sanitizer_common/sanitizer_getauxval.h
@@ -1,7 +1,8 @@
//===-- sanitizer_getauxval.h -----------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_hash.h b/libsanitizer/sanitizer_common/sanitizer_hash.h
new file mode 100644
index 0000000..3d97dcc
--- /dev/null
+++ b/libsanitizer/sanitizer_common/sanitizer_hash.h
@@ -0,0 +1,43 @@
+//===-- sanitizer_common.h --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a simple hash function.
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER_HASH_H
+#define SANITIZER_HASH_H
+
+#include "sanitizer_internal_defs.h"
+
+namespace __sanitizer {
+class MurMur2HashBuilder {
+ static const u32 m = 0x5bd1e995;
+ static const u32 seed = 0x9747b28c;
+ static const u32 r = 24;
+ u32 h;
+
+ public:
+ explicit MurMur2HashBuilder(u32 init = 0) { h = seed ^ init; }
+ void add(u32 k) {
+ k *= m;
+ k ^= k >> r;
+ k *= m;
+ h *= m;
+ h ^= k;
+ }
+ u32 get() {
+ u32 x = h;
+ x ^= x >> 13;
+ x *= m;
+ x ^= x >> 15;
+ return x;
+ }
+};
+} //namespace __sanitizer
+
+#endif // SANITIZER_HASH_H
diff --git a/libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc b/libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc
index b42e631..1ec7382 100644
--- a/libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_interceptors_ioctl_netbsd.inc -----------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -23,7 +24,7 @@ struct ioctl_desc {
const char *name;
};
-const unsigned ioctl_table_max = 1198;
+const unsigned ioctl_table_max = 1236;
static ioctl_desc ioctl_table[ioctl_table_max];
static unsigned ioctl_table_size = 0;
@@ -286,6 +287,8 @@ static void ioctl_table_fill() {
_(MLX_GET_CINFO, WRITE, struct_mlx_cinfo_sz);
/* Entries from file: dev/ic/nvmeio.h */
_(NVME_PASSTHROUGH_CMD, READWRITE, struct_nvme_pt_command_sz);
+ /* Entries from file: dev/ic/qemufwcfgio.h */
+ _(FWCFGIO_SET_INDEX, READ, sizeof(u16));
/* Entries from file: dev/ir/irdaio.h */
_(IRDA_RESET_PARAMS, NONE, 0);
_(IRDA_SET_PARAMS, READ, struct_irda_params_sz);
@@ -294,9 +297,6 @@ static void ioctl_table_fill() {
_(IRFRAMETTY_GET_DEVICE, WRITE, sizeof(unsigned int));
_(IRFRAMETTY_GET_DONGLE, WRITE, sizeof(unsigned int));
_(IRFRAMETTY_SET_DONGLE, READ, sizeof(unsigned int));
- /* Entries from file: dev/isa/satlinkio.h */
- _(SATIORESET, NONE, 0);
- _(SATIOGID, WRITE, struct_satlink_id_sz);
/* Entries from file: dev/isa/isvio.h */
_(ISV_CMD, READWRITE, struct_isv_cmd_sz);
/* Entries from file: dev/isa/wtreg.h */
@@ -645,6 +645,30 @@ static void ioctl_table_fill() {
_(SPKRTUNE, NONE, 0);
_(SPKRGETVOL, WRITE, sizeof(unsigned int));
_(SPKRSETVOL, READ, sizeof(unsigned int));
+#if defined(__x86_64__)
+ /* Entries from file: dev/nvmm/nvmm_ioctl.h */
+ _(NVMM_IOC_CAPABILITY, WRITE, struct_nvmm_ioc_capability_sz);
+ _(NVMM_IOC_MACHINE_CREATE, READWRITE, struct_nvmm_ioc_machine_create_sz);
+ _(NVMM_IOC_MACHINE_DESTROY, READ, struct_nvmm_ioc_machine_destroy_sz);
+ _(NVMM_IOC_MACHINE_CONFIGURE, READ, struct_nvmm_ioc_machine_configure_sz);
+ _(NVMM_IOC_VCPU_CREATE, READ, struct_nvmm_ioc_vcpu_create_sz);
+ _(NVMM_IOC_VCPU_DESTROY, READ, struct_nvmm_ioc_vcpu_destroy_sz);
+ _(NVMM_IOC_VCPU_SETSTATE, READ, struct_nvmm_ioc_vcpu_setstate_sz);
+ _(NVMM_IOC_VCPU_GETSTATE, READ, struct_nvmm_ioc_vcpu_getstate_sz);
+ _(NVMM_IOC_VCPU_INJECT, READ, struct_nvmm_ioc_vcpu_inject_sz);
+ _(NVMM_IOC_VCPU_RUN, READWRITE, struct_nvmm_ioc_vcpu_run_sz);
+ _(NVMM_IOC_GPA_MAP, READ, struct_nvmm_ioc_gpa_map_sz);
+ _(NVMM_IOC_GPA_UNMAP, READ, struct_nvmm_ioc_gpa_unmap_sz);
+ _(NVMM_IOC_HVA_MAP, READ, struct_nvmm_ioc_hva_map_sz);
+ _(NVMM_IOC_HVA_UNMAP, READ, struct_nvmm_ioc_hva_unmap_sz);
+ _(NVMM_IOC_CTL, READ, struct_nvmm_ioc_ctl_sz);
+#endif
+ /* Entries from file: dev/spi/spi_io.h */
+ _(SPI_IOCTL_CONFIGURE, READ, struct_spi_ioctl_configure_sz);
+ _(SPI_IOCTL_TRANSFER, READ, struct_spi_ioctl_transfer_sz);
+ /* Entries from file: fs/autofs/autofs_ioctl.h */
+ _(AUTOFSREQUEST, WRITE, struct_autofs_daemon_request_sz);
+ _(AUTOFSDONE, READ, struct_autofs_daemon_done_sz);
/* Entries from file: net/bpf.h */
_(BIOCGBLEN, WRITE, sizeof(unsigned int));
_(BIOCSBLEN, READWRITE, sizeof(unsigned int));
@@ -664,20 +688,12 @@ static void ioctl_table_fill() {
_(BIOCSHDRCMPLT, READ, sizeof(unsigned int));
_(BIOCSDLT, READ, sizeof(unsigned int));
_(BIOCGDLTLIST, READWRITE, struct_bpf_dltlist_sz);
- _(BIOCGSEESENT, WRITE, sizeof(unsigned int));
- _(BIOCSSEESENT, READ, sizeof(unsigned int));
+ _(BIOCGDIRECTION, WRITE, sizeof(unsigned int));
+ _(BIOCSDIRECTION, READ, sizeof(unsigned int));
_(BIOCSRTIMEOUT, READ, struct_timeval_sz);
_(BIOCGRTIMEOUT, WRITE, struct_timeval_sz);
_(BIOCGFEEDBACK, WRITE, sizeof(unsigned int));
_(BIOCSFEEDBACK, READ, sizeof(unsigned int));
- /* Entries from file: net/if_atm.h */
- _(SIOCRAWATM, READWRITE, sizeof(int));
- _(SIOCATMENA, READWRITE, struct_atm_pseudoioctl_sz);
- _(SIOCATMDIS, READWRITE, struct_atm_pseudoioctl_sz);
- _(SIOCSPVCTX, READWRITE, struct_pvctxreq_sz);
- _(SIOCGPVCTX, READWRITE, struct_pvctxreq_sz);
- _(SIOCSPVCSIF, READWRITE, struct_ifreq_sz);
- _(SIOCGPVCSIF, READWRITE, struct_ifreq_sz);
/* Entries from file: net/if_gre.h */
_(GRESADDRS, READ, struct_ifreq_sz);
_(GRESADDRD, READ, struct_ifreq_sz);
@@ -713,12 +729,12 @@ static void ioctl_table_fill() {
/* Entries from file: net/npf.h */
_(IOC_NPF_VERSION, WRITE, sizeof(int));
_(IOC_NPF_SWITCH, READ, sizeof(int));
- _(IOC_NPF_LOAD, READWRITE, struct_plistref_sz);
+ _(IOC_NPF_LOAD, READWRITE, struct_nvlist_ref_sz);
_(IOC_NPF_TABLE, READ, struct_npf_ioctl_table_sz);
_(IOC_NPF_STATS, READ, sizeof(uptr));
- _(IOC_NPF_SAVE, WRITE, struct_plistref_sz);
- _(IOC_NPF_RULE, READWRITE, struct_plistref_sz);
- _(IOC_NPF_CONN_LOOKUP, READWRITE, struct_plistref_sz);
+ _(IOC_NPF_SAVE, WRITE, struct_nvlist_ref_sz);
+ _(IOC_NPF_RULE, READWRITE, struct_nvlist_ref_sz);
+ _(IOC_NPF_CONN_LOOKUP, READWRITE, struct_nvlist_ref_sz);
/* Entries from file: net/if_pppoe.h */
_(PPPOESETPARMS, READ, struct_pppoediscparms_sz);
_(PPPOEGETPARMS, READWRITE, struct_pppoediscparms_sz);
@@ -841,6 +857,9 @@ static void ioctl_table_fill() {
_(SIOCGNATS, READWRITE, struct_ipfobj_sz);
_(SIOCGNATL, READWRITE, struct_ipfobj_sz);
_(SIOCPURGENAT, READWRITE, struct_ipfobj_sz);
+ /* Entries from file: netinet/sctp_uio.h */
+ _(SIOCCONNECTX, READWRITE, struct_sctp_connectx_addrs_sz);
+ _(SIOCCONNECTXDEL, READWRITE, struct_sctp_connectx_addrs_sz);
/* Entries from file: netinet6/in6_var.h */
_(SIOCSIFINFO_FLAGS, READWRITE, struct_in6_ndireq_sz);
_(SIOCAADDRCTL_POLICY, READ, struct_in6_addrpolicy_sz);
@@ -880,6 +899,9 @@ static void ioctl_table_fill() {
_(AUDIO_GETBUFINFO, WRITE, struct_audio_info_sz);
_(AUDIO_SETCHAN, READ, sizeof(int));
_(AUDIO_GETCHAN, WRITE, sizeof(int));
+ _(AUDIO_QUERYFORMAT, READWRITE, struct_audio_format_query_sz);
+ _(AUDIO_GETFORMAT, WRITE, struct_audio_info_sz);
+ _(AUDIO_SETFORMAT, READ, struct_audio_info_sz);
_(AUDIO_MIXER_READ, READWRITE, struct_mixer_ctrl_sz);
_(AUDIO_MIXER_WRITE, READWRITE, struct_mixer_ctrl_sz);
_(AUDIO_MIXER_DEVINFO, READWRITE, struct_mixer_devinfo_sz);
@@ -970,6 +992,7 @@ static void ioctl_table_fill() {
_(DIOCMWEDGES, WRITE, sizeof(int));
_(DIOCGSECTORSIZE, WRITE, sizeof(unsigned int));
_(DIOCGMEDIASIZE, WRITE, sizeof(uptr));
+ _(DIOCRMWEDGES, WRITE, sizeof(int));
/* Entries from file: sys/drvctlio.h */
_(DRVDETACHDEV, READ, struct_devdetachargs_sz);
_(DRVRESCANBUS, READ, struct_devrescanargs_sz);
@@ -1000,6 +1023,8 @@ static void ioctl_table_fill() {
/* Entries from file: sys/filio.h */
_(FIOCLEX, NONE, 0);
_(FIONCLEX, NONE, 0);
+ _(FIOSEEKDATA, READWRITE, sizeof(uptr));
+ _(FIOSEEKHOLE, READWRITE, sizeof(uptr));
_(FIONREAD, WRITE, sizeof(int));
_(FIONBIO, READ, sizeof(int));
_(FIOASYNC, READ, sizeof(int));
@@ -1093,7 +1118,6 @@ static void ioctl_table_fill() {
/* Entries from file: sys/power.h */
_(POWER_EVENT_RECVDICT, READWRITE, struct_plistref_sz);
_(POWER_IOC_GET_TYPE, WRITE, struct_power_type_sz);
- _(POWER_IOC_GET_TYPE_WITH_LOSSAGE, WRITE, sizeof(uptr));
/* Entries from file: sys/radioio.h */
_(RIOCGINFO, WRITE, struct_radio_info_sz);
_(RIOCSINFO, READWRITE, struct_radio_info_sz);
@@ -1131,6 +1155,7 @@ static void ioctl_table_fill() {
_(SIOCATMARK, WRITE, sizeof(int));
_(SIOCSPGRP, READ, sizeof(int));
_(SIOCGPGRP, WRITE, sizeof(int));
+ _(SIOCPEELOFF, READWRITE, sizeof(int));
_(SIOCADDRT, READ, struct_ortentry_sz);
_(SIOCDELRT, READ, struct_ortentry_sz);
_(SIOCSIFADDR, READ, struct_ifreq_sz);
@@ -1188,6 +1213,12 @@ static void ioctl_table_fill() {
_(SIOCSLINKSTR, READ, struct_ifdrv_sz);
_(SIOCGETHERCAP, READWRITE, struct_eccapreq_sz);
_(SIOCGIFINDEX, READWRITE, struct_ifreq_sz);
+ _(SIOCSETHERCAP, READ, struct_eccapreq_sz);
+ _(SIOCSIFDESCR, READ, struct_ifreq_sz);
+ _(SIOCGIFDESCR, READWRITE, struct_ifreq_sz);
+ _(SIOCGUMBINFO, READWRITE, struct_ifreq_sz);
+ _(SIOCSUMBPARAM, READ, struct_ifreq_sz);
+ _(SIOCGUMBPARAM, READWRITE, struct_ifreq_sz);
_(SIOCSETPFSYNC, READ, struct_ifreq_sz);
_(SIOCGETPFSYNC, READWRITE, struct_ifreq_sz);
/* Entries from file: sys/timepps.h */
@@ -1314,6 +1345,21 @@ static void ioctl_table_fill() {
_(WDOGIOC_TICKLE, NONE, 0);
_(WDOGIOC_GTICKLER, WRITE, sizeof(int));
_(WDOGIOC_GWDOGS, READWRITE, struct_wdog_conf_sz);
+ /* Entries from file: sys/kcov.h */
+ _(KCOV_IOC_SETBUFSIZE, READ, sizeof(u64));
+ _(KCOV_IOC_ENABLE, READ, sizeof(int));
+ _(KCOV_IOC_DISABLE, NONE, 0);
+ /* Entries from file: sys/ipmi.h */
+ _(IPMICTL_RECEIVE_MSG_TRUNC, READWRITE, struct_ipmi_recv_sz);
+ _(IPMICTL_RECEIVE_MSG, READWRITE, struct_ipmi_recv_sz);
+ _(IPMICTL_SEND_COMMAND, READ, struct_ipmi_req_sz);
+ _(IPMICTL_REGISTER_FOR_CMD, READ, struct_ipmi_cmdspec_sz);
+ _(IPMICTL_UNREGISTER_FOR_CMD, READ, struct_ipmi_cmdspec_sz);
+ _(IPMICTL_SET_GETS_EVENTS_CMD, READ, sizeof(int));
+ _(IPMICTL_SET_MY_ADDRESS_CMD, READ, sizeof(unsigned int));
+ _(IPMICTL_GET_MY_ADDRESS_CMD, WRITE, sizeof(unsigned int));
+ _(IPMICTL_SET_MY_LUN_CMD, READ, sizeof(unsigned int));
+ _(IPMICTL_GET_MY_LUN_CMD, WRITE, sizeof(unsigned int));
/* Entries from file: soundcard.h */
_(SNDCTL_DSP_RESET, NONE, 0);
_(SNDCTL_DSP_SYNC, NONE, 0);
diff --git a/libsanitizer/sanitizer_common/sanitizer_interface_internal.h b/libsanitizer/sanitizer_common/sanitizer_interface_internal.h
index 6597efa2..c110eff 100644
--- a/libsanitizer/sanitizer_common/sanitizer_interface_internal.h
+++ b/libsanitizer/sanitizer_common/sanitizer_interface_internal.h
@@ -1,7 +1,8 @@
//===-- sanitizer_interface_internal.h --------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
index 26bea8b..e0c6506 100644
--- a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
+++ b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h
@@ -1,7 +1,8 @@
//===-- sanitizer_internal_defs.h -------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -195,7 +196,9 @@ typedef u64 tid_t;
// This header should NOT include any other headers to avoid portability issues.
// Common defs.
+#ifndef INLINE
#define INLINE inline
+#endif
#define INTERFACE_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE
#define SANITIZER_WEAK_DEFAULT_IMPL \
extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE NOINLINE
@@ -419,7 +422,6 @@ inline void Trap() {
namespace __asan { using namespace __sanitizer; } // NOLINT
namespace __dsan { using namespace __sanitizer; } // NOLINT
namespace __dfsan { using namespace __sanitizer; } // NOLINT
-namespace __esan { using namespace __sanitizer; } // NOLINT
namespace __lsan { using namespace __sanitizer; } // NOLINT
namespace __msan { using namespace __sanitizer; } // NOLINT
namespace __hwasan { using namespace __sanitizer; } // NOLINT
diff --git a/libsanitizer/sanitizer_common/sanitizer_lfstack.h b/libsanitizer/sanitizer_common/sanitizer_lfstack.h
index 8bd0e91..af2ca55 100644
--- a/libsanitizer/sanitizer_common/sanitizer_lfstack.h
+++ b/libsanitizer/sanitizer_common/sanitizer_lfstack.h
@@ -1,7 +1,8 @@
//===-- sanitizer_lfstack.h -=-----------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_libc.cc b/libsanitizer/sanitizer_common/sanitizer_libc.cpp
index 94fa69b..5c9d3a8 100644
--- a/libsanitizer/sanitizer_common/sanitizer_libc.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_libc.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_libc.cc -------------------------------------------------===//
+//===-- sanitizer_libc.cpp ------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_libc.h b/libsanitizer/sanitizer_common/sanitizer_libc.h
index 4bc6791..3d5db35 100644
--- a/libsanitizer/sanitizer_common/sanitizer_libc.h
+++ b/libsanitizer/sanitizer_common/sanitizer_libc.h
@@ -1,7 +1,8 @@
//===-- sanitizer_libc.h ----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_libignore.cc b/libsanitizer/sanitizer_common/sanitizer_libignore.cpp
index 0a55149..eb9bb76 100644
--- a/libsanitizer/sanitizer_common/sanitizer_libignore.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_libignore.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_libignore.cc --------------------------------------------===//
+//===-- sanitizer_libignore.cpp -------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
diff --git a/libsanitizer/sanitizer_common/sanitizer_libignore.h b/libsanitizer/sanitizer_common/sanitizer_libignore.h
index b2884fa..256f685 100644
--- a/libsanitizer/sanitizer_common/sanitizer_libignore.h
+++ b/libsanitizer/sanitizer_common/sanitizer_libignore.h
@@ -1,7 +1,8 @@
//===-- sanitizer_libignore.h -----------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cc b/libsanitizer/sanitizer_common/sanitizer_linux.cpp
index dc1e984..1ed6af3 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_linux.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_linux.cc ------------------------------------------------===//
+//===-- sanitizer_linux.cpp -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -127,12 +128,6 @@ const int FUTEX_WAKE_PRIVATE = FUTEX_WAKE | FUTEX_PRIVATE_FLAG;
# define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0
#endif
-#if defined(__x86_64__) || SANITIZER_MIPS64
-extern "C" {
-extern void internal_sigreturn();
-}
-#endif
-
// Note : FreeBSD had implemented both
// Linux and OpenBSD apis, available from
// future 12.x version most likely
@@ -379,6 +374,10 @@ uptr internal_filesize(fd_t fd) {
return (uptr)st.st_size;
}
+uptr internal_dup(int oldfd) {
+ return internal_syscall(SYSCALL(dup), oldfd);
+}
+
uptr internal_dup2(int oldfd, int newfd) {
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
return internal_syscall(SYSCALL(dup3), oldfd, newfd, 0);
@@ -431,7 +430,7 @@ void internal__exit(int exitcode) {
unsigned int internal_sleep(unsigned int seconds) {
struct timespec ts;
- ts.tv_sec = 1;
+ ts.tv_sec = seconds;
ts.tv_nsec = 0;
int res = internal_syscall(SYSCALL(nanosleep), &ts, &ts);
if (res) return ts.tv_sec;
@@ -447,6 +446,8 @@ uptr internal_execve(const char *filename, char *const argv[],
// ----------------- sanitizer_common.h
bool FileExists(const char *filename) {
+ if (ShouldMockFailureToOpen(filename))
+ return false;
struct stat st;
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
if (internal_syscall(SYSCALL(newfstatat), AT_FDCWD, filename, &st, 0))
@@ -621,33 +622,13 @@ char **GetArgv() {
return argv;
}
-void ReExec() {
+char **GetEnviron() {
char **argv, **envp;
- const char *pathname = "/proc/self/exe";
-
-#if SANITIZER_NETBSD
- static const int name[] = {
- CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME,
- };
- char path[400];
- uptr len;
-
- len = sizeof(path);
- if (internal_sysctl(name, ARRAY_SIZE(name), path, &len, NULL, 0) != -1)
- pathname = path;
-#elif SANITIZER_SOLARIS
- pathname = getexecname();
- CHECK_NE(pathname, NULL);
-#endif
-
GetArgsAndEnv(&argv, &envp);
- uptr rv = internal_execve(pathname, argv, envp);
- int rverrno;
- CHECK_EQ(internal_iserror(rv, &rverrno), true);
- Printf("execve failed, errno %d\n", rverrno);
- Die();
+ return envp;
}
-#endif
+
+#endif // !SANITIZER_OPENBSD
#if !SANITIZER_SOLARIS
enum MutexState {
@@ -790,14 +771,19 @@ int internal_sysctl(const int *name, unsigned int namelen, void *oldp,
return sysctl(name, namelen, oldp, (size_t *)oldlenp, (void *)newp,
(size_t)newlen);
#else
- return sysctl(name, namelen, oldp, (size_t *)oldlenp, newp, (size_t)newlen);
+ return internal_syscall(SYSCALL(__sysctl), name, namelen, oldp,
+ (size_t *)oldlenp, newp, (size_t)newlen);
#endif
}
#if SANITIZER_FREEBSD
int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp,
const void *newp, uptr newlen) {
- return sysctlbyname(sname, oldp, (size_t *)oldlenp, newp, (size_t)newlen);
+ static decltype(sysctlbyname) *real = nullptr;
+ if (!real)
+ real = (decltype(sysctlbyname) *)dlsym(RTLD_NEXT, "sysctlbyname");
+ CHECK(real);
+ return real(sname, oldp, (size_t *)oldlenp, newp, (size_t)newlen);
}
#endif
#endif
@@ -849,24 +835,6 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) {
}
return result;
}
-
-// Invokes sigaction via a raw syscall with a restorer, but does not support
-// all platforms yet.
-// We disable for Go simply because we have not yet added to buildgo.sh.
-#if (defined(__x86_64__) || SANITIZER_MIPS64) && !SANITIZER_GO
-int internal_sigaction_syscall(int signum, const void *act, void *oldact) {
- if (act == nullptr)
- return internal_sigaction_norestorer(signum, act, oldact);
- __sanitizer_sigaction u_adjust;
- internal_memcpy(&u_adjust, act, sizeof(u_adjust));
-#if !SANITIZER_ANDROID || !SANITIZER_MIPS32
- if (u_adjust.sa_restorer == nullptr) {
- u_adjust.sa_restorer = internal_sigreturn;
- }
-#endif
- return internal_sigaction_norestorer(signum, (const void *)&u_adjust, oldact);
-}
-#endif // defined(__x86_64__) && !SANITIZER_GO
#endif // SANITIZER_LINUX
uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
@@ -1021,6 +989,8 @@ static uptr GetKernelAreaSize() {
// Firstly check if there are writable segments
// mapped to top gigabyte (e.g. stack).
MemoryMappingLayout proc_maps(/*cache_enabled*/true);
+ if (proc_maps.Error())
+ return 0;
MemoryMappedSegment segment;
while (proc_maps.Next(&segment)) {
if ((segment.end >= 3 * gbyte) && segment.IsWritable()) return 0;
@@ -1064,7 +1034,7 @@ uptr GetMaxVirtualAddress() {
return (1ULL << 40) - 1; // 0x000000ffffffffffUL;
# elif defined(__s390x__)
return (1ULL << 53) - 1; // 0x001fffffffffffffUL;
-# elif defined(__sparc__)
+#elif defined(__sparc__)
return ~(uptr)0;
# else
return (1ULL << 47) - 1; // 0x00007fffffffffffUL;
@@ -1088,18 +1058,25 @@ uptr GetMaxUserVirtualAddress() {
return addr;
}
+#if !SANITIZER_ANDROID
uptr GetPageSize() {
-// Android post-M sysconf(_SC_PAGESIZE) crashes if called from .preinit_array.
-#if SANITIZER_ANDROID
- return 4096;
-#elif SANITIZER_LINUX && (defined(__x86_64__) || defined(__i386__))
+#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__i386__))
return EXEC_PAGESIZE;
#elif SANITIZER_USE_GETAUXVAL
return getauxval(AT_PAGESZ);
+#elif SANITIZER_FREEBSD || SANITIZER_NETBSD
+// Use sysctl as sysconf can trigger interceptors internally.
+ int pz = 0;
+ uptr pzl = sizeof(pz);
+ int mib[2] = {CTL_HW, HW_PAGESIZE};
+ int rv = internal_sysctl(mib, 2, &pz, &pzl, nullptr, 0);
+ CHECK_EQ(rv, 0);
+ return (uptr)pz;
#else
return sysconf(_SC_PAGESIZE); // EXEC_PAGESIZE may not be trustworthy.
#endif
}
+#endif // !SANITIZER_ANDROID
#if !SANITIZER_OPENBSD
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
@@ -1853,17 +1830,17 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
#elif defined(__sparc__)
// Decode the instruction to determine the access type.
// From OpenSolaris $SRC/uts/sun4/os/trap.c (get_accesstype).
-# if SANITIZER_SOLARIS
+#if SANITIZER_SOLARIS
uptr pc = ucontext->uc_mcontext.gregs[REG_PC];
-# else
+#else
// Historical BSDism here.
struct sigcontext *scontext = (struct sigcontext *)context;
-# if defined(__arch64__)
+#if defined(__arch64__)
uptr pc = scontext->sigc_regs.tpc;
-# else
+#else
uptr pc = scontext->si_regs.pc;
-# endif
-# endif
+#endif
+#endif
u32 instr = *(u32 *)pc;
return (instr >> 21) & 1 ? WRITE: READ;
#else
@@ -1954,27 +1931,27 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
// pointer, but GCC always uses r31 when we need a frame pointer.
*bp = ucontext->uc_mcontext.regs->gpr[PT_R31];
#elif defined(__sparc__)
-# if defined(__arch64__) || defined(__sparcv9)
-# define STACK_BIAS 2047
-# else
-# define STACK_BIAS 0
+#if defined(__arch64__) || defined(__sparcv9)
+#define STACK_BIAS 2047
+#else
+#define STACK_BIAS 0
# endif
# if SANITIZER_SOLARIS
- ucontext_t *ucontext = (ucontext_t*)context;
+ ucontext_t *ucontext = (ucontext_t *)context;
*pc = ucontext->uc_mcontext.gregs[REG_PC];
*sp = ucontext->uc_mcontext.gregs[REG_O6] + STACK_BIAS;
-# else
+#else
// Historical BSDism here.
struct sigcontext *scontext = (struct sigcontext *)context;
-# if defined(__arch64__)
+#if defined(__arch64__)
*pc = scontext->sigc_regs.tpc;
*sp = scontext->sigc_regs.u_regs[14] + STACK_BIAS;
-# else
+#else
*pc = scontext->si_regs.pc;
*sp = scontext->si_regs.u_regs[14];
-# endif
+#endif
# endif
- *bp = (uptr) ((uhwptr *) *sp)[14] + STACK_BIAS;
+ *bp = (uptr)((uhwptr *)*sp)[14] + STACK_BIAS;
#elif defined(__mips__)
ucontext_t *ucontext = (ucontext_t*)context;
*pc = ucontext->uc_mcontext.pc;
@@ -1996,6 +1973,10 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
void SignalContext::InitPcSpBp() { GetPcSpBp(context, &pc, &sp, &bp); }
+void InitializePlatformEarly() {
+ // Do nothing.
+}
+
void MaybeReexec() {
// No need to re-exec on Linux.
}
@@ -2035,6 +2016,30 @@ void CheckASLR() {
#endif
}
+void CheckMPROTECT() {
+#if SANITIZER_NETBSD
+ int mib[3];
+ int paxflags;
+ uptr len = sizeof(paxflags);
+
+ mib[0] = CTL_PROC;
+ mib[1] = internal_getpid();
+ mib[2] = PROC_PID_PAXFLAGS;
+
+ if (UNLIKELY(internal_sysctl(mib, 3, &paxflags, &len, NULL, 0) == -1)) {
+ Printf("sysctl failed\n");
+ Die();
+ }
+
+ if (UNLIKELY(paxflags & CTL_PROC_PAXFLAGS_MPROTECT)) {
+ Printf("This sanitizer is not compatible with enabled MPROTECT\n");
+ Die();
+ }
+#else
+ // Do nothing
+#endif
+}
+
void PrintModuleMap() { }
void CheckNoDeepBind(const char *filename, int flag) {
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.h b/libsanitizer/sanitizer_common/sanitizer_linux.h
index e1f606f..c28347a 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux.h
+++ b/libsanitizer/sanitizer_common/sanitizer_linux.h
@@ -1,7 +1,8 @@
//===-- sanitizer_linux.h ---------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -16,6 +17,7 @@
SANITIZER_OPENBSD || SANITIZER_SOLARIS
#include "sanitizer_common.h"
#include "sanitizer_internal_defs.h"
+#include "sanitizer_platform_limits_freebsd.h"
#include "sanitizer_platform_limits_netbsd.h"
#include "sanitizer_platform_limits_openbsd.h"
#include "sanitizer_platform_limits_posix.h"
@@ -56,10 +58,6 @@ uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5);
// (like the process-wide error reporting SEGV handler) must use
// internal_sigaction instead.
int internal_sigaction_norestorer(int signum, const void *act, void *oldact);
-#if (defined(__x86_64__) || SANITIZER_MIPS64) && !SANITIZER_GO
-// Uses a raw system call to avoid interceptors.
-int internal_sigaction_syscall(int signum, const void *act, void *oldact);
-#endif
void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) \
|| defined(__powerpc64__) || defined(__s390__) || defined(__i386__) \
@@ -69,6 +67,9 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
#endif
#elif SANITIZER_FREEBSD
void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
+#elif SANITIZER_NETBSD
+void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
+uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg);
#endif // SANITIZER_LINUX
// This class reads thread IDs from /proc/<pid>/task using only syscalls.
@@ -103,6 +104,17 @@ bool LibraryNameIs(const char *full_name, const char *base_name);
// Call cb for each region mapped by map.
void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr));
+// Releases memory pages entirely within the [beg, end] address range.
+// The pages no longer count toward RSS; reads are guaranteed to return 0.
+// Requires (but does not verify!) that pages are MAP_PRIVATE.
+INLINE void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) {
+ // man madvise on Linux promises zero-fill for anonymous private pages.
+ // Testing shows the same behaviour for private (but not anonymous) mappings
+ // of shm_open() files, as long as the underlying file is untouched.
+ CHECK(SANITIZER_LINUX);
+ ReleaseMemoryPagesToOS(beg, end);
+}
+
#if SANITIZER_ANDROID
#if defined(__aarch64__)
@@ -131,13 +143,13 @@ void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr));
#error "Unsupported architecture."
#endif
-// The Android Bionic team has allocated a TLS slot for TSan starting with N,
-// given that Android currently doesn't support ELF TLS. It is used to store
-// Sanitizers thread specific data.
-static const int TLS_SLOT_TSAN = 8;
+// The Android Bionic team has allocated a TLS slot for sanitizers starting
+// with Q, given that Android currently doesn't support ELF TLS. It is used to
+// store sanitizer thread specific data.
+static const int TLS_SLOT_SANITIZER = 6;
ALWAYS_INLINE uptr *get_android_tls_ptr() {
- return reinterpret_cast<uptr *>(&__get_tls()[TLS_SLOT_TSAN]);
+ return reinterpret_cast<uptr *>(&__get_tls()[TLS_SLOT_SANITIZER]);
}
#endif // SANITIZER_ANDROID
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
index 28360f5..7dc38a0 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_linux_libcdep.cc ----------------------------------------===//
+//===-- sanitizer_linux_libcdep.cpp ---------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -21,6 +22,7 @@
#include "sanitizer_file.h"
#include "sanitizer_flags.h"
#include "sanitizer_freebsd.h"
+#include "sanitizer_getauxval.h"
#include "sanitizer_linux.h"
#include "sanitizer_placement_new.h"
#include "sanitizer_procmaps.h"
@@ -50,6 +52,7 @@
#endif
#if SANITIZER_SOLARIS
+#include <stdlib.h>
#include <thread.h>
#endif
@@ -97,6 +100,10 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
// Find the mapping that contains a stack variable.
MemoryMappingLayout proc_maps(/*cache_enabled*/true);
+ if (proc_maps.Error()) {
+ *stack_top = *stack_bottom = 0;
+ return;
+ }
MemoryMappedSegment segment;
uptr prev_end = 0;
while (proc_maps.Next(&segment)) {
@@ -808,6 +815,40 @@ u64 MonotonicNanoTime() {
}
#endif // SANITIZER_LINUX && !SANITIZER_GO
+#if !SANITIZER_OPENBSD
+void ReExec() {
+ const char *pathname = "/proc/self/exe";
+
+#if SANITIZER_NETBSD
+ static const int name[] = {
+ CTL_KERN,
+ KERN_PROC_ARGS,
+ -1,
+ KERN_PROC_PATHNAME,
+ };
+ char path[400];
+ uptr len;
+
+ len = sizeof(path);
+ if (internal_sysctl(name, ARRAY_SIZE(name), path, &len, NULL, 0) != -1)
+ pathname = path;
+#elif SANITIZER_SOLARIS
+ pathname = getexecname();
+ CHECK_NE(pathname, NULL);
+#elif SANITIZER_USE_GETAUXVAL
+ // Calling execve with /proc/self/exe sets that as $EXEC_ORIGIN. Binaries that
+ // rely on that will fail to load shared libraries. Query AT_EXECFN instead.
+ pathname = reinterpret_cast<const char *>(getauxval(AT_EXECFN));
+#endif
+
+ uptr rv = internal_execve(pathname, GetArgv(), GetEnviron());
+ int rverrno;
+ CHECK_EQ(internal_iserror(rv, &rverrno), true);
+ Printf("execve failed, errno %d\n", rverrno);
+ Die();
+}
+#endif // !SANITIZER_OPENBSD
+
} // namespace __sanitizer
#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_mips64.S b/libsanitizer/sanitizer_common/sanitizer_linux_mips64.S
deleted file mode 100644
index 8729642..0000000
--- a/libsanitizer/sanitizer_common/sanitizer_linux_mips64.S
+++ /dev/null
@@ -1,23 +0,0 @@
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-
-// Avoid being marked as needing an executable stack:
-#if defined(__linux__) && defined(__ELF__)
-.section .note.GNU-stack,"",%progbits
-#endif
-
-// Further contents are mips64 only:
-#if defined(__linux__) && defined(__mips64)
-
-.section .text
-.set noreorder
-.globl internal_sigreturn
-.type internal_sigreturn, @function
-internal_sigreturn:
-
- li $v0,5211 // #5211 is for SYS_rt_sigreturn
- syscall
-
-.size internal_sigreturn, .-internal_sigreturn
-
-#endif // defined(__linux__) && defined(__mips64)
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_s390.cc b/libsanitizer/sanitizer_common/sanitizer_linux_s390.cpp
index e55ffe0..41e187e 100644
--- a/libsanitizer/sanitizer_common/sanitizer_linux_s390.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_linux_s390.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_linux_s390.cc -------------------------------------------===//
+//===-- sanitizer_linux_s390.cpp ------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_x86_64.S b/libsanitizer/sanitizer_common/sanitizer_linux_x86_64.S
deleted file mode 100644
index 8ff9095..0000000
--- a/libsanitizer/sanitizer_common/sanitizer_linux_x86_64.S
+++ /dev/null
@@ -1,25 +0,0 @@
-// This file is dual licensed under the MIT and the University of Illinois Open
-// Source Licenses. See LICENSE.TXT for details.
-
-// Avoid being marked as needing an executable stack:
-#if defined(__linux__) && defined(__ELF__)
-.section .note.GNU-stack,"",%progbits
-#endif
-
-// Further contents are x86_64-only:
-#if defined(__linux__) && defined(__x86_64__)
-
-#include "../builtins/assembly.h"
-
-// If the "naked" function attribute were supported for x86 we could
-// do this via inline asm.
-.text
-.balign 4
-DEFINE_COMPILERRT_FUNCTION(internal_sigreturn)
- mov $0xf, %eax // 0xf == SYS_rt_sigreturn
- mov %rcx, %r10
- syscall
- ret // Won't normally reach here.
-END_COMPILERRT_FUNCTION(internal_sigreturn)
-
-#endif // defined(__linux__) && defined(__x86_64__)
diff --git a/libsanitizer/sanitizer_common/sanitizer_list.h b/libsanitizer/sanitizer_common/sanitizer_list.h
index d7e8b50..f0b9259 100644
--- a/libsanitizer/sanitizer_common/sanitizer_list.h
+++ b/libsanitizer/sanitizer_common/sanitizer_list.h
@@ -1,7 +1,8 @@
//===-- sanitizer_list.h ----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_local_address_space_view.h b/libsanitizer/sanitizer_common/sanitizer_local_address_space_view.h
new file mode 100644
index 0000000..5d1b526
--- /dev/null
+++ b/libsanitizer/sanitizer_common/sanitizer_local_address_space_view.h
@@ -0,0 +1,76 @@
+//===-- sanitizer_local_address_space_view.h --------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// `LocalAddressSpaceView` provides the local (i.e. target and current address
+// space are the same) implementation of the `AddressSpaveView` interface which
+// provides a simple interface to load memory from another process (i.e.
+// out-of-process)
+//
+// The `AddressSpaceView` interface requires that the type can be used as a
+// template parameter to objects that wish to be able to operate in an
+// out-of-process manner. In normal usage, objects are in-process and are thus
+// instantiated with the `LocalAddressSpaceView` type. This type is used to
+// load any pointers in instance methods. This implementation is effectively
+// a no-op. When an object is to be used in an out-of-process manner it is
+// instansiated with the `RemoteAddressSpaceView` type.
+//
+// By making `AddressSpaceView` a template parameter of an object, it can
+// change its implementation at compile time which has no run time overhead.
+// This also allows unifying in-process and out-of-process code which avoids
+// code duplication.
+//
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_LOCAL_ADDRES_SPACE_VIEW_H
+#define SANITIZER_LOCAL_ADDRES_SPACE_VIEW_H
+
+namespace __sanitizer {
+struct LocalAddressSpaceView {
+ // Load memory `sizeof(T) * num_elements` bytes of memory from the target
+ // process (always local for this implementation) starting at address
+ // `target_address`. The local copy of this memory is returned as a pointer.
+ // The caller should not write to this memory. The behaviour when doing so is
+ // undefined. Callers should use `LoadWritable()` to get access to memory
+ // that is writable.
+ //
+ // The lifetime of loaded memory is implementation defined.
+ template <typename T>
+ static const T *Load(const T *target_address, uptr num_elements = 1) {
+ // The target address space is the local address space so
+ // nothing needs to be copied. Just return the pointer.
+ return target_address;
+ }
+
+ // Load memory `sizeof(T) * num_elements` bytes of memory from the target
+ // process (always local for this implementation) starting at address
+ // `target_address`. The local copy of this memory is returned as a pointer.
+ // The memory returned may be written to.
+ //
+ // Writes made to the returned memory will be visible in the memory returned
+ // by subsequent `Load()` or `LoadWritable()` calls provided the
+ // `target_address` parameter is the same. It is not guaranteed that the
+ // memory returned by previous calls to `Load()` will contain any performed
+ // writes. If two or more overlapping regions of memory are loaded via
+ // separate calls to `LoadWritable()`, it is implementation defined whether
+ // writes made to the region returned by one call are visible in the regions
+ // returned by other calls.
+ //
+ // Given the above it is recommended to load the largest possible object
+ // that requires modification (e.g. a class) rather than individual fields
+ // from a class to avoid issues with overlapping writable regions.
+ //
+ // The lifetime of loaded memory is implementation defined.
+ template <typename T>
+ static T *LoadWritable(T *target_address, uptr num_elements = 1) {
+ // The target address space is the local address space so
+ // nothing needs to be copied. Just return the pointer.
+ return target_address;
+ }
+};
+} // namespace __sanitizer
+
+#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.cc b/libsanitizer/sanitizer_common/sanitizer_mac.cpp
index 28b2906..7552b7a 100644
--- a/libsanitizer/sanitizer_common/sanitizer_mac.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_mac.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_mac.cc --------------------------------------------------===//
+//===-- sanitizer_mac.cpp -------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -106,9 +107,20 @@ extern "C" int __munmap(void *, size_t) SANITIZER_WEAK_ATTRIBUTE;
#define VM_MEMORY_SANITIZER 99
#endif
+// XNU on Darwin provides a mmap flag that optimizes allocation/deallocation of
+// giant memory regions (i.e. shadow memory regions).
+#define kXnuFastMmapFd 0x4
+static size_t kXnuFastMmapThreshold = 2 << 30; // 2 GB
+static bool use_xnu_fast_mmap = false;
+
uptr internal_mmap(void *addr, size_t length, int prot, int flags,
int fd, u64 offset) {
- if (fd == -1) fd = VM_MAKE_TAG(VM_MEMORY_SANITIZER);
+ if (fd == -1) {
+ fd = VM_MAKE_TAG(VM_MEMORY_SANITIZER);
+ if (length >= kXnuFastMmapThreshold) {
+ if (use_xnu_fast_mmap) fd |= kXnuFastMmapFd;
+ }
+ }
if (&__mmap) return (uptr)__mmap(addr, length, prot, flags, fd, offset);
return (uptr)mmap(addr, length, prot, flags, fd, offset);
}
@@ -161,6 +173,10 @@ uptr internal_filesize(fd_t fd) {
return (uptr)st.st_size;
}
+uptr internal_dup(int oldfd) {
+ return dup(oldfd);
+}
+
uptr internal_dup2(int oldfd, int newfd) {
return dup2(oldfd, newfd);
}
@@ -223,25 +239,25 @@ int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp,
(size_t)newlen);
}
-int internal_forkpty(int *amaster) {
- int master, slave;
- if (openpty(&master, &slave, nullptr, nullptr, nullptr) == -1) return -1;
+int internal_forkpty(int *aparent) {
+ int parent, worker;
+ if (openpty(&parent, &worker, nullptr, nullptr, nullptr) == -1) return -1;
int pid = internal_fork();
if (pid == -1) {
- close(master);
- close(slave);
+ close(parent);
+ close(worker);
return -1;
}
if (pid == 0) {
- close(master);
- if (login_tty(slave) != 0) {
+ close(parent);
+ if (login_tty(worker) != 0) {
// We already forked, there's not much we can do. Let's quit.
Report("login_tty failed (errno %d)\n", errno);
internal__exit(1);
}
} else {
- *amaster = master;
- close(slave);
+ *aparent = parent;
+ close(worker);
}
return pid;
}
@@ -265,6 +281,8 @@ uptr internal_waitpid(int pid, int *status, int options) {
// ----------------- sanitizer_common.h
bool FileExists(const char *filename) {
+ if (ShouldMockFailureToOpen(filename))
+ return false;
struct stat st;
if (stat(filename, &st))
return false;
@@ -360,6 +378,10 @@ void CheckASLR() {
// Do nothing
}
+void CheckMPROTECT() {
+ // Do nothing
+}
+
uptr GetPageSize() {
return sysconf(_SC_PAGESIZE);
}
@@ -512,27 +534,35 @@ MacosVersion GetMacosVersionInternal() {
CHECK_NE(internal_sysctl(mib, 2, 0, &len, 0, 0), -1);
CHECK_LT(len, maxlen);
CHECK_NE(internal_sysctl(mib, 2, version, &len, 0, 0), -1);
- switch (version[0]) {
- case '9': return MACOS_VERSION_LEOPARD;
- case '1': {
- switch (version[1]) {
- case '0': return MACOS_VERSION_SNOW_LEOPARD;
- case '1': return MACOS_VERSION_LION;
- case '2': return MACOS_VERSION_MOUNTAIN_LION;
- case '3': return MACOS_VERSION_MAVERICKS;
- case '4': return MACOS_VERSION_YOSEMITE;
- case '5': return MACOS_VERSION_EL_CAPITAN;
- case '6': return MACOS_VERSION_SIERRA;
- case '7': return MACOS_VERSION_HIGH_SIERRA;
- case '8': return MACOS_VERSION_MOJAVE;
- default:
- if (IsDigit(version[1]))
- return MACOS_VERSION_UNKNOWN_NEWER;
- else
- return MACOS_VERSION_UNKNOWN;
- }
- }
- default: return MACOS_VERSION_UNKNOWN;
+
+ // Expect <major>.<minor>(.<patch>)
+ CHECK_GE(len, 3);
+ const char *p = version;
+ int major = internal_simple_strtoll(p, &p, /*base=*/10);
+ if (*p != '.') return MACOS_VERSION_UNKNOWN;
+ p += 1;
+ int minor = internal_simple_strtoll(p, &p, /*base=*/10);
+ if (*p != '.') return MACOS_VERSION_UNKNOWN;
+
+ switch (major) {
+ case 9: return MACOS_VERSION_LEOPARD;
+ case 10: return MACOS_VERSION_SNOW_LEOPARD;
+ case 11: return MACOS_VERSION_LION;
+ case 12: return MACOS_VERSION_MOUNTAIN_LION;
+ case 13: return MACOS_VERSION_MAVERICKS;
+ case 14: return MACOS_VERSION_YOSEMITE;
+ case 15: return MACOS_VERSION_EL_CAPITAN;
+ case 16: return MACOS_VERSION_SIERRA;
+ case 17:
+ // Not a typo, 17.5 Darwin Kernel Version maps to High Sierra 10.13.4.
+ if (minor >= 5)
+ return MACOS_VERSION_HIGH_SIERRA_DOT_RELEASE_4;
+ return MACOS_VERSION_HIGH_SIERRA;
+ case 18: return MACOS_VERSION_MOJAVE;
+ case 19: return MACOS_VERSION_CATALINA;
+ default:
+ if (major < 9) return MACOS_VERSION_UNKNOWN;
+ return MACOS_VERSION_UNKNOWN_NEWER;
}
}
@@ -675,6 +705,16 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
void SignalContext::InitPcSpBp() { GetPcSpBp(context, &pc, &sp, &bp); }
+void InitializePlatformEarly() {
+ // Only use xnu_fast_mmap when on x86_64 and the OS supports it.
+ use_xnu_fast_mmap =
+#if defined(__x86_64__)
+ GetMacosVersion() >= MACOS_VERSION_HIGH_SIERRA_DOT_RELEASE_4;
+#else
+ false;
+#endif
+}
+
#if !SANITIZER_GO
static const char kDyldInsertLibraries[] = "DYLD_INSERT_LIBRARIES";
LowLevelAllocator allocator_for_env;
@@ -872,7 +912,7 @@ char **GetArgv() {
return *_NSGetArgv();
}
-#if defined(__aarch64__) && SANITIZER_IOS && !SANITIZER_IOSSIM
+#if SANITIZER_IOS
// The task_vm_info struct is normally provided by the macOS SDK, but we need
// fields only available in 10.12+. Declare the struct manually to be able to
// build against older SDKs.
@@ -903,33 +943,37 @@ struct __sanitizer_task_vm_info {
#define __SANITIZER_TASK_VM_INFO_COUNT ((mach_msg_type_number_t) \
(sizeof(__sanitizer_task_vm_info) / sizeof(natural_t)))
-uptr GetTaskInfoMaxAddress() {
+static uptr GetTaskInfoMaxAddress() {
__sanitizer_task_vm_info vm_info = {} /* zero initialize */;
mach_msg_type_number_t count = __SANITIZER_TASK_VM_INFO_COUNT;
int err = task_info(mach_task_self(), TASK_VM_INFO, (int *)&vm_info, &count);
- if (err == 0 && vm_info.max_address != 0) {
- return vm_info.max_address - 1;
- } else {
- // xnu cannot provide vm address limit
- return 0x200000000 - 1;
- }
+ return err ? 0 : vm_info.max_address;
}
-#endif
uptr GetMaxUserVirtualAddress() {
-#if SANITIZER_WORDSIZE == 64
-# if defined(__aarch64__) && SANITIZER_IOS && !SANITIZER_IOSSIM
- // Get the maximum VM address
static uptr max_vm = GetTaskInfoMaxAddress();
- CHECK(max_vm);
- return max_vm;
+ if (max_vm != 0)
+ return max_vm - 1;
+
+ // xnu cannot provide vm address limit
+# if SANITIZER_WORDSIZE == 32
+ return 0xffe00000 - 1;
# else
- return (1ULL << 47) - 1; // 0x00007fffffffffffUL;
+ return 0x200000000 - 1;
# endif
-#else // SANITIZER_WORDSIZE == 32
+}
+
+#else // !SANITIZER_IOS
+
+uptr GetMaxUserVirtualAddress() {
+# if SANITIZER_WORDSIZE == 64
+ return (1ULL << 47) - 1; // 0x00007fffffffffffUL;
+# else // SANITIZER_WORDSIZE == 32
+ static_assert(SANITIZER_WORDSIZE == 32, "Wrong wordsize");
return (1ULL << 32) - 1; // 0xffffffff;
-#endif // SANITIZER_WORDSIZE
+# endif
}
+#endif
uptr GetMaxVirtualAddress() {
return GetMaxUserVirtualAddress();
diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.h b/libsanitizer/sanitizer_common/sanitizer_mac.h
index 8e7a4a2..2257883 100644
--- a/libsanitizer/sanitizer_common/sanitizer_mac.h
+++ b/libsanitizer/sanitizer_common/sanitizer_mac.h
@@ -1,7 +1,8 @@
//===-- sanitizer_mac.h -----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -41,7 +42,9 @@ enum MacosVersion {
MACOS_VERSION_EL_CAPITAN,
MACOS_VERSION_SIERRA,
MACOS_VERSION_HIGH_SIERRA,
+ MACOS_VERSION_HIGH_SIERRA_DOT_RELEASE_4,
MACOS_VERSION_MOJAVE,
+ MACOS_VERSION_CATALINA,
MACOS_VERSION_UNKNOWN_NEWER
};
diff --git a/libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cpp
index a0d5c3f..ac7e328 100644
--- a/libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_mac_libcdep.cc ------------------------------------------===//
+//===-- sanitizer_mac_libcdep.cpp -----------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_malloc_mac.inc b/libsanitizer/sanitizer_common/sanitizer_malloc_mac.inc
index 8887f5d..11adbe5 100644
--- a/libsanitizer/sanitizer_common/sanitizer_malloc_mac.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_malloc_mac.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_malloc_mac.inc --------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -28,9 +29,29 @@
// https://github.com/gperftools/gperftools.
namespace __sanitizer {
+
extern malloc_zone_t sanitizer_zone;
+
+struct sanitizer_malloc_introspection_t : public malloc_introspection_t {
+ // IMPORTANT: Do not change the order, alignment, or types of these fields to
+ // maintain binary compatibility. You should only add fields to this struct.
+
+ // Used to track changes to the allocator that will affect
+ // zone enumeration.
+ u64 allocator_enumeration_version;
+ uptr allocator_ptr;
+ uptr allocator_size;
+};
+
+u64 GetMallocZoneAllocatorEnumerationVersion() {
+ // This represents the current allocator ABI version.
+ // This field should be incremented every time the Allocator
+ // ABI changes in a way that breaks allocator enumeration.
+ return 0;
}
+} // namespace __sanitizer
+
INTERCEPTOR(malloc_zone_t *, malloc_create_zone,
vm_size_t start_size, unsigned zone_flags) {
COMMON_MALLOC_ENTER();
@@ -70,6 +91,15 @@ INTERCEPTOR(malloc_zone_t *, malloc_default_zone, void) {
return &sanitizer_zone;
}
+INTERCEPTOR(malloc_zone_t *, malloc_zone_from_ptr, const void *ptr) {
+ COMMON_MALLOC_ENTER();
+ size_t size = sanitizer_zone.size(&sanitizer_zone, ptr);
+ if (size) { // Claimed by sanitizer zone?
+ return &sanitizer_zone;
+ }
+ return REAL(malloc_zone_from_ptr)(ptr);
+}
+
INTERCEPTOR(malloc_zone_t *, malloc_default_purgeable_zone, void) {
// FIXME: ASan should support purgeable allocations.
// https://github.com/google/sanitizers/issues/139
@@ -205,7 +235,7 @@ void __sanitizer_mz_free(malloc_zone_t *zone, void *ptr) {
}
#define GET_ZONE_FOR_PTR(ptr) \
- malloc_zone_t *zone_ptr = malloc_zone_from_ptr(ptr); \
+ malloc_zone_t *zone_ptr = WRAP(malloc_zone_from_ptr)(ptr); \
const char *zone_name = (zone_ptr == 0) ? 0 : zone_ptr->zone_name
extern "C"
@@ -245,6 +275,13 @@ void *__sanitizer_mz_memalign(malloc_zone_t *zone, size_t align, size_t size) {
return p;
}
+// This public API exists purely for testing purposes.
+extern "C"
+SANITIZER_INTERFACE_ATTRIBUTE
+malloc_zone_t* __sanitizer_mz_default_zone() {
+ return &sanitizer_zone;
+}
+
// This function is currently unused, and we build with -Werror.
#if 0
void __sanitizer_mz_free_definite_size(
@@ -254,13 +291,48 @@ void __sanitizer_mz_free_definite_size(
}
#endif
-kern_return_t mi_enumerator(task_t task, void *,
- unsigned type_mask, vm_address_t zone_address,
- memory_reader_t reader,
+#ifndef COMMON_MALLOC_HAS_ZONE_ENUMERATOR
+#error "COMMON_MALLOC_HAS_ZONE_ENUMERATOR must be defined"
+#endif
+static_assert((COMMON_MALLOC_HAS_ZONE_ENUMERATOR) == 0 ||
+ (COMMON_MALLOC_HAS_ZONE_ENUMERATOR) == 1,
+ "COMMON_MALLOC_HAS_ZONE_ENUMERATOR must be 0 or 1");
+
+#if COMMON_MALLOC_HAS_ZONE_ENUMERATOR
+// Forward declare and expect the implementation to provided by
+// includer.
+kern_return_t mi_enumerator(task_t task, void *, unsigned type_mask,
+ vm_address_t zone_address, memory_reader_t reader,
+ vm_range_recorder_t recorder);
+#else
+// Provide stub implementation that fails.
+kern_return_t mi_enumerator(task_t task, void *, unsigned type_mask,
+ vm_address_t zone_address, memory_reader_t reader,
vm_range_recorder_t recorder) {
- // Should enumerate all the pointers we have. Seems like a lot of work.
+ // Not supported.
return KERN_FAILURE;
}
+#endif
+
+#ifndef COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT
+#error "COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT must be defined"
+#endif
+static_assert((COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT) == 0 ||
+ (COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT) == 1,
+ "COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT must be 0 or 1");
+#if COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT
+// Forward declare and expect the implementation to provided by
+// includer.
+void mi_extra_init(
+ sanitizer_malloc_introspection_t *mi);
+#else
+void mi_extra_init(
+ sanitizer_malloc_introspection_t *mi) {
+ // Just zero initialize the fields.
+ mi->allocator_ptr = 0;
+ mi->allocator_size = 0;
+}
+#endif
size_t mi_good_size(malloc_zone_t *zone, size_t size) {
// I think it's always safe to return size, but we maybe could do better.
@@ -300,8 +372,8 @@ boolean_t mi_zone_locked(malloc_zone_t *zone) {
namespace COMMON_MALLOC_NAMESPACE {
-void ReplaceSystemMalloc() {
- static malloc_introspection_t sanitizer_zone_introspection;
+void InitMallocZoneFields() {
+ static sanitizer_malloc_introspection_t sanitizer_zone_introspection;
// Ok to use internal_memset, these places are not performance-critical.
internal_memset(&sanitizer_zone_introspection, 0,
sizeof(sanitizer_zone_introspection));
@@ -316,6 +388,13 @@ void ReplaceSystemMalloc() {
sanitizer_zone_introspection.statistics = &mi_statistics;
sanitizer_zone_introspection.zone_locked = &mi_zone_locked;
+ // Set current allocator enumeration version.
+ sanitizer_zone_introspection.allocator_enumeration_version =
+ GetMallocZoneAllocatorEnumerationVersion();
+
+ // Perform any sanitizer specific initialization.
+ mi_extra_init(&sanitizer_zone_introspection);
+
internal_memset(&sanitizer_zone, 0, sizeof(malloc_zone_t));
// Use version 6 for OSX >= 10.6.
@@ -333,6 +412,10 @@ void ReplaceSystemMalloc() {
sanitizer_zone.free_definite_size = 0;
sanitizer_zone.memalign = &__sanitizer_mz_memalign;
sanitizer_zone.introspect = &sanitizer_zone_introspection;
+}
+
+void ReplaceSystemMalloc() {
+ InitMallocZoneFields();
// Register the zone.
malloc_zone_register(&sanitizer_zone);
diff --git a/libsanitizer/sanitizer_common/sanitizer_mutex.h b/libsanitizer/sanitizer_common/sanitizer_mutex.h
index 2b7f7d2..40a6591 100644
--- a/libsanitizer/sanitizer_common/sanitizer_mutex.h
+++ b/libsanitizer/sanitizer_common/sanitizer_mutex.h
@@ -1,7 +1,8 @@
//===-- sanitizer_mutex.h ---------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_netbsd.cc b/libsanitizer/sanitizer_common/sanitizer_netbsd.cpp
index d0df94d..4e74f6a 100644
--- a/libsanitizer/sanitizer_common/sanitizer_netbsd.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_netbsd.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_netbsd.cc -----------------------------------------------===//
+//===-- sanitizer_netbsd.cpp ----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -167,6 +168,11 @@ uptr internal_filesize(fd_t fd) {
return (uptr)st.st_size;
}
+uptr internal_dup(int oldfd) {
+ DEFINE__REAL(int, dup, int a);
+ return _REAL(dup, oldfd);
+}
+
uptr internal_dup2(int oldfd, int newfd) {
DEFINE__REAL(int, dup2, int a, int b);
return _REAL(dup2, oldfd, newfd);
@@ -200,7 +206,7 @@ void internal__exit(int exitcode) {
unsigned int internal_sleep(unsigned int seconds) {
struct timespec ts;
- ts.tv_sec = 1;
+ ts.tv_sec = seconds;
ts.tv_nsec = 0;
CHECK(&_sys___nanosleep50);
int res = _sys___nanosleep50(&ts, &ts);
@@ -239,10 +245,9 @@ uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
return _REAL(__clock_gettime50, clk_id, tp);
}
-uptr internal_ptrace(int request, int pid, void *addr, void *data) {
- Printf("internal_ptrace not implemented for NetBSD");
- Die();
- return 0;
+uptr internal_ptrace(int request, int pid, void *addr, int data) {
+ DEFINE__REAL(int, ptrace, int a, int b, void *c, int d);
+ return _REAL(ptrace, request, pid, addr, data);
}
uptr internal_waitpid(int pid, int *status, int options) {
@@ -316,11 +321,16 @@ void internal_sigemptyset(__sanitizer_sigset_t *set) {
(void)_REAL(__sigemptyset14, set);
}
-uptr intrnal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
- int *parent_tidptr, void *newtls, int *child_tidptr) {
- Printf("internal_clone not implemented for NetBSD");
- Die();
- return 0;
+void internal_sigdelset(__sanitizer_sigset_t *set, int signo) {
+ DEFINE__REAL(int, __sigdelset14, const void *a, int b);
+ (void)_REAL(__sigdelset14, set, signo);
+}
+
+uptr internal_clone(int (*fn)(void *), void *child_stack, int flags,
+ void *arg) {
+ DEFINE__REAL(int, clone, int (*a)(void *b), void *c, int d, void *e);
+
+ return _REAL(clone, fn, child_stack, flags, arg);
}
} // namespace __sanitizer
diff --git a/libsanitizer/sanitizer_common/sanitizer_openbsd.cc b/libsanitizer/sanitizer_common/sanitizer_openbsd.cpp
index 6ff8b0d..ed2d8ed 100644
--- a/libsanitizer/sanitizer_common/sanitizer_openbsd.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_openbsd.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_openbsd.cc ----------------------------------------------===//
+//===-- sanitizer_openbsd.cpp ---------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -99,6 +100,12 @@ char **GetArgv() {
return argv;
}
+char **GetEnviron() {
+ char **argv, **envp;
+ GetArgsAndEnv(&argv, &envp);
+ return envp;
+}
+
void ReExec() {
UNIMPLEMENTED();
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.cc b/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.cpp
index b989ed0..1ca0375 100644
--- a/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_persistent_allocator.cc -----------------------*- C++ -*-===//
+//===-- sanitizer_persistent_allocator.cpp ----------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.h b/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.h
index 7118503..de4fb6e 100644
--- a/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.h
+++ b/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.h
@@ -1,7 +1,8 @@
//===-- sanitizer_persistent_allocator.h ------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_placement_new.h b/libsanitizer/sanitizer_common/sanitizer_placement_new.h
index 7231e96..1ceb8b9 100644
--- a/libsanitizer/sanitizer_common/sanitizer_placement_new.h
+++ b/libsanitizer/sanitizer_common/sanitizer_placement_new.h
@@ -1,7 +1,8 @@
//===-- sanitizer_placement_new.h -------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform.h b/libsanitizer/sanitizer_common/sanitizer_platform.h
index cc72d52..b45c975 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform.h
@@ -1,7 +1,8 @@
//===-- sanitizer_platform.h ------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -240,7 +241,7 @@
# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 48)
# endif
#elif defined(__sparc__)
-# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 52)
+#define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 52)
#else
# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
#endif
@@ -249,9 +250,9 @@
// The SPARC64 Linux port implements this to split the VMA space into two
// non-contiguous halves with a huge hole in the middle.
#if defined(__sparc__) && SANITIZER_WORDSIZE == 64
-# define SANITIZER_SIGN_EXTENDED_ADDRESSES 1
+#define SANITIZER_SIGN_EXTENDED_ADDRESSES 1
#else
-# define SANITIZER_SIGN_EXTENDED_ADDRESSES 0
+#define SANITIZER_SIGN_EXTENDED_ADDRESSES 0
#endif
// The AArch64 linux port uses the canonical syscall set as mandated by
@@ -284,12 +285,6 @@
# define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 12)
#endif
-// Assume obsolete RPC headers are available by default
-#if !defined(HAVE_RPC_XDR_H) && !defined(HAVE_TIRPC_RPC_XDR_H)
-# define HAVE_RPC_XDR_H (SANITIZER_LINUX && !SANITIZER_ANDROID)
-# define HAVE_TIRPC_RPC_XDR_H 0
-#endif
-
/// \macro MSC_PREREQ
/// \brief Is the compiler MSVC of at least the specified version?
/// The common \param version values to check for are:
@@ -351,4 +346,13 @@
#define SANITIZER_SYMBOLIZER_MARKUP 0
#endif
+// Enable ability to support sanitizer initialization that is
+// compatible with the sanitizer library being loaded via
+// `dlopen()`.
+#if SANITIZER_MAC
+#define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 1
+#else
+#define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 0
+#endif
+
#endif // SANITIZER_PLATFORM_H
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
index d6fc2b9..e7becbb 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h
@@ -1,7 +1,8 @@
//===-- sanitizer_platform_interceptors.h -----------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -31,8 +32,9 @@
#endif
#if SI_POSIX
+# include "sanitizer_platform_limits_freebsd.h"
# include "sanitizer_platform_limits_netbsd.h"
-#include "sanitizer_platform_limits_openbsd.h"
+# include "sanitizer_platform_limits_openbsd.h"
# include "sanitizer_platform_limits_posix.h"
# include "sanitizer_platform_limits_solaris.h"
#endif
@@ -140,6 +142,9 @@
#define SANITIZER_INTERCEPT_MEMMOVE 1
#define SANITIZER_INTERCEPT_MEMCPY 1
#define SANITIZER_INTERCEPT_MEMCMP SI_NOT_FUCHSIA
+#define SANITIZER_INTERCEPT_BCMP \
+ SANITIZER_INTERCEPT_MEMCMP && \
+ ((SI_POSIX && _GNU_SOURCE) || SI_NETBSD || SI_OPENBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT_STRNDUP SI_POSIX
#define SANITIZER_INTERCEPT___STRNDUP SI_LINUX_NOT_FREEBSD
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
@@ -205,9 +210,13 @@
#define SANITIZER_INTERCEPT_GETPWENT \
(SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
SI_SOLARIS)
+#define SANITIZER_INTERCEPT_FGETGRENT_R \
+ (SI_FREEBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_FGETPWENT SI_LINUX_NOT_ANDROID || SI_SOLARIS
#define SANITIZER_INTERCEPT_GETPWENT_R \
(SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+#define SANITIZER_INTERCEPT_FGETPWENT_R \
+ (SI_FREEBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_SETPWENT \
(SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_CLOCK_GETTIME \
@@ -274,6 +283,9 @@
#define SANITIZER_INTERCEPT_WCRTOMB \
(SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
SI_SOLARIS)
+#define SANITIZER_INTERCEPT_WCTOMB \
+ (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \
+ SI_SOLARIS)
#define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID || SI_SOLARIS
#define SANITIZER_INTERCEPT_REALPATH SI_POSIX
#define SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME \
@@ -302,6 +314,7 @@
(SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_SIGPENDING SI_POSIX
#define SANITIZER_INTERCEPT_SIGPROCMASK SI_POSIX
+#define SANITIZER_INTERCEPT_PTHREAD_SIGMASK SI_POSIX
#define SANITIZER_INTERCEPT_BACKTRACE \
(SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_GETMNTENT SI_LINUX
@@ -350,11 +363,14 @@
#define SANITIZER_INTERCEPT_THR_EXIT SI_FREEBSD
#define SANITIZER_INTERCEPT_TMPNAM SI_POSIX
#define SANITIZER_INTERCEPT_TMPNAM_R SI_LINUX_NOT_ANDROID || SI_SOLARIS
+#define SANITIZER_INTERCEPT_TTYNAME SI_POSIX
#define SANITIZER_INTERCEPT_TTYNAME_R SI_POSIX
#define SANITIZER_INTERCEPT_TEMPNAM SI_POSIX
#define SANITIZER_INTERCEPT_SINCOS SI_LINUX || SI_SOLARIS
#define SANITIZER_INTERCEPT_REMQUO SI_POSIX
+#define SANITIZER_INTERCEPT_REMQUOL (SI_POSIX && !SI_NETBSD)
#define SANITIZER_INTERCEPT_LGAMMA SI_POSIX
+#define SANITIZER_INTERCEPT_LGAMMAL (SI_POSIX && !SI_NETBSD)
#define SANITIZER_INTERCEPT_LGAMMA_R (SI_FREEBSD || SI_LINUX || SI_SOLARIS)
#define SANITIZER_INTERCEPT_LGAMMAL_R SI_LINUX_NOT_ANDROID || SI_SOLARIS
#define SANITIZER_INTERCEPT_DRAND48_R SI_LINUX_NOT_ANDROID
@@ -378,7 +394,7 @@
#define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP \
(SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP \
- (SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_TLS_GET_ADDR \
(SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
@@ -398,7 +414,8 @@
#else
#define SANITIZER_INTERCEPT_AEABI_MEM 0
#endif
-#define SANITIZER_INTERCEPT___BZERO SI_MAC
+#define SANITIZER_INTERCEPT___BZERO SI_MAC || SI_LINUX_NOT_ANDROID
+#define SANITIZER_INTERCEPT_BZERO SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_FTIME \
(!SI_FREEBSD && !SI_NETBSD && !SI_OPENBSD && SI_POSIX)
#define SANITIZER_INTERCEPT_XDR SI_LINUX_NOT_ANDROID || SI_SOLARIS
@@ -470,10 +487,12 @@
#define SANITIZER_INTERCEPT_CFREE \
(!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA && \
SI_NOT_RTEMS)
+#define SANITIZER_INTERCEPT_REALLOCARRAY SI_POSIX
#define SANITIZER_INTERCEPT_ALIGNED_ALLOC (!SI_MAC && SI_NOT_RTEMS)
#define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC && !SI_OPENBSD)
#define SANITIZER_INTERCEPT_MCHECK_MPROBE SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_WCSCAT SI_POSIX
+#define SANITIZER_INTERCEPT_WCSDUP SI_POSIX
#define SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION (!SI_WINDOWS && SI_NOT_FUCHSIA)
#define SANITIZER_INTERCEPT_BSD_SIGNAL SI_ANDROID
@@ -508,5 +527,45 @@
#define SANITIZER_INTERCEPT_TTYENT SI_NETBSD
#define SANITIZER_INTERCEPT_PROTOENT SI_NETBSD
#define SANITIZER_INTERCEPT_NETENT SI_NETBSD
+#define SANITIZER_INTERCEPT_SETVBUF (SI_NETBSD || SI_FREEBSD || \
+ SI_LINUX || SI_MAC)
+#define SANITIZER_INTERCEPT_GETMNTINFO (SI_NETBSD || SI_FREEBSD || SI_MAC)
+#define SANITIZER_INTERCEPT_MI_VECTOR_HASH SI_NETBSD
+#define SANITIZER_INTERCEPT_GETVFSSTAT SI_NETBSD
+#define SANITIZER_INTERCEPT_REGEX (SI_NETBSD || SI_FREEBSD || SI_LINUX)
+#define SANITIZER_INTERCEPT_REGEXSUB SI_NETBSD
+#define SANITIZER_INTERCEPT_FTS (SI_NETBSD || SI_FREEBSD)
+#define SANITIZER_INTERCEPT_SYSCTL (SI_NETBSD || SI_FREEBSD || SI_MAC)
+#define SANITIZER_INTERCEPT_ASYSCTL SI_NETBSD
+#define SANITIZER_INTERCEPT_SYSCTLGETMIBINFO SI_NETBSD
+#define SANITIZER_INTERCEPT_NL_LANGINFO (SI_NETBSD || SI_FREEBSD || SI_MAC)
+#define SANITIZER_INTERCEPT_MODCTL SI_NETBSD
+#define SANITIZER_INTERCEPT_CAPSICUM SI_FREEBSD
+#define SANITIZER_INTERCEPT_STRTONUM (SI_NETBSD || SI_FREEBSD)
+#define SANITIZER_INTERCEPT_FPARSELN SI_NETBSD
+#define SANITIZER_INTERCEPT_STATVFS1 SI_NETBSD
+#define SANITIZER_INTERCEPT_STRTOI SI_NETBSD
+#define SANITIZER_INTERCEPT_CAPSICUM SI_FREEBSD
+#define SANITIZER_INTERCEPT_SHA1 SI_NETBSD
+#define SANITIZER_INTERCEPT_MD4 SI_NETBSD
+#define SANITIZER_INTERCEPT_RMD160 SI_NETBSD
+#define SANITIZER_INTERCEPT_MD5 SI_NETBSD
+#define SANITIZER_INTERCEPT_FSEEK (SI_NETBSD || SI_FREEBSD)
+#define SANITIZER_INTERCEPT_MD2 SI_NETBSD
+#define SANITIZER_INTERCEPT_SHA2 SI_NETBSD
+#define SANITIZER_INTERCEPT_CDB SI_NETBSD
+#define SANITIZER_INTERCEPT_VIS (SI_NETBSD || SI_FREEBSD)
+#define SANITIZER_INTERCEPT_POPEN SI_POSIX
+#define SANITIZER_INTERCEPT_POPENVE SI_NETBSD
+#define SANITIZER_INTERCEPT_PCLOSE SI_POSIX
+#define SANITIZER_INTERCEPT_FUNOPEN (SI_NETBSD || SI_FREEBSD)
+#define SANITIZER_INTERCEPT_FUNOPEN2 SI_NETBSD
+#define SANITIZER_INTERCEPT_GETFSENT (SI_FREEBSD || SI_NETBSD || SI_MAC)
+#define SANITIZER_INTERCEPT_ARC4RANDOM (SI_FREEBSD || SI_NETBSD)
+#define SANITIZER_INTERCEPT_FDEVNAME SI_FREEBSD
+#define SANITIZER_INTERCEPT_GETUSERSHELL (SI_POSIX && !SI_ANDROID)
+#define SANITIZER_INTERCEPT_SL_INIT (SI_FREEBSD || SI_NETBSD)
+
+#define SANITIZER_INTERCEPT_GETRANDOM SI_LINUX
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.cpp
new file mode 100644
index 0000000..2d1bb1a
--- /dev/null
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.cpp
@@ -0,0 +1,525 @@
+//===-- sanitizer_platform_limits_freebsd.cpp -----------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of Sanitizer common code.
+//
+// Sizes and layouts of platform-specific FreeBSD data structures.
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_platform.h"
+
+#if SANITIZER_FREEBSD
+
+#include <arpa/inet.h>
+#include <dirent.h>
+#include <fts.h>
+#include <fstab.h>
+#include <grp.h>
+#include <limits.h>
+#include <net/if.h>
+#include <netdb.h>
+#include <poll.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <regex.h>
+#include <signal.h>
+#include <stddef.h>
+#include <sys/mman.h>
+#include <sys/capsicum.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/times.h>
+#include <sys/types.h>
+#include <sys/utsname.h>
+#include <termios.h>
+#include <time.h>
+
+#include <net/route.h>
+#include <sys/mount.h>
+#include <sys/sockio.h>
+#include <sys/socket.h>
+#include <sys/filio.h>
+#include <sys/signal.h>
+#include <sys/timespec.h>
+#include <sys/timeb.h>
+#include <sys/mqueue.h>
+#include <sys/msg.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <sys/statvfs.h>
+#include <sys/soundcard.h>
+#include <sys/mtio.h>
+#include <sys/consio.h>
+#include <sys/kbio.h>
+#include <sys/link_elf.h>
+#include <netinet/ip_mroute.h>
+#include <netinet/in.h>
+#include <net/ethernet.h>
+#include <net/ppp_defs.h>
+#include <glob.h>
+#include <stdio.h>
+#include <stringlist.h>
+#include <term.h>
+#include <utmpx.h>
+#include <wchar.h>
+#include <vis.h>
+
+#define _KERNEL // to declare 'shminfo' structure
+# include <sys/shm.h>
+#undef _KERNEL
+
+#undef INLINE // to avoid clashes with sanitizers' definitions
+
+#undef IOC_DIRMASK
+
+# include <utime.h>
+# include <sys/ptrace.h>
+# include <semaphore.h>
+
+#include <ifaddrs.h>
+#include <sys/ucontext.h>
+#include <wordexp.h>
+
+// Include these after system headers to avoid name clashes and ambiguities.
+#include "sanitizer_internal_defs.h"
+#include "sanitizer_platform_limits_freebsd.h"
+
+namespace __sanitizer {
+ unsigned struct_cap_rights_sz = sizeof(cap_rights_t);
+ unsigned struct_utsname_sz = sizeof(struct utsname);
+ unsigned struct_stat_sz = sizeof(struct stat);
+ unsigned struct_rusage_sz = sizeof(struct rusage);
+ unsigned struct_tm_sz = sizeof(struct tm);
+ unsigned struct_passwd_sz = sizeof(struct passwd);
+ unsigned struct_group_sz = sizeof(struct group);
+ unsigned siginfo_t_sz = sizeof(siginfo_t);
+ unsigned struct_sigaction_sz = sizeof(struct sigaction);
+ unsigned struct_itimerval_sz = sizeof(struct itimerval);
+ unsigned pthread_t_sz = sizeof(pthread_t);
+ unsigned pthread_mutex_t_sz = sizeof(pthread_mutex_t);
+ unsigned pthread_cond_t_sz = sizeof(pthread_cond_t);
+ unsigned pid_t_sz = sizeof(pid_t);
+ unsigned timeval_sz = sizeof(timeval);
+ unsigned uid_t_sz = sizeof(uid_t);
+ unsigned gid_t_sz = sizeof(gid_t);
+ unsigned fpos_t_sz = sizeof(fpos_t);
+ unsigned mbstate_t_sz = sizeof(mbstate_t);
+ unsigned sigset_t_sz = sizeof(sigset_t);
+ unsigned struct_timezone_sz = sizeof(struct timezone);
+ unsigned struct_tms_sz = sizeof(struct tms);
+ unsigned struct_sigevent_sz = sizeof(struct sigevent);
+ unsigned struct_sched_param_sz = sizeof(struct sched_param);
+ unsigned struct_statfs_sz = sizeof(struct statfs);
+ unsigned struct_sockaddr_sz = sizeof(struct sockaddr);
+ unsigned ucontext_t_sz = sizeof(ucontext_t);
+ unsigned struct_rlimit_sz = sizeof(struct rlimit);
+ unsigned struct_timespec_sz = sizeof(struct timespec);
+ unsigned struct_utimbuf_sz = sizeof(struct utimbuf);
+ unsigned struct_itimerspec_sz = sizeof(struct itimerspec);
+ unsigned struct_timeb_sz = sizeof(struct timeb);
+ unsigned struct_msqid_ds_sz = sizeof(struct msqid_ds);
+ unsigned struct_mq_attr_sz = sizeof(struct mq_attr);
+ unsigned struct_statvfs_sz = sizeof(struct statvfs);
+ unsigned struct_shminfo_sz = sizeof(struct shminfo);
+ unsigned struct_shm_info_sz = sizeof(struct shm_info);
+ unsigned struct_regmatch_sz = sizeof(regmatch_t);
+ unsigned struct_regex_sz = sizeof(regex_t);
+ unsigned struct_fstab_sz = sizeof(struct fstab);
+ unsigned struct_FTS_sz = sizeof(FTS);
+ unsigned struct_FTSENT_sz = sizeof(FTSENT);
+ unsigned struct_StringList_sz = sizeof(StringList);
+
+ const uptr sig_ign = (uptr)SIG_IGN;
+ const uptr sig_dfl = (uptr)SIG_DFL;
+ const uptr sig_err = (uptr)SIG_ERR;
+ const uptr sa_siginfo = (uptr)SA_SIGINFO;
+
+ int shmctl_ipc_stat = (int)IPC_STAT;
+ int shmctl_ipc_info = (int)IPC_INFO;
+ int shmctl_shm_info = (int)SHM_INFO;
+ int shmctl_shm_stat = (int)SHM_STAT;
+ unsigned struct_utmpx_sz = sizeof(struct utmpx);
+
+ int map_fixed = MAP_FIXED;
+
+ int af_inet = (int)AF_INET;
+ int af_inet6 = (int)AF_INET6;
+
+ uptr __sanitizer_in_addr_sz(int af) {
+ if (af == AF_INET)
+ return sizeof(struct in_addr);
+ else if (af == AF_INET6)
+ return sizeof(struct in6_addr);
+ else
+ return 0;
+ }
+
+ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
+ int glob_nomatch = GLOB_NOMATCH;
+ int glob_altdirfunc = GLOB_ALTDIRFUNC;
+
+ unsigned path_max = PATH_MAX;
+
+ // ioctl arguments
+ unsigned struct_ifreq_sz = sizeof(struct ifreq);
+ unsigned struct_termios_sz = sizeof(struct termios);
+ unsigned struct_winsize_sz = sizeof(struct winsize);
+#if SOUND_VERSION >= 0x040000
+ unsigned struct_copr_buffer_sz = 0;
+ unsigned struct_copr_debug_buf_sz = 0;
+ unsigned struct_copr_msg_sz = 0;
+#else
+ unsigned struct_copr_buffer_sz = sizeof(struct copr_buffer);
+ unsigned struct_copr_debug_buf_sz = sizeof(struct copr_debug_buf);
+ unsigned struct_copr_msg_sz = sizeof(struct copr_msg);
+#endif
+ unsigned struct_midi_info_sz = sizeof(struct midi_info);
+ unsigned struct_mtget_sz = sizeof(struct mtget);
+ unsigned struct_mtop_sz = sizeof(struct mtop);
+ unsigned struct_sbi_instrument_sz = sizeof(struct sbi_instrument);
+ unsigned struct_seq_event_rec_sz = sizeof(struct seq_event_rec);
+ unsigned struct_synth_info_sz = sizeof(struct synth_info);
+ unsigned struct_audio_buf_info_sz = sizeof(struct audio_buf_info);
+ unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats);
+ unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req);
+ unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req);
+ const unsigned long __sanitizer_bufsiz = BUFSIZ;
+
+ const unsigned IOCTL_NOT_PRESENT = 0;
+
+ unsigned IOCTL_FIOASYNC = FIOASYNC;
+ unsigned IOCTL_FIOCLEX = FIOCLEX;
+ unsigned IOCTL_FIOGETOWN = FIOGETOWN;
+ unsigned IOCTL_FIONBIO = FIONBIO;
+ unsigned IOCTL_FIONCLEX = FIONCLEX;
+ unsigned IOCTL_FIOSETOWN = FIOSETOWN;
+ unsigned IOCTL_SIOCADDMULTI = SIOCADDMULTI;
+ unsigned IOCTL_SIOCATMARK = SIOCATMARK;
+ unsigned IOCTL_SIOCDELMULTI = SIOCDELMULTI;
+ unsigned IOCTL_SIOCGIFADDR = SIOCGIFADDR;
+ unsigned IOCTL_SIOCGIFBRDADDR = SIOCGIFBRDADDR;
+ unsigned IOCTL_SIOCGIFCONF = SIOCGIFCONF;
+ unsigned IOCTL_SIOCGIFDSTADDR = SIOCGIFDSTADDR;
+ unsigned IOCTL_SIOCGIFFLAGS = SIOCGIFFLAGS;
+ unsigned IOCTL_SIOCGIFMETRIC = SIOCGIFMETRIC;
+ unsigned IOCTL_SIOCGIFMTU = SIOCGIFMTU;
+ unsigned IOCTL_SIOCGIFNETMASK = SIOCGIFNETMASK;
+ unsigned IOCTL_SIOCGPGRP = SIOCGPGRP;
+ unsigned IOCTL_SIOCSIFADDR = SIOCSIFADDR;
+ unsigned IOCTL_SIOCSIFBRDADDR = SIOCSIFBRDADDR;
+ unsigned IOCTL_SIOCSIFDSTADDR = SIOCSIFDSTADDR;
+ unsigned IOCTL_SIOCSIFFLAGS = SIOCSIFFLAGS;
+ unsigned IOCTL_SIOCSIFMETRIC = SIOCSIFMETRIC;
+ unsigned IOCTL_SIOCSIFMTU = SIOCSIFMTU;
+ unsigned IOCTL_SIOCSIFNETMASK = SIOCSIFNETMASK;
+ unsigned IOCTL_SIOCSPGRP = SIOCSPGRP;
+ unsigned IOCTL_TIOCCONS = TIOCCONS;
+ unsigned IOCTL_TIOCEXCL = TIOCEXCL;
+ unsigned IOCTL_TIOCGETD = TIOCGETD;
+ unsigned IOCTL_TIOCGPGRP = TIOCGPGRP;
+ unsigned IOCTL_TIOCGWINSZ = TIOCGWINSZ;
+ unsigned IOCTL_TIOCMBIC = TIOCMBIC;
+ unsigned IOCTL_TIOCMBIS = TIOCMBIS;
+ unsigned IOCTL_TIOCMGET = TIOCMGET;
+ unsigned IOCTL_TIOCMSET = TIOCMSET;
+ unsigned IOCTL_TIOCNOTTY = TIOCNOTTY;
+ unsigned IOCTL_TIOCNXCL = TIOCNXCL;
+ unsigned IOCTL_TIOCOUTQ = TIOCOUTQ;
+ unsigned IOCTL_TIOCPKT = TIOCPKT;
+ unsigned IOCTL_TIOCSCTTY = TIOCSCTTY;
+ unsigned IOCTL_TIOCSETD = TIOCSETD;
+ unsigned IOCTL_TIOCSPGRP = TIOCSPGRP;
+ unsigned IOCTL_TIOCSTI = TIOCSTI;
+ unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ;
+ unsigned IOCTL_SIOCGETSGCNT = SIOCGETSGCNT;
+ unsigned IOCTL_SIOCGETVIFCNT = SIOCGETVIFCNT;
+ unsigned IOCTL_MTIOCGET = MTIOCGET;
+ unsigned IOCTL_MTIOCTOP = MTIOCTOP;
+ unsigned IOCTL_SNDCTL_DSP_GETBLKSIZE = SNDCTL_DSP_GETBLKSIZE;
+ unsigned IOCTL_SNDCTL_DSP_GETFMTS = SNDCTL_DSP_GETFMTS;
+ unsigned IOCTL_SNDCTL_DSP_NONBLOCK = SNDCTL_DSP_NONBLOCK;
+ unsigned IOCTL_SNDCTL_DSP_POST = SNDCTL_DSP_POST;
+ unsigned IOCTL_SNDCTL_DSP_RESET = SNDCTL_DSP_RESET;
+ unsigned IOCTL_SNDCTL_DSP_SETFMT = SNDCTL_DSP_SETFMT;
+ unsigned IOCTL_SNDCTL_DSP_SETFRAGMENT = SNDCTL_DSP_SETFRAGMENT;
+ unsigned IOCTL_SNDCTL_DSP_SPEED = SNDCTL_DSP_SPEED;
+ unsigned IOCTL_SNDCTL_DSP_STEREO = SNDCTL_DSP_STEREO;
+ unsigned IOCTL_SNDCTL_DSP_SUBDIVIDE = SNDCTL_DSP_SUBDIVIDE;
+ unsigned IOCTL_SNDCTL_DSP_SYNC = SNDCTL_DSP_SYNC;
+ unsigned IOCTL_SNDCTL_FM_4OP_ENABLE = SNDCTL_FM_4OP_ENABLE;
+ unsigned IOCTL_SNDCTL_FM_LOAD_INSTR = SNDCTL_FM_LOAD_INSTR;
+ unsigned IOCTL_SNDCTL_MIDI_INFO = SNDCTL_MIDI_INFO;
+ unsigned IOCTL_SNDCTL_MIDI_PRETIME = SNDCTL_MIDI_PRETIME;
+ unsigned IOCTL_SNDCTL_SEQ_CTRLRATE = SNDCTL_SEQ_CTRLRATE;
+ unsigned IOCTL_SNDCTL_SEQ_GETINCOUNT = SNDCTL_SEQ_GETINCOUNT;
+ unsigned IOCTL_SNDCTL_SEQ_GETOUTCOUNT = SNDCTL_SEQ_GETOUTCOUNT;
+ unsigned IOCTL_SNDCTL_SEQ_NRMIDIS = SNDCTL_SEQ_NRMIDIS;
+ unsigned IOCTL_SNDCTL_SEQ_NRSYNTHS = SNDCTL_SEQ_NRSYNTHS;
+ unsigned IOCTL_SNDCTL_SEQ_OUTOFBAND = SNDCTL_SEQ_OUTOFBAND;
+ unsigned IOCTL_SNDCTL_SEQ_PANIC = SNDCTL_SEQ_PANIC;
+ unsigned IOCTL_SNDCTL_SEQ_PERCMODE = SNDCTL_SEQ_PERCMODE;
+ unsigned IOCTL_SNDCTL_SEQ_RESET = SNDCTL_SEQ_RESET;
+ unsigned IOCTL_SNDCTL_SEQ_RESETSAMPLES = SNDCTL_SEQ_RESETSAMPLES;
+ unsigned IOCTL_SNDCTL_SEQ_SYNC = SNDCTL_SEQ_SYNC;
+ unsigned IOCTL_SNDCTL_SEQ_TESTMIDI = SNDCTL_SEQ_TESTMIDI;
+ unsigned IOCTL_SNDCTL_SEQ_THRESHOLD = SNDCTL_SEQ_THRESHOLD;
+ unsigned IOCTL_SNDCTL_SYNTH_INFO = SNDCTL_SYNTH_INFO;
+ unsigned IOCTL_SNDCTL_SYNTH_MEMAVL = SNDCTL_SYNTH_MEMAVL;
+ unsigned IOCTL_SNDCTL_TMR_CONTINUE = SNDCTL_TMR_CONTINUE;
+ unsigned IOCTL_SNDCTL_TMR_METRONOME = SNDCTL_TMR_METRONOME;
+ unsigned IOCTL_SNDCTL_TMR_SELECT = SNDCTL_TMR_SELECT;
+ unsigned IOCTL_SNDCTL_TMR_SOURCE = SNDCTL_TMR_SOURCE;
+ unsigned IOCTL_SNDCTL_TMR_START = SNDCTL_TMR_START;
+ unsigned IOCTL_SNDCTL_TMR_STOP = SNDCTL_TMR_STOP;
+ unsigned IOCTL_SNDCTL_TMR_TEMPO = SNDCTL_TMR_TEMPO;
+ unsigned IOCTL_SNDCTL_TMR_TIMEBASE = SNDCTL_TMR_TIMEBASE;
+ unsigned IOCTL_SOUND_MIXER_READ_ALTPCM = SOUND_MIXER_READ_ALTPCM;
+ unsigned IOCTL_SOUND_MIXER_READ_BASS = SOUND_MIXER_READ_BASS;
+ unsigned IOCTL_SOUND_MIXER_READ_CAPS = SOUND_MIXER_READ_CAPS;
+ unsigned IOCTL_SOUND_MIXER_READ_CD = SOUND_MIXER_READ_CD;
+ unsigned IOCTL_SOUND_MIXER_READ_DEVMASK = SOUND_MIXER_READ_DEVMASK;
+ unsigned IOCTL_SOUND_MIXER_READ_ENHANCE = SOUND_MIXER_READ_ENHANCE;
+ unsigned IOCTL_SOUND_MIXER_READ_IGAIN = SOUND_MIXER_READ_IGAIN;
+ unsigned IOCTL_SOUND_MIXER_READ_IMIX = SOUND_MIXER_READ_IMIX;
+ unsigned IOCTL_SOUND_MIXER_READ_LINE = SOUND_MIXER_READ_LINE;
+ unsigned IOCTL_SOUND_MIXER_READ_LINE1 = SOUND_MIXER_READ_LINE1;
+ unsigned IOCTL_SOUND_MIXER_READ_LINE2 = SOUND_MIXER_READ_LINE2;
+ unsigned IOCTL_SOUND_MIXER_READ_LINE3 = SOUND_MIXER_READ_LINE3;
+ unsigned IOCTL_SOUND_MIXER_READ_LOUD = SOUND_MIXER_READ_LOUD;
+ unsigned IOCTL_SOUND_MIXER_READ_MIC = SOUND_MIXER_READ_MIC;
+ unsigned IOCTL_SOUND_MIXER_READ_MUTE = SOUND_MIXER_READ_MUTE;
+ unsigned IOCTL_SOUND_MIXER_READ_OGAIN = SOUND_MIXER_READ_OGAIN;
+ unsigned IOCTL_SOUND_MIXER_READ_PCM = SOUND_MIXER_READ_PCM;
+ unsigned IOCTL_SOUND_MIXER_READ_RECLEV = SOUND_MIXER_READ_RECLEV;
+ unsigned IOCTL_SOUND_MIXER_READ_RECMASK = SOUND_MIXER_READ_RECMASK;
+ unsigned IOCTL_SOUND_MIXER_READ_RECSRC = SOUND_MIXER_READ_RECSRC;
+ unsigned IOCTL_SOUND_MIXER_READ_SPEAKER = SOUND_MIXER_READ_SPEAKER;
+ unsigned IOCTL_SOUND_MIXER_READ_STEREODEVS = SOUND_MIXER_READ_STEREODEVS;
+ unsigned IOCTL_SOUND_MIXER_READ_SYNTH = SOUND_MIXER_READ_SYNTH;
+ unsigned IOCTL_SOUND_MIXER_READ_TREBLE = SOUND_MIXER_READ_TREBLE;
+ unsigned IOCTL_SOUND_MIXER_READ_VOLUME = SOUND_MIXER_READ_VOLUME;
+ unsigned IOCTL_SOUND_MIXER_WRITE_ALTPCM = SOUND_MIXER_WRITE_ALTPCM;
+ unsigned IOCTL_SOUND_MIXER_WRITE_BASS = SOUND_MIXER_WRITE_BASS;
+ unsigned IOCTL_SOUND_MIXER_WRITE_CD = SOUND_MIXER_WRITE_CD;
+ unsigned IOCTL_SOUND_MIXER_WRITE_ENHANCE = SOUND_MIXER_WRITE_ENHANCE;
+ unsigned IOCTL_SOUND_MIXER_WRITE_IGAIN = SOUND_MIXER_WRITE_IGAIN;
+ unsigned IOCTL_SOUND_MIXER_WRITE_IMIX = SOUND_MIXER_WRITE_IMIX;
+ unsigned IOCTL_SOUND_MIXER_WRITE_LINE = SOUND_MIXER_WRITE_LINE;
+ unsigned IOCTL_SOUND_MIXER_WRITE_LINE1 = SOUND_MIXER_WRITE_LINE1;
+ unsigned IOCTL_SOUND_MIXER_WRITE_LINE2 = SOUND_MIXER_WRITE_LINE2;
+ unsigned IOCTL_SOUND_MIXER_WRITE_LINE3 = SOUND_MIXER_WRITE_LINE3;
+ unsigned IOCTL_SOUND_MIXER_WRITE_LOUD = SOUND_MIXER_WRITE_LOUD;
+ unsigned IOCTL_SOUND_MIXER_WRITE_MIC = SOUND_MIXER_WRITE_MIC;
+ unsigned IOCTL_SOUND_MIXER_WRITE_MUTE = SOUND_MIXER_WRITE_MUTE;
+ unsigned IOCTL_SOUND_MIXER_WRITE_OGAIN = SOUND_MIXER_WRITE_OGAIN;
+ unsigned IOCTL_SOUND_MIXER_WRITE_PCM = SOUND_MIXER_WRITE_PCM;
+ unsigned IOCTL_SOUND_MIXER_WRITE_RECLEV = SOUND_MIXER_WRITE_RECLEV;
+ unsigned IOCTL_SOUND_MIXER_WRITE_RECSRC = SOUND_MIXER_WRITE_RECSRC;
+ unsigned IOCTL_SOUND_MIXER_WRITE_SPEAKER = SOUND_MIXER_WRITE_SPEAKER;
+ unsigned IOCTL_SOUND_MIXER_WRITE_SYNTH = SOUND_MIXER_WRITE_SYNTH;
+ unsigned IOCTL_SOUND_MIXER_WRITE_TREBLE = SOUND_MIXER_WRITE_TREBLE;
+ unsigned IOCTL_SOUND_MIXER_WRITE_VOLUME = SOUND_MIXER_WRITE_VOLUME;
+ unsigned IOCTL_VT_ACTIVATE = VT_ACTIVATE;
+ unsigned IOCTL_VT_GETMODE = VT_GETMODE;
+ unsigned IOCTL_VT_OPENQRY = VT_OPENQRY;
+ unsigned IOCTL_VT_RELDISP = VT_RELDISP;
+ unsigned IOCTL_VT_SETMODE = VT_SETMODE;
+ unsigned IOCTL_VT_WAITACTIVE = VT_WAITACTIVE;
+ unsigned IOCTL_GIO_SCRNMAP = GIO_SCRNMAP;
+ unsigned IOCTL_KDDISABIO = KDDISABIO;
+ unsigned IOCTL_KDENABIO = KDENABIO;
+ unsigned IOCTL_KDGETLED = KDGETLED;
+ unsigned IOCTL_KDGETMODE = KDGETMODE;
+ unsigned IOCTL_KDGKBMODE = KDGKBMODE;
+ unsigned IOCTL_KDGKBTYPE = KDGKBTYPE;
+ unsigned IOCTL_KDMKTONE = KDMKTONE;
+ unsigned IOCTL_KDSETLED = KDSETLED;
+ unsigned IOCTL_KDSETMODE = KDSETMODE;
+ unsigned IOCTL_KDSKBMODE = KDSKBMODE;
+ unsigned IOCTL_KIOCSOUND = KIOCSOUND;
+ unsigned IOCTL_PIO_SCRNMAP = PIO_SCRNMAP;
+ unsigned IOCTL_SNDCTL_DSP_GETISPACE = SNDCTL_DSP_GETISPACE;
+
+ const int si_SEGV_MAPERR = SEGV_MAPERR;
+ const int si_SEGV_ACCERR = SEGV_ACCERR;
+ const int unvis_valid = UNVIS_VALID;
+ const int unvis_validpush = UNVIS_VALIDPUSH;
+} // namespace __sanitizer
+
+using namespace __sanitizer;
+
+COMPILER_CHECK(sizeof(__sanitizer_pthread_attr_t) >= sizeof(pthread_attr_t));
+
+COMPILER_CHECK(sizeof(socklen_t) == sizeof(unsigned));
+CHECK_TYPE_SIZE(pthread_key_t);
+
+// There are more undocumented fields in dl_phdr_info that we are not interested
+// in.
+COMPILER_CHECK(sizeof(__sanitizer_dl_phdr_info) <= sizeof(dl_phdr_info));
+CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_addr);
+CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_name);
+CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phdr);
+CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phnum);
+
+CHECK_TYPE_SIZE(glob_t);
+CHECK_SIZE_AND_OFFSET(glob_t, gl_pathc);
+CHECK_SIZE_AND_OFFSET(glob_t, gl_pathv);
+CHECK_SIZE_AND_OFFSET(glob_t, gl_offs);
+CHECK_SIZE_AND_OFFSET(glob_t, gl_flags);
+CHECK_SIZE_AND_OFFSET(glob_t, gl_closedir);
+CHECK_SIZE_AND_OFFSET(glob_t, gl_readdir);
+CHECK_SIZE_AND_OFFSET(glob_t, gl_opendir);
+CHECK_SIZE_AND_OFFSET(glob_t, gl_lstat);
+CHECK_SIZE_AND_OFFSET(glob_t, gl_stat);
+
+CHECK_TYPE_SIZE(addrinfo);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_flags);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_family);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_socktype);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_protocol);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_protocol);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_addrlen);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_canonname);
+CHECK_SIZE_AND_OFFSET(addrinfo, ai_addr);
+
+CHECK_TYPE_SIZE(hostent);
+CHECK_SIZE_AND_OFFSET(hostent, h_name);
+CHECK_SIZE_AND_OFFSET(hostent, h_aliases);
+CHECK_SIZE_AND_OFFSET(hostent, h_addrtype);
+CHECK_SIZE_AND_OFFSET(hostent, h_length);
+CHECK_SIZE_AND_OFFSET(hostent, h_addr_list);
+
+CHECK_TYPE_SIZE(iovec);
+CHECK_SIZE_AND_OFFSET(iovec, iov_base);
+CHECK_SIZE_AND_OFFSET(iovec, iov_len);
+
+CHECK_TYPE_SIZE(msghdr);
+CHECK_SIZE_AND_OFFSET(msghdr, msg_name);
+CHECK_SIZE_AND_OFFSET(msghdr, msg_namelen);
+CHECK_SIZE_AND_OFFSET(msghdr, msg_iov);
+CHECK_SIZE_AND_OFFSET(msghdr, msg_iovlen);
+CHECK_SIZE_AND_OFFSET(msghdr, msg_control);
+CHECK_SIZE_AND_OFFSET(msghdr, msg_controllen);
+CHECK_SIZE_AND_OFFSET(msghdr, msg_flags);
+
+CHECK_TYPE_SIZE(cmsghdr);
+CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_len);
+CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_level);
+CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_type);
+
+COMPILER_CHECK(sizeof(__sanitizer_dirent) <= sizeof(dirent));
+CHECK_SIZE_AND_OFFSET(dirent, d_ino);
+CHECK_SIZE_AND_OFFSET(dirent, d_reclen);
+
+CHECK_TYPE_SIZE(ifconf);
+CHECK_SIZE_AND_OFFSET(ifconf, ifc_len);
+CHECK_SIZE_AND_OFFSET(ifconf, ifc_ifcu);
+
+CHECK_TYPE_SIZE(pollfd);
+CHECK_SIZE_AND_OFFSET(pollfd, fd);
+CHECK_SIZE_AND_OFFSET(pollfd, events);
+CHECK_SIZE_AND_OFFSET(pollfd, revents);
+
+CHECK_TYPE_SIZE(nfds_t);
+
+CHECK_TYPE_SIZE(sigset_t);
+
+COMPILER_CHECK(sizeof(__sanitizer_sigaction) == sizeof(struct sigaction));
+// Can't write checks for sa_handler and sa_sigaction due to them being
+// preprocessor macros.
+CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask);
+
+CHECK_TYPE_SIZE(wordexp_t);
+CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordc);
+CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordv);
+CHECK_SIZE_AND_OFFSET(wordexp_t, we_offs);
+
+CHECK_TYPE_SIZE(tm);
+CHECK_SIZE_AND_OFFSET(tm, tm_sec);
+CHECK_SIZE_AND_OFFSET(tm, tm_min);
+CHECK_SIZE_AND_OFFSET(tm, tm_hour);
+CHECK_SIZE_AND_OFFSET(tm, tm_mday);
+CHECK_SIZE_AND_OFFSET(tm, tm_mon);
+CHECK_SIZE_AND_OFFSET(tm, tm_year);
+CHECK_SIZE_AND_OFFSET(tm, tm_wday);
+CHECK_SIZE_AND_OFFSET(tm, tm_yday);
+CHECK_SIZE_AND_OFFSET(tm, tm_isdst);
+CHECK_SIZE_AND_OFFSET(tm, tm_gmtoff);
+CHECK_SIZE_AND_OFFSET(tm, tm_zone);
+
+CHECK_TYPE_SIZE(ether_addr);
+
+CHECK_TYPE_SIZE(ipc_perm);
+CHECK_SIZE_AND_OFFSET(ipc_perm, key);
+CHECK_SIZE_AND_OFFSET(ipc_perm, seq);
+CHECK_SIZE_AND_OFFSET(ipc_perm, uid);
+CHECK_SIZE_AND_OFFSET(ipc_perm, gid);
+CHECK_SIZE_AND_OFFSET(ipc_perm, cuid);
+CHECK_SIZE_AND_OFFSET(ipc_perm, cgid);
+
+CHECK_TYPE_SIZE(shmid_ds);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_perm);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_segsz);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_atime);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_dtime);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_ctime);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_cpid);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_lpid);
+CHECK_SIZE_AND_OFFSET(shmid_ds, shm_nattch);
+
+CHECK_TYPE_SIZE(clock_t);
+
+CHECK_TYPE_SIZE(ifaddrs);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_addr);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_netmask);
+#undef ifa_dstaddr
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr);
+CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_data);
+
+CHECK_TYPE_SIZE(timeb);
+CHECK_SIZE_AND_OFFSET(timeb, time);
+CHECK_SIZE_AND_OFFSET(timeb, millitm);
+CHECK_SIZE_AND_OFFSET(timeb, timezone);
+CHECK_SIZE_AND_OFFSET(timeb, dstflag);
+
+CHECK_TYPE_SIZE(passwd);
+CHECK_SIZE_AND_OFFSET(passwd, pw_name);
+CHECK_SIZE_AND_OFFSET(passwd, pw_passwd);
+CHECK_SIZE_AND_OFFSET(passwd, pw_uid);
+CHECK_SIZE_AND_OFFSET(passwd, pw_gid);
+CHECK_SIZE_AND_OFFSET(passwd, pw_dir);
+CHECK_SIZE_AND_OFFSET(passwd, pw_shell);
+
+CHECK_SIZE_AND_OFFSET(passwd, pw_gecos);
+
+CHECK_TYPE_SIZE(group);
+CHECK_SIZE_AND_OFFSET(group, gr_name);
+CHECK_SIZE_AND_OFFSET(group, gr_passwd);
+CHECK_SIZE_AND_OFFSET(group, gr_gid);
+CHECK_SIZE_AND_OFFSET(group, gr_mem);
+
+#if HAVE_RPC_XDR_H
+CHECK_TYPE_SIZE(XDR);
+CHECK_SIZE_AND_OFFSET(XDR, x_op);
+CHECK_SIZE_AND_OFFSET(XDR, x_ops);
+CHECK_SIZE_AND_OFFSET(XDR, x_public);
+CHECK_SIZE_AND_OFFSET(XDR, x_private);
+CHECK_SIZE_AND_OFFSET(XDR, x_base);
+CHECK_SIZE_AND_OFFSET(XDR, x_handy);
+COMPILER_CHECK(__sanitizer_XDR_ENCODE == XDR_ENCODE);
+COMPILER_CHECK(__sanitizer_XDR_DECODE == XDR_DECODE);
+COMPILER_CHECK(__sanitizer_XDR_FREE == XDR_FREE);
+#endif
+
+CHECK_TYPE_SIZE(sem_t);
+
+COMPILER_CHECK(sizeof(__sanitizer_cap_rights_t) >= sizeof(cap_rights_t));
+#endif // SANITIZER_FREEBSD
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.h
new file mode 100644
index 0000000..46307c6
--- /dev/null
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.h
@@ -0,0 +1,656 @@
+//===-- sanitizer_platform_limits_freebsd.h -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of Sanitizer common code.
+//
+// Sizes and layouts of platform-specific FreeBSD data structures.
+//===----------------------------------------------------------------------===//
+
+#ifndef SANITIZER_PLATFORM_LIMITS_FREEBSD_H
+#define SANITIZER_PLATFORM_LIMITS_FREEBSD_H
+
+#if SANITIZER_FREEBSD
+
+#include "sanitizer_internal_defs.h"
+#include "sanitizer_platform.h"
+
+#include "sanitizer_platform_limits_posix.h"
+
+// FreeBSD's dlopen() returns a pointer to an Obj_Entry structure that
+// incorporates the map structure.
+# define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \
+ ((link_map*)((handle) == nullptr ? nullptr : ((char*)(handle) + 560)))
+// Get sys/_types.h, because that tells us whether 64-bit inodes are
+// used in struct dirent below.
+#include <sys/_types.h>
+
+namespace __sanitizer {
+ extern unsigned struct_utsname_sz;
+ extern unsigned struct_stat_sz;
+#if defined(__powerpc64__)
+ const unsigned struct___old_kernel_stat_sz = 0;
+#else
+ const unsigned struct___old_kernel_stat_sz = 32;
+#endif
+ extern unsigned struct_rusage_sz;
+ extern unsigned siginfo_t_sz;
+ extern unsigned struct_itimerval_sz;
+ extern unsigned pthread_t_sz;
+ extern unsigned pthread_mutex_t_sz;
+ extern unsigned pthread_cond_t_sz;
+ extern unsigned pid_t_sz;
+ extern unsigned timeval_sz;
+ extern unsigned uid_t_sz;
+ extern unsigned gid_t_sz;
+ extern unsigned fpos_t_sz;
+ extern unsigned mbstate_t_sz;
+ extern unsigned struct_timezone_sz;
+ extern unsigned struct_tms_sz;
+ extern unsigned struct_itimerspec_sz;
+ extern unsigned struct_sigevent_sz;
+ extern unsigned struct_sched_param_sz;
+ extern unsigned struct_statfs64_sz;
+ extern unsigned struct_statfs_sz;
+ extern unsigned struct_sockaddr_sz;
+ extern unsigned ucontext_t_sz;
+ extern unsigned struct_rlimit_sz;
+ extern unsigned struct_utimbuf_sz;
+ extern unsigned struct_timespec_sz;
+ extern unsigned struct_regmatch_sz;
+ extern unsigned struct_regex_sz;
+ extern unsigned struct_FTS_sz;
+ extern unsigned struct_FTSENT_sz;
+ extern const int unvis_valid;
+ extern const int unvis_validpush;
+
+ struct __sanitizer_iocb {
+ u64 aio_data;
+ u32 aio_key_or_aio_reserved1; // Simply crazy.
+ u32 aio_reserved1_or_aio_key; // Luckily, we don't need these.
+ u16 aio_lio_opcode;
+ s16 aio_reqprio;
+ u32 aio_fildes;
+ u64 aio_buf;
+ u64 aio_nbytes;
+ s64 aio_offset;
+ u64 aio_reserved2;
+ u64 aio_reserved3;
+ };
+
+ struct __sanitizer_io_event {
+ u64 data;
+ u64 obj;
+ u64 res;
+ u64 res2;
+ };
+
+ const unsigned iocb_cmd_pread = 0;
+ const unsigned iocb_cmd_pwrite = 1;
+ const unsigned iocb_cmd_preadv = 7;
+ const unsigned iocb_cmd_pwritev = 8;
+
+ struct __sanitizer___sysctl_args {
+ int *name;
+ int nlen;
+ void *oldval;
+ uptr *oldlenp;
+ void *newval;
+ uptr newlen;
+ unsigned long ___unused[4];
+ };
+
+ struct __sanitizer_ipc_perm {
+ unsigned int cuid;
+ unsigned int cgid;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned short mode;
+ unsigned short seq;
+ long key;
+ };
+
+ struct __sanitizer_shmid_ds {
+ __sanitizer_ipc_perm shm_perm;
+ unsigned long shm_segsz;
+ unsigned int shm_lpid;
+ unsigned int shm_cpid;
+ int shm_nattch;
+ unsigned long shm_atime;
+ unsigned long shm_dtime;
+ unsigned long shm_ctime;
+ };
+
+ extern unsigned struct_msqid_ds_sz;
+ extern unsigned struct_mq_attr_sz;
+ extern unsigned struct_timeb_sz;
+ extern unsigned struct_statvfs_sz;
+
+ struct __sanitizer_iovec {
+ void *iov_base;
+ uptr iov_len;
+ };
+
+ struct __sanitizer_ifaddrs {
+ struct __sanitizer_ifaddrs *ifa_next;
+ char *ifa_name;
+ unsigned int ifa_flags;
+ void *ifa_addr; // (struct sockaddr *)
+ void *ifa_netmask; // (struct sockaddr *)
+# undef ifa_dstaddr
+ void *ifa_dstaddr; // (struct sockaddr *)
+ void *ifa_data;
+ };
+
+ typedef unsigned __sanitizer_pthread_key_t;
+
+ struct __sanitizer_passwd {
+ char *pw_name;
+ char *pw_passwd;
+ int pw_uid;
+ int pw_gid;
+ long pw_change;
+ char *pw_class;
+ char *pw_gecos;
+ char *pw_dir;
+ char *pw_shell;
+ long pw_expire;
+ int pw_fields;
+ };
+
+ struct __sanitizer_group {
+ char *gr_name;
+ char *gr_passwd;
+ int gr_gid;
+ char **gr_mem;
+ };
+
+#if defined(__LP64___)
+ typedef long long __sanitizer_time_t;
+#else
+ typedef long __sanitizer_time_t;
+#endif
+
+ typedef long __sanitizer_suseconds_t;
+
+ struct __sanitizer_timeval {
+ __sanitizer_time_t tv_sec;
+ __sanitizer_suseconds_t tv_usec;
+ };
+
+ struct __sanitizer_itimerval {
+ struct __sanitizer_timeval it_interval;
+ struct __sanitizer_timeval it_value;
+ };
+
+ struct __sanitizer_timeb {
+ __sanitizer_time_t time;
+ unsigned short millitm;
+ short timezone;
+ short dstflag;
+ };
+
+ struct __sanitizer_ether_addr {
+ u8 octet[6];
+ };
+
+ struct __sanitizer_tm {
+ int tm_sec;
+ int tm_min;
+ int tm_hour;
+ int tm_mday;
+ int tm_mon;
+ int tm_year;
+ int tm_wday;
+ int tm_yday;
+ int tm_isdst;
+ long int tm_gmtoff;
+ const char *tm_zone;
+ };
+
+ struct __sanitizer_msghdr {
+ void *msg_name;
+ unsigned msg_namelen;
+ struct __sanitizer_iovec *msg_iov;
+ unsigned msg_iovlen;
+ void *msg_control;
+ unsigned msg_controllen;
+ int msg_flags;
+ };
+
+ struct __sanitizer_cmsghdr {
+ unsigned cmsg_len;
+ int cmsg_level;
+ int cmsg_type;
+ };
+
+ struct __sanitizer_dirent {
+#if defined(__INO64)
+ unsigned long long d_fileno;
+ unsigned long long d_off;
+#else
+ unsigned int d_fileno;
+#endif
+ unsigned short d_reclen;
+ // more fields that we don't care about
+ };
+
+// 'clock_t' is 32 bits wide on x64 FreeBSD
+ typedef int __sanitizer_clock_t;
+ typedef int __sanitizer_clockid_t;
+
+#if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__)\
+ || defined(__mips__)
+ typedef unsigned __sanitizer___kernel_uid_t;
+ typedef unsigned __sanitizer___kernel_gid_t;
+#else
+ typedef unsigned short __sanitizer___kernel_uid_t;
+ typedef unsigned short __sanitizer___kernel_gid_t;
+#endif
+ typedef long long __sanitizer___kernel_off_t;
+
+#if defined(__powerpc__) || defined(__mips__)
+ typedef unsigned int __sanitizer___kernel_old_uid_t;
+ typedef unsigned int __sanitizer___kernel_old_gid_t;
+#else
+ typedef unsigned short __sanitizer___kernel_old_uid_t;
+ typedef unsigned short __sanitizer___kernel_old_gid_t;
+#endif
+
+ typedef long long __sanitizer___kernel_loff_t;
+ typedef struct {
+ unsigned long fds_bits[1024 / (8 * sizeof(long))];
+ } __sanitizer___kernel_fd_set;
+
+ // This thing depends on the platform. We are only interested in the upper
+ // limit. Verified with a compiler assert in .cpp.
+ const int pthread_attr_t_max_sz = 128;
+ union __sanitizer_pthread_attr_t {
+ char size[pthread_attr_t_max_sz]; // NOLINT
+ void *align;
+ };
+
+ const unsigned old_sigset_t_sz = sizeof(unsigned long);
+
+ struct __sanitizer_sigset_t {
+ // uint32_t * 4
+ unsigned int __bits[4];
+ };
+
+ typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t;
+
+ struct __sanitizer_siginfo {
+ // The size is determined by looking at sizeof of real siginfo_t on linux.
+ u64 opaque[128 / sizeof(u64)];
+ };
+
+ using __sanitizer_sighandler_ptr = void (*)(int sig);
+ using __sanitizer_sigactionhandler_ptr =
+ void (*)(int sig, __sanitizer_siginfo *siginfo, void *uctx);
+
+ struct __sanitizer_sigaction {
+ union {
+ __sanitizer_sigactionhandler_ptr sigaction;
+ __sanitizer_sighandler_ptr handler;
+ };
+ int sa_flags;
+ __sanitizer_sigset_t sa_mask;
+ };
+
+ struct __sanitizer_sem_t {
+ u32 data[4];
+ };
+
+ extern const uptr sig_ign;
+ extern const uptr sig_dfl;
+ extern const uptr sig_err;
+ extern const uptr sa_siginfo;
+
+ extern int af_inet;
+ extern int af_inet6;
+ uptr __sanitizer_in_addr_sz(int af);
+
+ struct __sanitizer_dl_phdr_info {
+ uptr dlpi_addr;
+ const char *dlpi_name;
+ const void *dlpi_phdr;
+ short dlpi_phnum;
+ };
+
+ extern unsigned struct_ElfW_Phdr_sz;
+
+ struct __sanitizer_addrinfo {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ unsigned ai_addrlen;
+ char *ai_canonname;
+ void *ai_addr;
+ struct __sanitizer_addrinfo *ai_next;
+ };
+
+ struct __sanitizer_hostent {
+ char *h_name;
+ char **h_aliases;
+ int h_addrtype;
+ int h_length;
+ char **h_addr_list;
+ };
+
+ struct __sanitizer_pollfd {
+ int fd;
+ short events;
+ short revents;
+ };
+
+ typedef unsigned __sanitizer_nfds_t;
+
+ struct __sanitizer_glob_t {
+ uptr gl_pathc;
+ uptr gl_matchc;
+ uptr gl_offs;
+ int gl_flags;
+ char **gl_pathv;
+ int (*gl_errfunc)(const char*, int);
+ void (*gl_closedir)(void *dirp);
+ struct dirent *(*gl_readdir)(void *dirp);
+ void *(*gl_opendir)(const char*);
+ int (*gl_lstat)(const char*, void* /* struct stat* */);
+ int (*gl_stat)(const char*, void* /* struct stat* */);
+ };
+
+ extern int glob_nomatch;
+ extern int glob_altdirfunc;
+
+ extern unsigned path_max;
+
+ struct __sanitizer_wordexp_t {
+ uptr we_wordc;
+ char **we_wordv;
+ uptr we_offs;
+ char *we_strings;
+ uptr we_nbytes;
+ };
+
+ typedef void __sanitizer_FILE;
+
+ extern unsigned struct_shminfo_sz;
+ extern unsigned struct_shm_info_sz;
+ extern int shmctl_ipc_stat;
+ extern int shmctl_ipc_info;
+ extern int shmctl_shm_info;
+ extern int shmctl_shm_stat;
+
+ extern unsigned struct_utmpx_sz;
+
+ extern int map_fixed;
+
+ // ioctl arguments
+ struct __sanitizer_ifconf {
+ int ifc_len;
+ union {
+ void *ifcu_req;
+ } ifc_ifcu;
+ };
+
+#define IOC_NRBITS 8
+#define IOC_TYPEBITS 8
+#if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__)
+#define IOC_SIZEBITS 13
+#define IOC_DIRBITS 3
+#define IOC_NONE 1U
+#define IOC_WRITE 4U
+#define IOC_READ 2U
+#else
+#define IOC_SIZEBITS 14
+#define IOC_DIRBITS 2
+#define IOC_NONE 0U
+#define IOC_WRITE 1U
+#define IOC_READ 2U
+#endif
+#define IOC_NRMASK ((1 << IOC_NRBITS) - 1)
+#define IOC_TYPEMASK ((1 << IOC_TYPEBITS) - 1)
+#define IOC_SIZEMASK ((1 << IOC_SIZEBITS) - 1)
+#if defined(IOC_DIRMASK)
+#undef IOC_DIRMASK
+#endif
+#define IOC_DIRMASK ((1 << IOC_DIRBITS) - 1)
+#define IOC_NRSHIFT 0
+#define IOC_TYPESHIFT (IOC_NRSHIFT + IOC_NRBITS)
+#define IOC_SIZESHIFT (IOC_TYPESHIFT + IOC_TYPEBITS)
+#define IOC_DIRSHIFT (IOC_SIZESHIFT + IOC_SIZEBITS)
+#define EVIOC_EV_MAX 0x1f
+#define EVIOC_ABS_MAX 0x3f
+
+#define IOC_DIR(nr) (((nr) >> IOC_DIRSHIFT) & IOC_DIRMASK)
+#define IOC_TYPE(nr) (((nr) >> IOC_TYPESHIFT) & IOC_TYPEMASK)
+#define IOC_NR(nr) (((nr) >> IOC_NRSHIFT) & IOC_NRMASK)
+#define IOC_SIZE(nr) (((nr) >> IOC_SIZESHIFT) & IOC_SIZEMASK)
+
+ extern unsigned struct_ifreq_sz;
+ extern unsigned struct_termios_sz;
+ extern unsigned struct_winsize_sz;
+
+ extern unsigned struct_copr_buffer_sz;
+ extern unsigned struct_copr_debug_buf_sz;
+ extern unsigned struct_copr_msg_sz;
+ extern unsigned struct_midi_info_sz;
+ extern unsigned struct_mtget_sz;
+ extern unsigned struct_mtop_sz;
+ extern unsigned struct_rtentry_sz;
+ extern unsigned struct_sbi_instrument_sz;
+ extern unsigned struct_seq_event_rec_sz;
+ extern unsigned struct_synth_info_sz;
+ extern unsigned struct_vt_mode_sz;
+
+ extern const unsigned long __sanitizer_bufsiz;
+ extern unsigned struct_audio_buf_info_sz;
+ extern unsigned struct_ppp_stats_sz;
+ extern unsigned struct_sioc_sg_req_sz;
+ extern unsigned struct_sioc_vif_req_sz;
+
+ // ioctl request identifiers
+
+ // A special value to mark ioctls that are not present on the target platform,
+ // when it can not be determined without including any system headers.
+ extern const unsigned IOCTL_NOT_PRESENT;
+
+ extern unsigned IOCTL_FIOASYNC;
+ extern unsigned IOCTL_FIOCLEX;
+ extern unsigned IOCTL_FIOGETOWN;
+ extern unsigned IOCTL_FIONBIO;
+ extern unsigned IOCTL_FIONCLEX;
+ extern unsigned IOCTL_FIOSETOWN;
+ extern unsigned IOCTL_SIOCADDMULTI;
+ extern unsigned IOCTL_SIOCATMARK;
+ extern unsigned IOCTL_SIOCDELMULTI;
+ extern unsigned IOCTL_SIOCGIFADDR;
+ extern unsigned IOCTL_SIOCGIFBRDADDR;
+ extern unsigned IOCTL_SIOCGIFCONF;
+ extern unsigned IOCTL_SIOCGIFDSTADDR;
+ extern unsigned IOCTL_SIOCGIFFLAGS;
+ extern unsigned IOCTL_SIOCGIFMETRIC;
+ extern unsigned IOCTL_SIOCGIFMTU;
+ extern unsigned IOCTL_SIOCGIFNETMASK;
+ extern unsigned IOCTL_SIOCGPGRP;
+ extern unsigned IOCTL_SIOCSIFADDR;
+ extern unsigned IOCTL_SIOCSIFBRDADDR;
+ extern unsigned IOCTL_SIOCSIFDSTADDR;
+ extern unsigned IOCTL_SIOCSIFFLAGS;
+ extern unsigned IOCTL_SIOCSIFMETRIC;
+ extern unsigned IOCTL_SIOCSIFMTU;
+ extern unsigned IOCTL_SIOCSIFNETMASK;
+ extern unsigned IOCTL_SIOCSPGRP;
+ extern unsigned IOCTL_TIOCCONS;
+ extern unsigned IOCTL_TIOCEXCL;
+ extern unsigned IOCTL_TIOCGETD;
+ extern unsigned IOCTL_TIOCGPGRP;
+ extern unsigned IOCTL_TIOCGWINSZ;
+ extern unsigned IOCTL_TIOCMBIC;
+ extern unsigned IOCTL_TIOCMBIS;
+ extern unsigned IOCTL_TIOCMGET;
+ extern unsigned IOCTL_TIOCMSET;
+ extern unsigned IOCTL_TIOCNOTTY;
+ extern unsigned IOCTL_TIOCNXCL;
+ extern unsigned IOCTL_TIOCOUTQ;
+ extern unsigned IOCTL_TIOCPKT;
+ extern unsigned IOCTL_TIOCSCTTY;
+ extern unsigned IOCTL_TIOCSETD;
+ extern unsigned IOCTL_TIOCSPGRP;
+ extern unsigned IOCTL_TIOCSTI;
+ extern unsigned IOCTL_TIOCSWINSZ;
+ extern unsigned IOCTL_SIOCGETSGCNT;
+ extern unsigned IOCTL_SIOCGETVIFCNT;
+ extern unsigned IOCTL_MTIOCGET;
+ extern unsigned IOCTL_MTIOCTOP;
+ extern unsigned IOCTL_SIOCADDRT;
+ extern unsigned IOCTL_SIOCDELRT;
+ extern unsigned IOCTL_SNDCTL_DSP_GETBLKSIZE;
+ extern unsigned IOCTL_SNDCTL_DSP_GETFMTS;
+ extern unsigned IOCTL_SNDCTL_DSP_NONBLOCK;
+ extern unsigned IOCTL_SNDCTL_DSP_POST;
+ extern unsigned IOCTL_SNDCTL_DSP_RESET;
+ extern unsigned IOCTL_SNDCTL_DSP_SETFMT;
+ extern unsigned IOCTL_SNDCTL_DSP_SETFRAGMENT;
+ extern unsigned IOCTL_SNDCTL_DSP_SPEED;
+ extern unsigned IOCTL_SNDCTL_DSP_STEREO;
+ extern unsigned IOCTL_SNDCTL_DSP_SUBDIVIDE;
+ extern unsigned IOCTL_SNDCTL_DSP_SYNC;
+ extern unsigned IOCTL_SNDCTL_FM_4OP_ENABLE;
+ extern unsigned IOCTL_SNDCTL_FM_LOAD_INSTR;
+ extern unsigned IOCTL_SNDCTL_MIDI_INFO;
+ extern unsigned IOCTL_SNDCTL_MIDI_PRETIME;
+ extern unsigned IOCTL_SNDCTL_SEQ_CTRLRATE;
+ extern unsigned IOCTL_SNDCTL_SEQ_GETINCOUNT;
+ extern unsigned IOCTL_SNDCTL_SEQ_GETOUTCOUNT;
+ extern unsigned IOCTL_SNDCTL_SEQ_NRMIDIS;
+ extern unsigned IOCTL_SNDCTL_SEQ_NRSYNTHS;
+ extern unsigned IOCTL_SNDCTL_SEQ_OUTOFBAND;
+ extern unsigned IOCTL_SNDCTL_SEQ_PANIC;
+ extern unsigned IOCTL_SNDCTL_SEQ_PERCMODE;
+ extern unsigned IOCTL_SNDCTL_SEQ_RESET;
+ extern unsigned IOCTL_SNDCTL_SEQ_RESETSAMPLES;
+ extern unsigned IOCTL_SNDCTL_SEQ_SYNC;
+ extern unsigned IOCTL_SNDCTL_SEQ_TESTMIDI;
+ extern unsigned IOCTL_SNDCTL_SEQ_THRESHOLD;
+ extern unsigned IOCTL_SNDCTL_SYNTH_INFO;
+ extern unsigned IOCTL_SNDCTL_SYNTH_MEMAVL;
+ extern unsigned IOCTL_SNDCTL_TMR_CONTINUE;
+ extern unsigned IOCTL_SNDCTL_TMR_METRONOME;
+ extern unsigned IOCTL_SNDCTL_TMR_SELECT;
+ extern unsigned IOCTL_SNDCTL_TMR_SOURCE;
+ extern unsigned IOCTL_SNDCTL_TMR_START;
+ extern unsigned IOCTL_SNDCTL_TMR_STOP;
+ extern unsigned IOCTL_SNDCTL_TMR_TEMPO;
+ extern unsigned IOCTL_SNDCTL_TMR_TIMEBASE;
+ extern unsigned IOCTL_SOUND_MIXER_READ_ALTPCM;
+ extern unsigned IOCTL_SOUND_MIXER_READ_BASS;
+ extern unsigned IOCTL_SOUND_MIXER_READ_CAPS;
+ extern unsigned IOCTL_SOUND_MIXER_READ_CD;
+ extern unsigned IOCTL_SOUND_MIXER_READ_DEVMASK;
+ extern unsigned IOCTL_SOUND_MIXER_READ_ENHANCE;
+ extern unsigned IOCTL_SOUND_MIXER_READ_IGAIN;
+ extern unsigned IOCTL_SOUND_MIXER_READ_IMIX;
+ extern unsigned IOCTL_SOUND_MIXER_READ_LINE1;
+ extern unsigned IOCTL_SOUND_MIXER_READ_LINE2;
+ extern unsigned IOCTL_SOUND_MIXER_READ_LINE3;
+ extern unsigned IOCTL_SOUND_MIXER_READ_LINE;
+ extern unsigned IOCTL_SOUND_MIXER_READ_LOUD;
+ extern unsigned IOCTL_SOUND_MIXER_READ_MIC;
+ extern unsigned IOCTL_SOUND_MIXER_READ_MUTE;
+ extern unsigned IOCTL_SOUND_MIXER_READ_OGAIN;
+ extern unsigned IOCTL_SOUND_MIXER_READ_PCM;
+ extern unsigned IOCTL_SOUND_MIXER_READ_RECLEV;
+ extern unsigned IOCTL_SOUND_MIXER_READ_RECMASK;
+ extern unsigned IOCTL_SOUND_MIXER_READ_RECSRC;
+ extern unsigned IOCTL_SOUND_MIXER_READ_SPEAKER;
+ extern unsigned IOCTL_SOUND_MIXER_READ_STEREODEVS;
+ extern unsigned IOCTL_SOUND_MIXER_READ_SYNTH;
+ extern unsigned IOCTL_SOUND_MIXER_READ_TREBLE;
+ extern unsigned IOCTL_SOUND_MIXER_READ_VOLUME;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_ALTPCM;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_BASS;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_CD;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_ENHANCE;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_IGAIN;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_IMIX;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE1;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE2;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE3;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_LOUD;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_MIC;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_MUTE;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_OGAIN;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_PCM;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_RECLEV;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_RECSRC;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_SPEAKER;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_SYNTH;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_TREBLE;
+ extern unsigned IOCTL_SOUND_MIXER_WRITE_VOLUME;
+ extern unsigned IOCTL_SOUND_PCM_READ_BITS;
+ extern unsigned IOCTL_SOUND_PCM_READ_CHANNELS;
+ extern unsigned IOCTL_SOUND_PCM_READ_FILTER;
+ extern unsigned IOCTL_SOUND_PCM_READ_RATE;
+ extern unsigned IOCTL_SOUND_PCM_WRITE_CHANNELS;
+ extern unsigned IOCTL_SOUND_PCM_WRITE_FILTER;
+ extern unsigned IOCTL_VT_ACTIVATE;
+ extern unsigned IOCTL_VT_GETMODE;
+ extern unsigned IOCTL_VT_OPENQRY;
+ extern unsigned IOCTL_VT_RELDISP;
+ extern unsigned IOCTL_VT_SETMODE;
+ extern unsigned IOCTL_VT_WAITACTIVE;
+ extern unsigned IOCTL_GIO_SCRNMAP;
+ extern unsigned IOCTL_KDDISABIO;
+ extern unsigned IOCTL_KDENABIO;
+ extern unsigned IOCTL_KDGETLED;
+ extern unsigned IOCTL_KDGETMODE;
+ extern unsigned IOCTL_KDGKBMODE;
+ extern unsigned IOCTL_KDGKBTYPE;
+ extern unsigned IOCTL_KDMKTONE;
+ extern unsigned IOCTL_KDSETLED;
+ extern unsigned IOCTL_KDSETMODE;
+ extern unsigned IOCTL_KDSKBMODE;
+
+ extern const int si_SEGV_MAPERR;
+ extern const int si_SEGV_ACCERR;
+
+ struct __sanitizer_cap_rights {
+ u64 cr_rights[2];
+ };
+
+ typedef struct __sanitizer_cap_rights __sanitizer_cap_rights_t;
+ extern unsigned struct_cap_rights_sz;
+
+ extern unsigned struct_fstab_sz;
+ extern unsigned struct_StringList_sz;
+} // namespace __sanitizer
+
+#define CHECK_TYPE_SIZE(TYPE) \
+ COMPILER_CHECK(sizeof(__sanitizer_##TYPE) == sizeof(TYPE))
+
+#define CHECK_SIZE_AND_OFFSET(CLASS, MEMBER) \
+ COMPILER_CHECK(sizeof(((__sanitizer_##CLASS *) NULL)->MEMBER) == \
+ sizeof(((CLASS *) NULL)->MEMBER)); \
+ COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) == \
+ offsetof(CLASS, MEMBER))
+
+// For sigaction, which is a function and struct at the same time,
+// and thus requires explicit "struct" in sizeof() expression.
+#define CHECK_STRUCT_SIZE_AND_OFFSET(CLASS, MEMBER) \
+ COMPILER_CHECK(sizeof(((struct __sanitizer_##CLASS *) NULL)->MEMBER) == \
+ sizeof(((struct CLASS *) NULL)->MEMBER)); \
+ COMPILER_CHECK(offsetof(struct __sanitizer_##CLASS, MEMBER) == \
+ offsetof(struct CLASS, MEMBER))
+
+#define SIGACTION_SYMNAME sigaction
+
+#endif
+
+#endif // SANITIZER_FREEBSD
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp
index 3a90653..7c1a21d 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_platform_limits_linux.cc --------------------------------===//
+//===-- sanitizer_platform_limits_linux.cpp -------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -12,7 +13,7 @@
// This is a separate compilation unit for linux headers that conflict with
// userspace headers.
-// Most "normal" includes go in sanitizer_platform_limits_posix.cc
+// Most "normal" includes go in sanitizer_platform_limits_posix.cpp
#include "sanitizer_platform.h"
#if SANITIZER_LINUX
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cpp
index 8e74727..f01de6c 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_platform_limits_netbsd.cc -------------------------------===//
+//===-- sanitizer_platform_limits_netbsd.cpp ------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -13,9 +14,82 @@
#include "sanitizer_platform.h"
#if SANITIZER_NETBSD
+
+#define _KMEMUSER
+#define RAY_DO_SIGLEV
+
+// clang-format off
#include <sys/param.h>
#include <sys/types.h>
-
+#include <sys/sysctl.h>
+#include <sys/disk.h>
+#include <sys/disklabel.h>
+#include <sys/mount.h>
+#include <sys/agpio.h>
+#include <sys/ataio.h>
+#include <sys/audioio.h>
+#include <sys/cdbr.h>
+#include <sys/cdio.h>
+#include <sys/chio.h>
+#include <sys/clockctl.h>
+#include <sys/cpuio.h>
+#include <sys/dkio.h>
+#include <sys/drvctlio.h>
+#include <sys/dvdio.h>
+#include <sys/envsys.h>
+#include <sys/event.h>
+#include <sys/fdio.h>
+#include <sys/filio.h>
+#include <sys/gpio.h>
+#include <sys/ioctl.h>
+#include <sys/ioctl_compat.h>
+#include <sys/joystick.h>
+#include <sys/ksyms.h>
+#include <sys/lua.h>
+#include <sys/midiio.h>
+#include <sys/mtio.h>
+#include <sys/power.h>
+#include <sys/radioio.h>
+#include <sys/rndio.h>
+#include <sys/scanio.h>
+#include <sys/scsiio.h>
+#include <sys/sockio.h>
+#include <sys/timepps.h>
+#include <sys/ttycom.h>
+#include <sys/verified_exec.h>
+#include <sys/videoio.h>
+#include <sys/wdog.h>
+#include <sys/event.h>
+#include <sys/filio.h>
+#include <sys/ipc.h>
+#include <sys/ipmi.h>
+#include <sys/kcov.h>
+#include <sys/mman.h>
+#include <sys/module.h>
+#include <sys/mount.h>
+#include <sys/mqueue.h>
+#include <sys/msg.h>
+#include <sys/mtio.h>
+#include <sys/ptrace.h>
+#include <sys/resource.h>
+#include <sys/sem.h>
+#include <sys/sha1.h>
+#include <sys/sha2.h>
+#include <sys/shm.h>
+#include <sys/signal.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/soundcard.h>
+#include <sys/stat.h>
+#include <sys/statvfs.h>
+#include <sys/time.h>
+#include <sys/timeb.h>
+#include <sys/times.h>
+#include <sys/timespec.h>
+#include <sys/timex.h>
+#include <sys/types.h>
+#include <sys/ucontext.h>
+#include <sys/utsname.h>
#include <altq/altq.h>
#include <altq/altq_afmap.h>
#include <altq/altq_blue.h>
@@ -45,47 +119,39 @@
#include <dev/ic/icp_ioctl.h>
#include <dev/ic/isp_ioctl.h>
#include <dev/ic/mlxio.h>
+#include <dev/ic/qemufwcfgio.h>
#include <dev/ic/nvmeio.h>
#include <dev/ir/irdaio.h>
#include <dev/isa/isvio.h>
-#include <dev/isa/satlinkio.h>
#include <dev/isa/wtreg.h>
#include <dev/iscsi/iscsi_ioctl.h>
#include <dev/ofw/openfirmio.h>
#include <dev/pci/amrio.h>
-
#include <dev/pci/mlyreg.h>
#include <dev/pci/mlyio.h>
-
#include <dev/pci/pciio.h>
#include <dev/pci/tweio.h>
#include <dev/pcmcia/if_cnwioctl.h>
-#include <dirent.h>
-#include <glob.h>
-#include <grp.h>
-#include <ifaddrs.h>
-#include <limits.h>
-#include <link_elf.h>
-#include <net/if.h>
-#include <net/if_ether.h>
+#include <net/bpf.h>
+#include <net/if_gre.h>
#include <net/ppp_defs.h>
-#include <net/route.h>
-#include <netdb.h>
-#include <netinet/in.h>
+#include <net/if_ppp.h>
+#include <net/if_pppoe.h>
+#include <net/if_sppp.h>
+#include <net/if_srt.h>
+#include <net/if_tap.h>
+#include <net/if_tun.h>
+#include <net/npf.h>
+#include <net/pfvar.h>
+#include <net/slip.h>
+#include <netbt/hci.h>
#include <netinet/ip_compat.h>
#include <netinet/ip_fil.h>
-#include <netinet/ip_mroute.h>
-#include <poll.h>
-#include <pthread.h>
-#include <pwd.h>
-#include <semaphore.h>
-#include <signal.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <sys/disk.h>
-#include <sys/disklabel.h>
-#include <sys/mount.h>
-#define RAY_DO_SIGLEV
+#include <netinet/ip_nat.h>
+#include <netinet/ip_proxy.h>
+#include <netinet6/in6_var.h>
+#include <netinet6/nd6.h>
+#include <netsmb/smb_dev.h>
#include <dev/biovar.h>
#include <dev/bluetooth/btdev.h>
#include <dev/bluetooth/btsco.h>
@@ -95,10 +161,13 @@
#include <dev/kttcpio.h>
#include <dev/lockstat.h>
#include <dev/md.h>
+#include <net/if_ether.h>
#include <dev/pcmcia/if_rayreg.h>
+#include <stdio.h>
#include <dev/raidframe/raidframeio.h>
#include <dev/sbus/mbppio.h>
#include <dev/scsipi/ses.h>
+#include <dev/spi/spi_io.h>
#include <dev/spkrio.h>
#include <dev/sun/disklabel.h>
#include <dev/sun/fbio.h>
@@ -113,86 +182,30 @@
#include <dev/vndvar.h>
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplay_usl_io.h>
-#include <net/bpf.h>
-#include <net/if_atm.h>
-#include <net/if_gre.h>
-#include <net/if_ppp.h>
-#include <net/if_pppoe.h>
-#include <net/if_sppp.h>
-#include <net/if_srt.h>
-#include <net/if_tap.h>
-#include <net/if_tun.h>
-#include <net/npf.h>
-#include <net/pfvar.h>
-#include <net/slip.h>
-#include <netbt/hci.h>
-#include <netinet/ip_nat.h>
-#include <netinet/ip_proxy.h>
-#include <netinet6/in6_var.h>
-#include <netinet6/nd6.h>
-#include <netnatm/natm.h>
-#include <netsmb/smb_dev.h>
+#include <fs/autofs/autofs_ioctl.h>
+#include <dirent.h>
+#include <glob.h>
+#include <grp.h>
+#include <ifaddrs.h>
+#include <limits.h>
+#include <link_elf.h>
+#include <net/if.h>
+#include <net/route.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/ip_mroute.h>
+#include <netinet/sctp_uio.h>
+#include <poll.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <semaphore.h>
+#include <signal.h>
+#include <stddef.h>
+#include <md2.h>
+#include <md4.h>
+#include <md5.h>
+#include <rmd160.h>
#include <soundcard.h>
-#include <sys/agpio.h>
-#include <sys/ataio.h>
-#include <sys/audioio.h>
-#include <sys/cdio.h>
-#include <sys/chio.h>
-#include <sys/clockctl.h>
-#include <sys/cpuio.h>
-#include <sys/dkio.h>
-#include <sys/drvctlio.h>
-#include <sys/dvdio.h>
-#include <sys/envsys.h>
-#include <sys/event.h>
-#include <sys/fdio.h>
-#include <sys/filio.h>
-#include <sys/gpio.h>
-#include <sys/ioctl.h>
-#include <sys/ioctl_compat.h>
-#include <sys/joystick.h>
-#include <sys/ksyms.h>
-#include <sys/lua.h>
-#include <sys/midiio.h>
-#include <sys/mtio.h>
-#include <sys/power.h>
-#include <sys/radioio.h>
-#include <sys/rndio.h>
-#include <sys/scanio.h>
-#include <sys/scsiio.h>
-#include <sys/sockio.h>
-#include <sys/timepps.h>
-#include <sys/ttycom.h>
-#include <sys/verified_exec.h>
-#include <sys/videoio.h>
-#include <sys/wdog.h>
-//#include <xen/xenio.h>
-#include <sys/event.h>
-#include <sys/filio.h>
-#include <sys/ipc.h>
-#include <sys/mman.h>
-#include <sys/mount.h>
-#include <sys/mqueue.h>
-#include <sys/msg.h>
-#include <sys/mtio.h>
-#include <sys/ptrace.h>
-#include <sys/resource.h>
-#include <sys/sem.h>
-#include <sys/shm.h>
-#include <sys/signal.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/soundcard.h>
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-#include <sys/time.h>
-#include <sys/timeb.h>
-#include <sys/times.h>
-#include <sys/timespec.h>
-#include <sys/timex.h>
-#include <sys/types.h>
-#include <sys/ucontext.h>
-#include <sys/utsname.h>
#include <term.h>
#include <termios.h>
#include <time.h>
@@ -200,8 +213,19 @@
#include <utime.h>
#include <utmp.h>
#include <utmpx.h>
+#include <vis.h>
#include <wchar.h>
#include <wordexp.h>
+#include <ttyent.h>
+#include <fts.h>
+#include <regex.h>
+#include <fstab.h>
+#include <stringlist.h>
+
+#if defined(__x86_64__)
+#include <nvmm.h>
+#endif
+// clang-format on
// Include these after system headers to avoid name clashes and ambiguities.
#include "sanitizer_internal_defs.h"
@@ -236,6 +260,11 @@ unsigned struct_rlimit_sz = sizeof(struct rlimit);
unsigned struct_timespec_sz = sizeof(struct timespec);
unsigned struct_sembuf_sz = sizeof(struct sembuf);
unsigned struct_kevent_sz = sizeof(struct kevent);
+unsigned struct_FTS_sz = sizeof(FTS);
+unsigned struct_FTSENT_sz = sizeof(FTSENT);
+unsigned struct_regex_sz = sizeof(regex_t);
+unsigned struct_regmatch_sz = sizeof(regmatch_t);
+unsigned struct_fstab_sz = sizeof(struct fstab);
unsigned struct_utimbuf_sz = sizeof(struct utimbuf);
unsigned struct_itimerspec_sz = sizeof(struct itimerspec);
unsigned struct_timex_sz = sizeof(struct timex);
@@ -249,6 +278,8 @@ const uptr sig_dfl = (uptr)SIG_DFL;
const uptr sig_err = (uptr)SIG_ERR;
const uptr sa_siginfo = (uptr)SA_SIGINFO;
+const unsigned long __sanitizer_bufsiz = BUFSIZ;
+
int ptrace_pt_io = PT_IO;
int ptrace_pt_lwpinfo = PT_LWPINFO;
int ptrace_pt_set_event_mask = PT_SET_EVENT_MASK;
@@ -337,6 +368,14 @@ unsigned path_max = PATH_MAX;
int struct_ttyent_sz = sizeof(struct ttyent);
+struct __sanitizer_nvlist_ref_t {
+ void *buf;
+ uptr len;
+ int flags;
+};
+
+typedef __sanitizer_nvlist_ref_t nvlist_ref_t;
+
// ioctl arguments
unsigned struct_altqreq_sz = sizeof(altqreq);
unsigned struct_amr_user_ioctl_sz = sizeof(amr_user_ioctl);
@@ -348,7 +387,6 @@ unsigned struct_atabusiodetach_args_sz = sizeof(atabusiodetach_args);
unsigned struct_atabusioscan_args_sz = sizeof(atabusioscan_args);
unsigned struct_ath_diag_sz = sizeof(ath_diag);
unsigned struct_atm_flowmap_sz = sizeof(atm_flowmap);
-unsigned struct_atm_pseudoioctl_sz = sizeof(atm_pseudoioctl);
unsigned struct_audio_buf_info_sz = sizeof(audio_buf_info);
unsigned struct_audio_device_sz = sizeof(audio_device);
unsigned struct_audio_encoding_sz = sizeof(audio_encoding);
@@ -594,7 +632,6 @@ unsigned struct_priq_delete_filter_sz = sizeof(priq_delete_filter);
unsigned struct_priq_interface_sz = sizeof(priq_interface);
unsigned struct_priq_modify_class_sz = sizeof(priq_modify_class);
unsigned struct_ptmget_sz = sizeof(ptmget);
-unsigned struct_pvctxreq_sz = sizeof(pvctxreq);
unsigned struct_radio_info_sz = sizeof(radio_info);
unsigned struct_red_conf_sz = sizeof(red_conf);
unsigned struct_red_interface_sz = sizeof(red_interface);
@@ -606,7 +643,6 @@ unsigned struct_rf_recon_req_sz = sizeof(rf_recon_req);
unsigned struct_rio_conf_sz = sizeof(rio_conf);
unsigned struct_rio_interface_sz = sizeof(rio_interface);
unsigned struct_rio_stats_sz = sizeof(rio_stats);
-unsigned struct_satlink_id_sz = sizeof(satlink_id);
unsigned struct_scan_io_sz = sizeof(scan_io);
unsigned struct_scbusaccel_args_sz = sizeof(scbusaccel_args);
unsigned struct_scbusiodetach_args_sz = sizeof(scbusiodetach_args);
@@ -654,6 +690,29 @@ unsigned struct_usb_config_desc_sz = sizeof(usb_config_desc);
unsigned struct_usb_ctl_report_desc_sz = sizeof(usb_ctl_report_desc);
unsigned struct_usb_ctl_report_sz = sizeof(usb_ctl_report);
unsigned struct_usb_ctl_request_sz = sizeof(usb_ctl_request);
+#if defined(__x86_64__)
+unsigned struct_nvmm_ioc_capability_sz = sizeof(nvmm_ioc_capability);
+unsigned struct_nvmm_ioc_machine_create_sz = sizeof(nvmm_ioc_machine_create);
+unsigned struct_nvmm_ioc_machine_destroy_sz = sizeof(nvmm_ioc_machine_destroy);
+unsigned struct_nvmm_ioc_machine_configure_sz =
+ sizeof(nvmm_ioc_machine_configure);
+unsigned struct_nvmm_ioc_vcpu_create_sz = sizeof(nvmm_ioc_vcpu_create);
+unsigned struct_nvmm_ioc_vcpu_destroy_sz = sizeof(nvmm_ioc_vcpu_destroy);
+unsigned struct_nvmm_ioc_vcpu_setstate_sz = sizeof(nvmm_ioc_vcpu_destroy);
+unsigned struct_nvmm_ioc_vcpu_getstate_sz = sizeof(nvmm_ioc_vcpu_getstate);
+unsigned struct_nvmm_ioc_vcpu_inject_sz = sizeof(nvmm_ioc_vcpu_inject);
+unsigned struct_nvmm_ioc_vcpu_run_sz = sizeof(nvmm_ioc_vcpu_run);
+unsigned struct_nvmm_ioc_gpa_map_sz = sizeof(nvmm_ioc_gpa_map);
+unsigned struct_nvmm_ioc_gpa_unmap_sz = sizeof(nvmm_ioc_gpa_unmap);
+unsigned struct_nvmm_ioc_hva_map_sz = sizeof(nvmm_ioc_hva_map);
+unsigned struct_nvmm_ioc_hva_unmap_sz = sizeof(nvmm_ioc_hva_unmap);
+unsigned struct_nvmm_ioc_ctl_sz = sizeof(nvmm_ioc_ctl);
+#endif
+unsigned struct_spi_ioctl_configure_sz = sizeof(spi_ioctl_configure);
+unsigned struct_spi_ioctl_transfer_sz = sizeof(spi_ioctl_transfer);
+unsigned struct_autofs_daemon_request_sz = sizeof(autofs_daemon_request);
+unsigned struct_autofs_daemon_done_sz = sizeof(autofs_daemon_done);
+unsigned struct_sctp_connectx_addrs_sz = sizeof(sctp_connectx_addrs);
unsigned struct_usb_device_info_old_sz = sizeof(usb_device_info_old);
unsigned struct_usb_device_info_sz = sizeof(usb_device_info);
unsigned struct_usb_device_stats_sz = sizeof(usb_device_stats);
@@ -693,6 +752,9 @@ unsigned struct_vnd_user_sz = sizeof(vnd_user);
unsigned struct_vt_stat_sz = sizeof(vt_stat);
unsigned struct_wdog_conf_sz = sizeof(wdog_conf);
unsigned struct_wdog_mode_sz = sizeof(wdog_mode);
+unsigned struct_ipmi_recv_sz = sizeof(ipmi_recv);
+unsigned struct_ipmi_req_sz = sizeof(ipmi_req);
+unsigned struct_ipmi_cmdspec_sz = sizeof(ipmi_cmdspec);
unsigned struct_wfq_conf_sz = sizeof(wfq_conf);
unsigned struct_wfq_getqid_sz = sizeof(wfq_getqid);
unsigned struct_wfq_getstats_sz = sizeof(wfq_getstats);
@@ -778,6 +840,7 @@ unsigned struct_iscsi_wait_event_parameters_sz =
unsigned struct_isp_stats_sz = sizeof(isp_stats_t);
unsigned struct_lsenable_sz = sizeof(struct lsenable);
unsigned struct_lsdisable_sz = sizeof(struct lsdisable);
+unsigned struct_audio_format_query_sz = sizeof(audio_format_query);
unsigned struct_mixer_ctrl_sz = sizeof(struct mixer_ctrl);
unsigned struct_mixer_devinfo_sz = sizeof(struct mixer_devinfo);
unsigned struct_mpu_command_rec_sz = sizeof(mpu_command_rec);
@@ -795,6 +858,8 @@ unsigned struct_RF_SparetWait_sz = sizeof(RF_SparetWait_t);
unsigned struct_RF_ComponentLabel_sz = sizeof(RF_ComponentLabel_t);
unsigned struct_RF_SingleComponent_sz = sizeof(RF_SingleComponent_t);
unsigned struct_RF_ProgressInfo_sz = sizeof(RF_ProgressInfo_t);
+unsigned struct_nvlist_ref_sz = sizeof(struct __sanitizer_nvlist_ref_t);
+unsigned struct_StringList_sz = sizeof(StringList);
const unsigned IOCTL_NOT_PRESENT = 0;
@@ -1059,6 +1124,7 @@ unsigned IOCTL_MLX_REBUILDSTAT = MLX_REBUILDSTAT;
unsigned IOCTL_MLX_GET_SYSDRIVE = MLX_GET_SYSDRIVE;
unsigned IOCTL_MLX_GET_CINFO = MLX_GET_CINFO;
unsigned IOCTL_NVME_PASSTHROUGH_CMD = NVME_PASSTHROUGH_CMD;
+unsigned IOCTL_FWCFGIO_SET_INDEX = FWCFGIO_SET_INDEX;
unsigned IOCTL_IRDA_RESET_PARAMS = IRDA_RESET_PARAMS;
unsigned IOCTL_IRDA_SET_PARAMS = IRDA_SET_PARAMS;
unsigned IOCTL_IRDA_GET_SPEEDMASK = IRDA_GET_SPEEDMASK;
@@ -1066,9 +1132,6 @@ unsigned IOCTL_IRDA_GET_TURNAROUNDMASK = IRDA_GET_TURNAROUNDMASK;
unsigned IOCTL_IRFRAMETTY_GET_DEVICE = IRFRAMETTY_GET_DEVICE;
unsigned IOCTL_IRFRAMETTY_GET_DONGLE = IRFRAMETTY_GET_DONGLE;
unsigned IOCTL_IRFRAMETTY_SET_DONGLE = IRFRAMETTY_SET_DONGLE;
-unsigned IOCTL_SATIORESET = SATIORESET;
-unsigned IOCTL_SATIOGID = SATIOGID;
-unsigned IOCTL_SATIOSBUFSIZE = SATIOSBUFSIZE;
unsigned IOCTL_ISV_CMD = ISV_CMD;
unsigned IOCTL_WTQICMD = WTQICMD;
unsigned IOCTL_ISCSI_GET_VERSION = ISCSI_GET_VERSION;
@@ -1388,6 +1451,27 @@ unsigned IOCTL_SPKRTONE = SPKRTONE;
unsigned IOCTL_SPKRTUNE = SPKRTUNE;
unsigned IOCTL_SPKRGETVOL = SPKRGETVOL;
unsigned IOCTL_SPKRSETVOL = SPKRSETVOL;
+#if defined(__x86_64__)
+unsigned IOCTL_NVMM_IOC_CAPABILITY = NVMM_IOC_CAPABILITY;
+unsigned IOCTL_NVMM_IOC_MACHINE_CREATE = NVMM_IOC_MACHINE_CREATE;
+unsigned IOCTL_NVMM_IOC_MACHINE_DESTROY = NVMM_IOC_MACHINE_DESTROY;
+unsigned IOCTL_NVMM_IOC_MACHINE_CONFIGURE = NVMM_IOC_MACHINE_CONFIGURE;
+unsigned IOCTL_NVMM_IOC_VCPU_CREATE = NVMM_IOC_VCPU_CREATE;
+unsigned IOCTL_NVMM_IOC_VCPU_DESTROY = NVMM_IOC_VCPU_DESTROY;
+unsigned IOCTL_NVMM_IOC_VCPU_SETSTATE = NVMM_IOC_VCPU_SETSTATE;
+unsigned IOCTL_NVMM_IOC_VCPU_GETSTATE = NVMM_IOC_VCPU_GETSTATE;
+unsigned IOCTL_NVMM_IOC_VCPU_INJECT = NVMM_IOC_VCPU_INJECT;
+unsigned IOCTL_NVMM_IOC_VCPU_RUN = NVMM_IOC_VCPU_RUN;
+unsigned IOCTL_NVMM_IOC_GPA_MAP = NVMM_IOC_GPA_MAP;
+unsigned IOCTL_NVMM_IOC_GPA_UNMAP = NVMM_IOC_GPA_UNMAP;
+unsigned IOCTL_NVMM_IOC_HVA_MAP = NVMM_IOC_HVA_MAP;
+unsigned IOCTL_NVMM_IOC_HVA_UNMAP = NVMM_IOC_HVA_UNMAP;
+unsigned IOCTL_NVMM_IOC_CTL = NVMM_IOC_CTL;
+#endif
+unsigned IOCTL_SPI_IOCTL_CONFIGURE = SPI_IOCTL_CONFIGURE;
+unsigned IOCTL_SPI_IOCTL_TRANSFER = SPI_IOCTL_TRANSFER;
+unsigned IOCTL_AUTOFSREQUEST = AUTOFSREQUEST;
+unsigned IOCTL_AUTOFSDONE = AUTOFSDONE;
unsigned IOCTL_BIOCGBLEN = BIOCGBLEN;
unsigned IOCTL_BIOCSBLEN = BIOCSBLEN;
unsigned IOCTL_BIOCSETF = BIOCSETF;
@@ -1406,19 +1490,12 @@ unsigned IOCTL_BIOCGHDRCMPLT = BIOCGHDRCMPLT;
unsigned IOCTL_BIOCSHDRCMPLT = BIOCSHDRCMPLT;
unsigned IOCTL_BIOCSDLT = BIOCSDLT;
unsigned IOCTL_BIOCGDLTLIST = BIOCGDLTLIST;
-unsigned IOCTL_BIOCGSEESENT = BIOCGSEESENT;
-unsigned IOCTL_BIOCSSEESENT = BIOCSSEESENT;
+unsigned IOCTL_BIOCGDIRECTION = BIOCGDIRECTION;
+unsigned IOCTL_BIOCSDIRECTION = BIOCSDIRECTION;
unsigned IOCTL_BIOCSRTIMEOUT = BIOCSRTIMEOUT;
unsigned IOCTL_BIOCGRTIMEOUT = BIOCGRTIMEOUT;
unsigned IOCTL_BIOCGFEEDBACK = BIOCGFEEDBACK;
unsigned IOCTL_BIOCSFEEDBACK = BIOCSFEEDBACK;
-unsigned IOCTL_SIOCRAWATM = SIOCRAWATM;
-unsigned IOCTL_SIOCATMENA = SIOCATMENA;
-unsigned IOCTL_SIOCATMDIS = SIOCATMDIS;
-unsigned IOCTL_SIOCSPVCTX = SIOCSPVCTX;
-unsigned IOCTL_SIOCGPVCTX = SIOCGPVCTX;
-unsigned IOCTL_SIOCSPVCSIF = SIOCSPVCSIF;
-unsigned IOCTL_SIOCGPVCSIF = SIOCGPVCSIF;
unsigned IOCTL_GRESADDRS = GRESADDRS;
unsigned IOCTL_GRESADDRD = GRESADDRD;
unsigned IOCTL_GREGADDRS = GREGADDRS;
@@ -1573,6 +1650,8 @@ unsigned IOCTL_SIOCRMNAT = SIOCRMNAT;
unsigned IOCTL_SIOCGNATS = SIOCGNATS;
unsigned IOCTL_SIOCGNATL = SIOCGNATL;
unsigned IOCTL_SIOCPURGENAT = SIOCPURGENAT;
+unsigned IOCTL_SIOCCONNECTX = SIOCCONNECTX;
+unsigned IOCTL_SIOCCONNECTXDEL = SIOCCONNECTXDEL;
unsigned IOCTL_SIOCSIFINFO_FLAGS = SIOCSIFINFO_FLAGS;
unsigned IOCTL_SIOCAADDRCTL_POLICY = SIOCAADDRCTL_POLICY;
unsigned IOCTL_SIOCDADDRCTL_POLICY = SIOCDADDRCTL_POLICY;
@@ -1608,6 +1687,9 @@ unsigned IOCTL_AUDIO_GETPROPS = AUDIO_GETPROPS;
unsigned IOCTL_AUDIO_GETBUFINFO = AUDIO_GETBUFINFO;
unsigned IOCTL_AUDIO_SETCHAN = AUDIO_SETCHAN;
unsigned IOCTL_AUDIO_GETCHAN = AUDIO_GETCHAN;
+unsigned IOCTL_AUDIO_QUERYFORMAT = AUDIO_QUERYFORMAT;
+unsigned IOCTL_AUDIO_GETFORMAT = AUDIO_GETFORMAT;
+unsigned IOCTL_AUDIO_SETFORMAT = AUDIO_SETFORMAT;
unsigned IOCTL_AUDIO_MIXER_READ = AUDIO_MIXER_READ;
unsigned IOCTL_AUDIO_MIXER_WRITE = AUDIO_MIXER_WRITE;
unsigned IOCTL_AUDIO_MIXER_DEVINFO = AUDIO_MIXER_DEVINFO;
@@ -1693,6 +1775,7 @@ unsigned IOCTL_DIOCTUR = DIOCTUR;
unsigned IOCTL_DIOCMWEDGES = DIOCMWEDGES;
unsigned IOCTL_DIOCGSECTORSIZE = DIOCGSECTORSIZE;
unsigned IOCTL_DIOCGMEDIASIZE = DIOCGMEDIASIZE;
+unsigned IOCTL_DIOCRMWEDGES = DIOCRMWEDGES;
unsigned IOCTL_DRVDETACHDEV = DRVDETACHDEV;
unsigned IOCTL_DRVRESCANBUS = DRVRESCANBUS;
unsigned IOCTL_DRVCTLCOMMAND = DRVCTLCOMMAND;
@@ -1717,6 +1800,8 @@ unsigned IOCTL_FDIOCGETFORMAT = FDIOCGETFORMAT;
unsigned IOCTL_FDIOCFORMAT_TRACK = FDIOCFORMAT_TRACK;
unsigned IOCTL_FIOCLEX = FIOCLEX;
unsigned IOCTL_FIONCLEX = FIONCLEX;
+unsigned IOCTL_FIOSEEKDATA = FIOSEEKDATA;
+unsigned IOCTL_FIOSEEKHOLE = FIOSEEKHOLE;
unsigned IOCTL_FIONREAD = FIONREAD;
unsigned IOCTL_FIONBIO = FIONBIO;
unsigned IOCTL_FIOASYNC = FIOASYNC;
@@ -1802,8 +1887,6 @@ unsigned IOCTL_MTIOCSLOCATE = MTIOCSLOCATE;
unsigned IOCTL_MTIOCHLOCATE = MTIOCHLOCATE;
unsigned IOCTL_POWER_EVENT_RECVDICT = POWER_EVENT_RECVDICT;
unsigned IOCTL_POWER_IOC_GET_TYPE = POWER_IOC_GET_TYPE;
-unsigned IOCTL_POWER_IOC_GET_TYPE_WITH_LOSSAGE =
- POWER_IOC_GET_TYPE_WITH_LOSSAGE;
unsigned IOCTL_RIOCGINFO = RIOCGINFO;
unsigned IOCTL_RIOCSINFO = RIOCSINFO;
unsigned IOCTL_RIOCSSRCH = RIOCSSRCH;
@@ -1838,6 +1921,7 @@ unsigned IOCTL_SIOCGLOWAT = SIOCGLOWAT;
unsigned IOCTL_SIOCATMARK = SIOCATMARK;
unsigned IOCTL_SIOCSPGRP = SIOCSPGRP;
unsigned IOCTL_SIOCGPGRP = SIOCGPGRP;
+unsigned IOCTL_SIOCPEELOFF = SIOCPEELOFF;
unsigned IOCTL_SIOCADDRT = SIOCADDRT;
unsigned IOCTL_SIOCDELRT = SIOCDELRT;
unsigned IOCTL_SIOCSIFADDR = SIOCSIFADDR;
@@ -1895,6 +1979,12 @@ unsigned IOCTL_SIOCGLINKSTR = SIOCGLINKSTR;
unsigned IOCTL_SIOCSLINKSTR = SIOCSLINKSTR;
unsigned IOCTL_SIOCGETHERCAP = SIOCGETHERCAP;
unsigned IOCTL_SIOCGIFINDEX = SIOCGIFINDEX;
+unsigned IOCTL_SIOCSETHERCAP = SIOCSETHERCAP;
+unsigned IOCTL_SIOCSIFDESCR = SIOCSIFDESCR;
+unsigned IOCTL_SIOCGIFDESCR = SIOCGIFDESCR;
+unsigned IOCTL_SIOCGUMBINFO = SIOCGUMBINFO;
+unsigned IOCTL_SIOCSUMBPARAM = SIOCSUMBPARAM;
+unsigned IOCTL_SIOCGUMBPARAM = SIOCGUMBPARAM;
unsigned IOCTL_SIOCSETPFSYNC = SIOCSETPFSYNC;
unsigned IOCTL_SIOCGETPFSYNC = SIOCGETPFSYNC;
unsigned IOCTL_PPS_IOC_CREATE = PPS_IOC_CREATE;
@@ -2016,6 +2106,19 @@ unsigned IOCTL_WDOGIOC_WHICH = WDOGIOC_WHICH;
unsigned IOCTL_WDOGIOC_TICKLE = WDOGIOC_TICKLE;
unsigned IOCTL_WDOGIOC_GTICKLER = WDOGIOC_GTICKLER;
unsigned IOCTL_WDOGIOC_GWDOGS = WDOGIOC_GWDOGS;
+unsigned IOCTL_KCOV_IOC_SETBUFSIZE = KCOV_IOC_SETBUFSIZE;
+unsigned IOCTL_KCOV_IOC_ENABLE = KCOV_IOC_ENABLE;
+unsigned IOCTL_KCOV_IOC_DISABLE = KCOV_IOC_DISABLE;
+unsigned IOCTL_IPMICTL_RECEIVE_MSG_TRUNC = IPMICTL_RECEIVE_MSG_TRUNC;
+unsigned IOCTL_IPMICTL_RECEIVE_MSG = IPMICTL_RECEIVE_MSG;
+unsigned IOCTL_IPMICTL_SEND_COMMAND = IPMICTL_SEND_COMMAND;
+unsigned IOCTL_IPMICTL_REGISTER_FOR_CMD = IPMICTL_REGISTER_FOR_CMD;
+unsigned IOCTL_IPMICTL_UNREGISTER_FOR_CMD = IPMICTL_UNREGISTER_FOR_CMD;
+unsigned IOCTL_IPMICTL_SET_GETS_EVENTS_CMD = IPMICTL_SET_GETS_EVENTS_CMD;
+unsigned IOCTL_IPMICTL_SET_MY_ADDRESS_CMD = IPMICTL_SET_MY_ADDRESS_CMD;
+unsigned IOCTL_IPMICTL_GET_MY_ADDRESS_CMD = IPMICTL_GET_MY_ADDRESS_CMD;
+unsigned IOCTL_IPMICTL_SET_MY_LUN_CMD = IPMICTL_SET_MY_LUN_CMD;
+unsigned IOCTL_IPMICTL_GET_MY_LUN_CMD = IPMICTL_GET_MY_LUN_CMD;
unsigned IOCTL_SNDCTL_DSP_RESET = SNDCTL_DSP_RESET;
unsigned IOCTL_SNDCTL_DSP_SYNC = SNDCTL_DSP_SYNC;
unsigned IOCTL_SNDCTL_DSP_SPEED = SNDCTL_DSP_SPEED;
@@ -2061,6 +2164,44 @@ unsigned IOCTL_SNDCTL_DSP_SILENCE = SNDCTL_DSP_SILENCE;
const int si_SEGV_MAPERR = SEGV_MAPERR;
const int si_SEGV_ACCERR = SEGV_ACCERR;
+
+const int modctl_load = MODCTL_LOAD;
+const int modctl_unload = MODCTL_UNLOAD;
+const int modctl_stat = MODCTL_STAT;
+const int modctl_exists = MODCTL_EXISTS;
+
+const unsigned SHA1_CTX_sz = sizeof(SHA1_CTX);
+const unsigned SHA1_return_length = SHA1_DIGEST_STRING_LENGTH;
+
+const unsigned MD4_CTX_sz = sizeof(MD4_CTX);
+const unsigned MD4_return_length = MD4_DIGEST_STRING_LENGTH;
+
+const unsigned RMD160_CTX_sz = sizeof(RMD160_CTX);
+const unsigned RMD160_return_length = RMD160_DIGEST_STRING_LENGTH;
+
+const unsigned MD5_CTX_sz = sizeof(MD5_CTX);
+const unsigned MD5_return_length = MD5_DIGEST_STRING_LENGTH;
+
+const unsigned fpos_t_sz = sizeof(fpos_t);
+
+const unsigned MD2_CTX_sz = sizeof(MD2_CTX);
+const unsigned MD2_return_length = MD2_DIGEST_STRING_LENGTH;
+
+#define SHA2_CONST(LEN) \
+ const unsigned SHA##LEN##_CTX_sz = sizeof(SHA##LEN##_CTX); \
+ const unsigned SHA##LEN##_return_length = SHA##LEN##_DIGEST_STRING_LENGTH; \
+ const unsigned SHA##LEN##_block_length = SHA##LEN##_BLOCK_LENGTH; \
+ const unsigned SHA##LEN##_digest_length = SHA##LEN##_DIGEST_LENGTH
+
+SHA2_CONST(224);
+SHA2_CONST(256);
+SHA2_CONST(384);
+SHA2_CONST(512);
+
+#undef SHA2_CONST
+
+const int unvis_valid = UNVIS_VALID;
+const int unvis_validpush = UNVIS_VALIDPUSH;
} // namespace __sanitizer
using namespace __sanitizer;
@@ -2151,6 +2292,29 @@ CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordc);
CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordv);
CHECK_SIZE_AND_OFFSET(wordexp_t, we_offs);
+COMPILER_CHECK(sizeof(__sanitizer_FILE) <= sizeof(FILE));
+CHECK_SIZE_AND_OFFSET(FILE, _p);
+CHECK_SIZE_AND_OFFSET(FILE, _r);
+CHECK_SIZE_AND_OFFSET(FILE, _w);
+CHECK_SIZE_AND_OFFSET(FILE, _flags);
+CHECK_SIZE_AND_OFFSET(FILE, _file);
+CHECK_SIZE_AND_OFFSET(FILE, _bf);
+CHECK_SIZE_AND_OFFSET(FILE, _lbfsize);
+CHECK_SIZE_AND_OFFSET(FILE, _cookie);
+CHECK_SIZE_AND_OFFSET(FILE, _close);
+CHECK_SIZE_AND_OFFSET(FILE, _read);
+CHECK_SIZE_AND_OFFSET(FILE, _seek);
+CHECK_SIZE_AND_OFFSET(FILE, _write);
+CHECK_SIZE_AND_OFFSET(FILE, _ext);
+CHECK_SIZE_AND_OFFSET(FILE, _up);
+CHECK_SIZE_AND_OFFSET(FILE, _ur);
+CHECK_SIZE_AND_OFFSET(FILE, _ubuf);
+CHECK_SIZE_AND_OFFSET(FILE, _nbuf);
+CHECK_SIZE_AND_OFFSET(FILE, _flush);
+CHECK_SIZE_AND_OFFSET(FILE, _lb_unused);
+CHECK_SIZE_AND_OFFSET(FILE, _blksize);
+CHECK_SIZE_AND_OFFSET(FILE, _offset);
+
CHECK_TYPE_SIZE(tm);
CHECK_SIZE_AND_OFFSET(tm, tm_sec);
CHECK_SIZE_AND_OFFSET(tm, tm_min);
@@ -2222,4 +2386,10 @@ CHECK_SIZE_AND_OFFSET(group, gr_passwd);
CHECK_SIZE_AND_OFFSET(group, gr_gid);
CHECK_SIZE_AND_OFFSET(group, gr_mem);
+CHECK_TYPE_SIZE(modctl_load_t);
+CHECK_SIZE_AND_OFFSET(modctl_load_t, ml_filename);
+CHECK_SIZE_AND_OFFSET(modctl_load_t, ml_flags);
+CHECK_SIZE_AND_OFFSET(modctl_load_t, ml_props);
+CHECK_SIZE_AND_OFFSET(modctl_load_t, ml_propslen);
+
#endif // SANITIZER_NETBSD
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h
index eddfc12..4fb3b8c 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h
@@ -1,7 +1,8 @@
//===-- sanitizer_platform_limits_netbsd.h --------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -23,10 +24,10 @@
#if defined(__x86_64__)
#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \
- _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 312)
+ _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 264)
#elif defined(__i386__)
#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \
- _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 164)
+ _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 136)
#endif
namespace __sanitizer {
@@ -58,6 +59,29 @@ extern unsigned struct_timespec_sz;
extern unsigned struct_sembuf_sz;
extern unsigned struct_kevent_sz;
+extern unsigned struct_FTS_sz;
+extern unsigned struct_FTSENT_sz;
+
+extern unsigned struct_regex_sz;
+extern unsigned struct_regmatch_sz;
+
+extern unsigned struct_fstab_sz;
+
+struct __sanitizer_regmatch {
+ OFF_T rm_so;
+ OFF_T rm_eo;
+};
+
+typedef struct __sanitizer_modctl_load {
+ const char *ml_filename;
+ int ml_flags;
+ const char *ml_props;
+ uptr ml_propslen;
+} __sanitizer_modctl_load_t;
+extern const int modctl_load;
+extern const int modctl_unload;
+extern const int modctl_stat;
+extern const int modctl_exists;
union __sanitizer_sigval {
int sival_int;
@@ -423,8 +447,36 @@ struct __sanitizer_wordexp_t {
uptr we_nbytes;
};
-typedef char __sanitizer_FILE;
-#define SANITIZER_HAS_STRUCT_FILE 0
+struct __sanitizer_FILE {
+ unsigned char *_p;
+ int _r;
+ int _w;
+ unsigned short _flags;
+ short _file;
+ struct {
+ unsigned char *_base;
+ int _size;
+ } _bf;
+ int _lbfsize;
+ void *_cookie;
+ int (*_close)(void *ptr);
+ u64 (*_read)(void *, void *, uptr);
+ u64 (*_seek)(void *, u64, int);
+ uptr (*_write)(void *, const void *, uptr);
+ struct {
+ unsigned char *_base;
+ int _size;
+ } _ext;
+ unsigned char *_up;
+ int _ur;
+ unsigned char _ubuf[3];
+ unsigned char _nbuf[1];
+ int (*_flush)(void *ptr);
+ char _lb_unused[sizeof(uptr)];
+ int _blksize;
+ u64 _offset;
+};
+#define SANITIZER_HAS_STRUCT_FILE 1
extern int shmctl_ipc_stat;
@@ -458,6 +510,8 @@ struct __sanitizer_ttyent {
char *ty_class;
};
+extern const unsigned long __sanitizer_bufsiz;
+
#define IOC_NRBITS 8
#define IOC_TYPEBITS 8
#define IOC_SIZEBITS 14
@@ -494,7 +548,6 @@ extern unsigned struct_atabusiodetach_args_sz;
extern unsigned struct_atabusioscan_args_sz;
extern unsigned struct_ath_diag_sz;
extern unsigned struct_atm_flowmap_sz;
-extern unsigned struct_atm_pseudoioctl_sz;
extern unsigned struct_audio_buf_info_sz;
extern unsigned struct_audio_device_sz;
extern unsigned struct_audio_encoding_sz;
@@ -749,7 +802,6 @@ extern unsigned struct_rf_recon_req_sz;
extern unsigned struct_rio_conf_sz;
extern unsigned struct_rio_interface_sz;
extern unsigned struct_rio_stats_sz;
-extern unsigned struct_satlink_id_sz;
extern unsigned struct_scan_io_sz;
extern unsigned struct_scbusaccel_args_sz;
extern unsigned struct_scbusiodetach_args_sz;
@@ -797,6 +849,28 @@ extern unsigned struct_usb_config_desc_sz;
extern unsigned struct_usb_ctl_report_desc_sz;
extern unsigned struct_usb_ctl_report_sz;
extern unsigned struct_usb_ctl_request_sz;
+#if defined(__x86_64__)
+extern unsigned struct_nvmm_ioc_capability_sz;
+extern unsigned struct_nvmm_ioc_machine_create_sz;
+extern unsigned struct_nvmm_ioc_machine_destroy_sz;
+extern unsigned struct_nvmm_ioc_machine_configure_sz;
+extern unsigned struct_nvmm_ioc_vcpu_create_sz;
+extern unsigned struct_nvmm_ioc_vcpu_destroy_sz;
+extern unsigned struct_nvmm_ioc_vcpu_setstate_sz;
+extern unsigned struct_nvmm_ioc_vcpu_getstate_sz;
+extern unsigned struct_nvmm_ioc_vcpu_inject_sz;
+extern unsigned struct_nvmm_ioc_vcpu_run_sz;
+extern unsigned struct_nvmm_ioc_gpa_map_sz;
+extern unsigned struct_nvmm_ioc_gpa_unmap_sz;
+extern unsigned struct_nvmm_ioc_hva_map_sz;
+extern unsigned struct_nvmm_ioc_hva_unmap_sz;
+extern unsigned struct_nvmm_ioc_ctl_sz;
+#endif
+extern unsigned struct_spi_ioctl_configure_sz;
+extern unsigned struct_spi_ioctl_transfer_sz;
+extern unsigned struct_autofs_daemon_request_sz;
+extern unsigned struct_autofs_daemon_done_sz;
+extern unsigned struct_sctp_connectx_addrs_sz;
extern unsigned struct_usb_device_info_old_sz;
extern unsigned struct_usb_device_info_sz;
extern unsigned struct_usb_device_stats_sz;
@@ -836,6 +910,9 @@ extern unsigned struct_vnd_user_sz;
extern unsigned struct_vt_stat_sz;
extern unsigned struct_wdog_conf_sz;
extern unsigned struct_wdog_mode_sz;
+extern unsigned struct_ipmi_recv_sz;
+extern unsigned struct_ipmi_req_sz;
+extern unsigned struct_ipmi_cmdspec_sz;
extern unsigned struct_wfq_conf_sz;
extern unsigned struct_wfq_getqid_sz;
extern unsigned struct_wfq_getstats_sz;
@@ -914,6 +991,7 @@ extern unsigned struct_iscsi_wait_event_parameters_sz;
extern unsigned struct_isp_stats_sz;
extern unsigned struct_lsenable_sz;
extern unsigned struct_lsdisable_sz;
+extern unsigned struct_audio_format_query_sz;
extern unsigned struct_mixer_ctrl_sz;
extern unsigned struct_mixer_devinfo_sz;
extern unsigned struct_mpu_command_rec_sz;
@@ -931,6 +1009,8 @@ extern unsigned struct_RF_SparetWait_sz;
extern unsigned struct_RF_ComponentLabel_sz;
extern unsigned struct_RF_SingleComponent_sz;
extern unsigned struct_RF_ProgressInfo_sz;
+extern unsigned struct_nvlist_ref_sz;
+extern unsigned struct_StringList_sz;
// A special value to mark ioctls that are not present on the target platform,
@@ -1199,6 +1279,7 @@ extern unsigned IOCTL_MLX_REBUILDSTAT;
extern unsigned IOCTL_MLX_GET_SYSDRIVE;
extern unsigned IOCTL_MLX_GET_CINFO;
extern unsigned IOCTL_NVME_PASSTHROUGH_CMD;
+extern unsigned IOCTL_FWCFGIO_SET_INDEX;
extern unsigned IOCTL_IRDA_RESET_PARAMS;
extern unsigned IOCTL_IRDA_SET_PARAMS;
extern unsigned IOCTL_IRDA_GET_SPEEDMASK;
@@ -1206,9 +1287,6 @@ extern unsigned IOCTL_IRDA_GET_TURNAROUNDMASK;
extern unsigned IOCTL_IRFRAMETTY_GET_DEVICE;
extern unsigned IOCTL_IRFRAMETTY_GET_DONGLE;
extern unsigned IOCTL_IRFRAMETTY_SET_DONGLE;
-extern unsigned IOCTL_SATIORESET;
-extern unsigned IOCTL_SATIOGID;
-extern unsigned IOCTL_SATIOSBUFSIZE;
extern unsigned IOCTL_ISV_CMD;
extern unsigned IOCTL_WTQICMD;
extern unsigned IOCTL_ISCSI_GET_VERSION;
@@ -1520,6 +1598,25 @@ extern unsigned IOCTL_SPKRTONE;
extern unsigned IOCTL_SPKRTUNE;
extern unsigned IOCTL_SPKRGETVOL;
extern unsigned IOCTL_SPKRSETVOL;
+#if defined(__x86_64__)
+extern unsigned IOCTL_NVMM_IOC_CAPABILITY;
+extern unsigned IOCTL_NVMM_IOC_MACHINE_CREATE;
+extern unsigned IOCTL_NVMM_IOC_MACHINE_DESTROY;
+extern unsigned IOCTL_NVMM_IOC_MACHINE_CONFIGURE;
+extern unsigned IOCTL_NVMM_IOC_VCPU_CREATE;
+extern unsigned IOCTL_NVMM_IOC_VCPU_DESTROY;
+extern unsigned IOCTL_NVMM_IOC_VCPU_SETSTATE;
+extern unsigned IOCTL_NVMM_IOC_VCPU_GETSTATE;
+extern unsigned IOCTL_NVMM_IOC_VCPU_INJECT;
+extern unsigned IOCTL_NVMM_IOC_VCPU_RUN;
+extern unsigned IOCTL_NVMM_IOC_GPA_MAP;
+extern unsigned IOCTL_NVMM_IOC_GPA_UNMAP;
+extern unsigned IOCTL_NVMM_IOC_HVA_MAP;
+extern unsigned IOCTL_NVMM_IOC_HVA_UNMAP;
+extern unsigned IOCTL_NVMM_IOC_CTL;
+#endif
+extern unsigned IOCTL_AUTOFSREQUEST;
+extern unsigned IOCTL_AUTOFSDONE;
extern unsigned IOCTL_BIOCGBLEN;
extern unsigned IOCTL_BIOCSBLEN;
extern unsigned IOCTL_BIOCSETF;
@@ -1538,19 +1635,12 @@ extern unsigned IOCTL_BIOCGHDRCMPLT;
extern unsigned IOCTL_BIOCSHDRCMPLT;
extern unsigned IOCTL_BIOCSDLT;
extern unsigned IOCTL_BIOCGDLTLIST;
-extern unsigned IOCTL_BIOCGSEESENT;
-extern unsigned IOCTL_BIOCSSEESENT;
+extern unsigned IOCTL_BIOCGDIRECTION;
+extern unsigned IOCTL_BIOCSDIRECTION;
extern unsigned IOCTL_BIOCSRTIMEOUT;
extern unsigned IOCTL_BIOCGRTIMEOUT;
extern unsigned IOCTL_BIOCGFEEDBACK;
extern unsigned IOCTL_BIOCSFEEDBACK;
-extern unsigned IOCTL_SIOCRAWATM;
-extern unsigned IOCTL_SIOCATMENA;
-extern unsigned IOCTL_SIOCATMDIS;
-extern unsigned IOCTL_SIOCSPVCTX;
-extern unsigned IOCTL_SIOCGPVCTX;
-extern unsigned IOCTL_SIOCSPVCSIF;
-extern unsigned IOCTL_SIOCGPVCSIF;
extern unsigned IOCTL_GRESADDRS;
extern unsigned IOCTL_GRESADDRD;
extern unsigned IOCTL_GREGADDRS;
@@ -1705,6 +1795,8 @@ extern unsigned IOCTL_SIOCRMNAT;
extern unsigned IOCTL_SIOCGNATS;
extern unsigned IOCTL_SIOCGNATL;
extern unsigned IOCTL_SIOCPURGENAT;
+extern unsigned IOCTL_SIOCCONNECTX;
+extern unsigned IOCTL_SIOCCONNECTXDEL;
extern unsigned IOCTL_SIOCSIFINFO_FLAGS;
extern unsigned IOCTL_SIOCAADDRCTL_POLICY;
extern unsigned IOCTL_SIOCDADDRCTL_POLICY;
@@ -1740,6 +1832,9 @@ extern unsigned IOCTL_AUDIO_GETPROPS;
extern unsigned IOCTL_AUDIO_GETBUFINFO;
extern unsigned IOCTL_AUDIO_SETCHAN;
extern unsigned IOCTL_AUDIO_GETCHAN;
+extern unsigned IOCTL_AUDIO_QUERYFORMAT;
+extern unsigned IOCTL_AUDIO_GETFORMAT;
+extern unsigned IOCTL_AUDIO_SETFORMAT;
extern unsigned IOCTL_AUDIO_MIXER_READ;
extern unsigned IOCTL_AUDIO_MIXER_WRITE;
extern unsigned IOCTL_AUDIO_MIXER_DEVINFO;
@@ -1825,6 +1920,7 @@ extern unsigned IOCTL_DIOCTUR;
extern unsigned IOCTL_DIOCMWEDGES;
extern unsigned IOCTL_DIOCGSECTORSIZE;
extern unsigned IOCTL_DIOCGMEDIASIZE;
+extern unsigned IOCTL_DIOCRMWEDGES;
extern unsigned IOCTL_DRVDETACHDEV;
extern unsigned IOCTL_DRVRESCANBUS;
extern unsigned IOCTL_DRVCTLCOMMAND;
@@ -1849,6 +1945,8 @@ extern unsigned IOCTL_FDIOCGETFORMAT;
extern unsigned IOCTL_FDIOCFORMAT_TRACK;
extern unsigned IOCTL_FIOCLEX;
extern unsigned IOCTL_FIONCLEX;
+extern unsigned IOCTL_FIOSEEKDATA;
+extern unsigned IOCTL_FIOSEEKHOLE;
extern unsigned IOCTL_FIONREAD;
extern unsigned IOCTL_FIONBIO;
extern unsigned IOCTL_FIOASYNC;
@@ -1924,6 +2022,8 @@ extern unsigned IOCTL_SEQUENCER_TMR_TEMPO;
extern unsigned IOCTL_SEQUENCER_TMR_SOURCE;
extern unsigned IOCTL_SEQUENCER_TMR_METRONOME;
extern unsigned IOCTL_SEQUENCER_TMR_SELECT;
+extern unsigned IOCTL_SPI_IOCTL_CONFIGURE;
+extern unsigned IOCTL_SPI_IOCTL_TRANSFER;
extern unsigned IOCTL_MTIOCTOP;
extern unsigned IOCTL_MTIOCGET;
extern unsigned IOCTL_MTIOCIEOT;
@@ -1934,7 +2034,6 @@ extern unsigned IOCTL_MTIOCSLOCATE;
extern unsigned IOCTL_MTIOCHLOCATE;
extern unsigned IOCTL_POWER_EVENT_RECVDICT;
extern unsigned IOCTL_POWER_IOC_GET_TYPE;
-extern unsigned IOCTL_POWER_IOC_GET_TYPE_WITH_LOSSAGE;
extern unsigned IOCTL_RIOCGINFO;
extern unsigned IOCTL_RIOCSINFO;
extern unsigned IOCTL_RIOCSSRCH;
@@ -1969,6 +2068,7 @@ extern unsigned IOCTL_SIOCGLOWAT;
extern unsigned IOCTL_SIOCATMARK;
extern unsigned IOCTL_SIOCSPGRP;
extern unsigned IOCTL_SIOCGPGRP;
+extern unsigned IOCTL_SIOCPEELOFF;
extern unsigned IOCTL_SIOCADDRT;
extern unsigned IOCTL_SIOCDELRT;
extern unsigned IOCTL_SIOCSIFADDR;
@@ -2026,6 +2126,12 @@ extern unsigned IOCTL_SIOCGLINKSTR;
extern unsigned IOCTL_SIOCSLINKSTR;
extern unsigned IOCTL_SIOCGETHERCAP;
extern unsigned IOCTL_SIOCGIFINDEX;
+extern unsigned IOCTL_SIOCSETHERCAP;
+extern unsigned IOCTL_SIOCSIFDESCR;
+extern unsigned IOCTL_SIOCGIFDESCR;
+extern unsigned IOCTL_SIOCGUMBINFO;
+extern unsigned IOCTL_SIOCSUMBPARAM;
+extern unsigned IOCTL_SIOCGUMBPARAM;
extern unsigned IOCTL_SIOCSETPFSYNC;
extern unsigned IOCTL_SIOCGETPFSYNC;
extern unsigned IOCTL_PPS_IOC_CREATE;
@@ -2147,6 +2253,19 @@ extern unsigned IOCTL_WDOGIOC_WHICH;
extern unsigned IOCTL_WDOGIOC_TICKLE;
extern unsigned IOCTL_WDOGIOC_GTICKLER;
extern unsigned IOCTL_WDOGIOC_GWDOGS;
+extern unsigned IOCTL_KCOV_IOC_SETBUFSIZE;
+extern unsigned IOCTL_KCOV_IOC_ENABLE;
+extern unsigned IOCTL_KCOV_IOC_DISABLE;
+extern unsigned IOCTL_IPMICTL_RECEIVE_MSG_TRUNC;
+extern unsigned IOCTL_IPMICTL_RECEIVE_MSG;
+extern unsigned IOCTL_IPMICTL_SEND_COMMAND;
+extern unsigned IOCTL_IPMICTL_REGISTER_FOR_CMD;
+extern unsigned IOCTL_IPMICTL_UNREGISTER_FOR_CMD;
+extern unsigned IOCTL_IPMICTL_SET_GETS_EVENTS_CMD;
+extern unsigned IOCTL_IPMICTL_SET_MY_ADDRESS_CMD;
+extern unsigned IOCTL_IPMICTL_GET_MY_ADDRESS_CMD;
+extern unsigned IOCTL_IPMICTL_SET_MY_LUN_CMD;
+extern unsigned IOCTL_IPMICTL_GET_MY_LUN_CMD;
extern unsigned IOCTL_SNDCTL_DSP_RESET;
extern unsigned IOCTL_SNDCTL_DSP_SYNC;
extern unsigned IOCTL_SNDCTL_DSP_SPEED;
@@ -2192,6 +2311,74 @@ extern unsigned IOCTL_SNDCTL_DSP_SILENCE;
extern const int si_SEGV_MAPERR;
extern const int si_SEGV_ACCERR;
+
+extern const unsigned SHA1_CTX_sz;
+extern const unsigned SHA1_return_length;
+
+extern const unsigned MD4_CTX_sz;
+extern const unsigned MD4_return_length;
+
+extern const unsigned RMD160_CTX_sz;
+extern const unsigned RMD160_return_length;
+
+extern const unsigned MD5_CTX_sz;
+extern const unsigned MD5_return_length;
+
+extern const unsigned fpos_t_sz;
+
+extern const unsigned MD2_CTX_sz;
+extern const unsigned MD2_return_length;
+
+#define SHA2_EXTERN(LEN) \
+ extern const unsigned SHA##LEN##_CTX_sz; \
+ extern const unsigned SHA##LEN##_return_length; \
+ extern const unsigned SHA##LEN##_block_length; \
+ extern const unsigned SHA##LEN##_digest_length
+
+SHA2_EXTERN(224);
+SHA2_EXTERN(256);
+SHA2_EXTERN(384);
+SHA2_EXTERN(512);
+
+#undef SHA2_EXTERN
+
+extern const int unvis_valid;
+extern const int unvis_validpush;
+
+struct __sanitizer_cdbr {
+ void (*unmap)(void *, void *, uptr);
+ void *cookie;
+ u8 *mmap_base;
+ uptr mmap_size;
+
+ u8 *hash_base;
+ u8 *offset_base;
+ u8 *data_base;
+
+ u32 data_size;
+ u32 entries;
+ u32 entries_index;
+ u32 seed;
+
+ u8 offset_size;
+ u8 index_size;
+
+ u32 entries_m;
+ u32 entries_index_m;
+ u8 entries_s1, entries_s2;
+ u8 entries_index_s1, entries_index_s2;
+};
+
+struct __sanitizer_cdbw {
+ uptr data_counter;
+ uptr data_allocated;
+ uptr data_size;
+ uptr *data_len;
+ void **data_ptr;
+ uptr hash_size;
+ void *hash;
+ uptr key_counter;
+};
} // namespace __sanitizer
#define CHECK_TYPE_SIZE(TYPE) \
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cpp
index e114ff4..1251562 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_platform_limits_openbsd.cc ------------------------------===//
+//===-- sanitizer_platform_limits_openbsd.cpp -----------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h
index 8f21de7..6d8b062 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h
@@ -1,7 +1,8 @@
//===-- sanitizer_platform_limits_openbsd.h -------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp
index 6cd4a5b..7f1132c 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_platform_limits_posix.cc --------------------------------===//
+//===-- sanitizer_platform_limits_posix.cpp -------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -12,7 +13,7 @@
#include "sanitizer_platform.h"
-#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_MAC
+#if SANITIZER_LINUX || SANITIZER_MAC
// Tests in this file assume that off_t-dependent data structures match the
// libc ABI. For example, struct dirent here is what readdir() function (as
// exported from libc) returns, and not the user-facing "dirent", which
@@ -43,7 +44,8 @@
#include <termios.h>
#include <time.h>
#include <wchar.h>
-#if !SANITIZER_MAC && !SANITIZER_FREEBSD
+#include <regex.h>
+#if !SANITIZER_MAC
#include <utmp.h>
#endif
@@ -52,6 +54,7 @@
#endif
#if !SANITIZER_ANDROID
+#include <fstab.h>
#include <sys/mount.h>
#include <sys/timeb.h>
#include <utmpx.h>
@@ -76,43 +79,11 @@
#include <net/if_arp.h>
#endif
-#if SANITIZER_FREEBSD
-# include <sys/mount.h>
-# include <sys/sockio.h>
-# include <sys/socket.h>
-# include <sys/filio.h>
-# include <sys/signal.h>
-# include <sys/timespec.h>
-# include <sys/timex.h>
-# include <sys/mqueue.h>
-# include <sys/msg.h>
-# include <sys/ipc.h>
-# include <sys/msg.h>
-# include <sys/statvfs.h>
-# include <sys/soundcard.h>
-# include <sys/mtio.h>
-# include <sys/consio.h>
-# include <sys/kbio.h>
-# include <sys/link_elf.h>
-# include <netinet/ip_mroute.h>
-# include <netinet/in.h>
-# include <net/ethernet.h>
-# include <net/ppp_defs.h>
-# include <glob.h>
-# include <term.h>
-
-#define _KERNEL // to declare 'shminfo' structure
-# include <sys/shm.h>
-#undef _KERNEL
-
-#undef INLINE // to avoid clashes with sanitizers' definitions
-#endif
-
-#if SANITIZER_FREEBSD || SANITIZER_IOS
+#if SANITIZER_IOS
#undef IOC_DIRMASK
#endif
-#if SANITIZER_LINUX || SANITIZER_FREEBSD
+#if SANITIZER_LINUX
# include <utime.h>
# include <sys/ptrace.h>
# if defined(__mips64) || defined(__aarch64__) || defined(__arm__)
@@ -144,8 +115,6 @@ typedef struct user_fpregs elf_fpregset_t;
#include <netrom/netrom.h>
#if HAVE_RPC_XDR_H
# include <rpc/xdr.h>
-#elif HAVE_TIRPC_RPC_XDR_H
-# include <tirpc/rpc/xdr.h>
#endif
#include <scsi/scsi.h>
#include <sys/mtio.h>
@@ -196,9 +165,9 @@ typedef struct user_fpregs elf_fpregset_t;
namespace __sanitizer {
unsigned struct_utsname_sz = sizeof(struct utsname);
unsigned struct_stat_sz = sizeof(struct stat);
-#if !SANITIZER_IOS && !SANITIZER_FREEBSD
+#if !SANITIZER_IOS
unsigned struct_stat64_sz = sizeof(struct stat64);
-#endif // !SANITIZER_IOS && !SANITIZER_FREEBSD
+#endif // !SANITIZER_IOS
unsigned struct_rusage_sz = sizeof(struct rusage);
unsigned struct_tm_sz = sizeof(struct tm);
unsigned struct_passwd_sz = sizeof(struct passwd);
@@ -219,13 +188,15 @@ namespace __sanitizer {
unsigned struct_tms_sz = sizeof(struct tms);
unsigned struct_sigevent_sz = sizeof(struct sigevent);
unsigned struct_sched_param_sz = sizeof(struct sched_param);
-
+ unsigned struct_regex_sz = sizeof(regex_t);
+ unsigned struct_regmatch_sz = sizeof(regmatch_t);
#if SANITIZER_MAC && !SANITIZER_IOS
unsigned struct_statfs64_sz = sizeof(struct statfs64);
#endif // SANITIZER_MAC && !SANITIZER_IOS
#if !SANITIZER_ANDROID
+ unsigned struct_fstab_sz = sizeof(struct fstab);
unsigned struct_statfs_sz = sizeof(struct statfs);
unsigned struct_sockaddr_sz = sizeof(struct sockaddr);
unsigned ucontext_t_sz = sizeof(ucontext_t);
@@ -242,12 +213,12 @@ namespace __sanitizer {
unsigned struct_oldold_utsname_sz = sizeof(struct oldold_utsname);
#endif // SANITIZER_LINUX
-#if SANITIZER_LINUX || SANITIZER_FREEBSD
+#if SANITIZER_LINUX
unsigned struct_rlimit_sz = sizeof(struct rlimit);
unsigned struct_timespec_sz = sizeof(struct timespec);
unsigned struct_utimbuf_sz = sizeof(struct utimbuf);
unsigned struct_itimerspec_sz = sizeof(struct itimerspec);
-#endif // SANITIZER_LINUX || SANITIZER_FREEBSD
+#endif // SANITIZER_LINUX
#if SANITIZER_LINUX && !SANITIZER_ANDROID
// Use pre-computed size of struct ustat to avoid <sys/ustat.h> which
@@ -267,12 +238,12 @@ namespace __sanitizer {
unsigned struct_statvfs64_sz = sizeof(struct statvfs64);
#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
-#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
+#if SANITIZER_LINUX && !SANITIZER_ANDROID
unsigned struct_timex_sz = sizeof(struct timex);
unsigned struct_msqid_ds_sz = sizeof(struct msqid_ds);
unsigned struct_mq_attr_sz = sizeof(struct mq_attr);
unsigned struct_statvfs_sz = sizeof(struct statvfs);
-#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
+#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
const uptr sig_ign = (uptr)SIG_IGN;
const uptr sig_dfl = (uptr)SIG_DFL;
@@ -284,7 +255,7 @@ namespace __sanitizer {
#endif
-#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
+#if SANITIZER_LINUX && !SANITIZER_ANDROID
unsigned struct_shminfo_sz = sizeof(struct shminfo);
unsigned struct_shm_info_sz = sizeof(struct shm_info);
int shmctl_ipc_stat = (int)IPC_STAT;
@@ -320,7 +291,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(ElfW(Phdr));
unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
#endif
-#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
+#if SANITIZER_LINUX && !SANITIZER_ANDROID
int glob_nomatch = GLOB_NOMATCH;
int glob_altdirfunc = GLOB_ALTDIRFUNC;
#endif
@@ -445,7 +416,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
unsigned struct_vt_stat_sz = sizeof(struct vt_stat);
#endif // SANITIZER_LINUX
-#if SANITIZER_LINUX || SANITIZER_FREEBSD
+#if SANITIZER_LINUX
#if SOUND_VERSION >= 0x040000
unsigned struct_copr_buffer_sz = 0;
unsigned struct_copr_debug_buf_sz = 0;
@@ -462,7 +433,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
unsigned struct_seq_event_rec_sz = sizeof(struct seq_event_rec);
unsigned struct_synth_info_sz = sizeof(struct synth_info);
unsigned struct_vt_mode_sz = sizeof(struct vt_mode);
-#endif // SANITIZER_LINUX || SANITIZER_FREEBSD
+#endif // SANITIZER_LINUX
#if SANITIZER_LINUX && !SANITIZER_ANDROID
unsigned struct_ax25_parms_struct_sz = sizeof(struct ax25_parms_struct);
@@ -489,7 +460,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
unsigned struct_unimapinit_sz = sizeof(struct unimapinit);
#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
-#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
+#if SANITIZER_LINUX && !SANITIZER_ANDROID
unsigned struct_audio_buf_info_sz = sizeof(struct audio_buf_info);
unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats);
#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
@@ -499,6 +470,8 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req);
#endif
+ const unsigned long __sanitizer_bufsiz = BUFSIZ;
+
const unsigned IOCTL_NOT_PRESENT = 0;
unsigned IOCTL_FIOASYNC = FIOASYNC;
@@ -545,7 +518,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
unsigned IOCTL_TIOCSPGRP = TIOCSPGRP;
unsigned IOCTL_TIOCSTI = TIOCSTI;
unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ;
-#if ((SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID)
+#if SANITIZER_LINUX && !SANITIZER_ANDROID
unsigned IOCTL_SIOCGETSGCNT = SIOCGETSGCNT;
unsigned IOCTL_SIOCGETVIFCNT = SIOCGETVIFCNT;
#endif
@@ -735,9 +708,6 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
unsigned IOCTL_VT_RESIZE = VT_RESIZE;
unsigned IOCTL_VT_RESIZEX = VT_RESIZEX;
unsigned IOCTL_VT_SENDSIG = VT_SENDSIG;
-#endif // SANITIZER_LINUX
-
-#if SANITIZER_LINUX || SANITIZER_FREEBSD
unsigned IOCTL_MTIOCGET = MTIOCGET;
unsigned IOCTL_MTIOCTOP = MTIOCTOP;
unsigned IOCTL_SNDCTL_DSP_GETBLKSIZE = SNDCTL_DSP_GETBLKSIZE;
@@ -830,7 +800,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
unsigned IOCTL_VT_RELDISP = VT_RELDISP;
unsigned IOCTL_VT_SETMODE = VT_SETMODE;
unsigned IOCTL_VT_WAITACTIVE = VT_WAITACTIVE;
-#endif // SANITIZER_LINUX || SANITIZER_FREEBSD
+#endif // SANITIZER_LINUX
#if SANITIZER_LINUX && !SANITIZER_ANDROID
unsigned IOCTL_CYGETDEFTHRESH = CYGETDEFTHRESH;
@@ -923,7 +893,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
unsigned IOCTL_TIOCSSERIAL = TIOCSSERIAL;
#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
-#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
+#if SANITIZER_LINUX && !SANITIZER_ANDROID
unsigned IOCTL_GIO_SCRNMAP = GIO_SCRNMAP;
unsigned IOCTL_KDDISABIO = KDDISABIO;
unsigned IOCTL_KDENABIO = KDENABIO;
@@ -1241,7 +1211,7 @@ CHECK_SIZE_AND_OFFSET(group, gr_passwd);
CHECK_SIZE_AND_OFFSET(group, gr_gid);
CHECK_SIZE_AND_OFFSET(group, gr_mem);
-#if HAVE_RPC_XDR_H || HAVE_TIRPC_RPC_XDR_H
+#if HAVE_RPC_XDR_H
CHECK_TYPE_SIZE(XDR);
CHECK_SIZE_AND_OFFSET(XDR, x_op);
CHECK_SIZE_AND_OFFSET(XDR, x_ops);
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
index 73af92a..f2d4812 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -1,7 +1,8 @@
//===-- sanitizer_platform_limits_posix.h ---------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -13,22 +14,12 @@
#ifndef SANITIZER_PLATFORM_LIMITS_POSIX_H
#define SANITIZER_PLATFORM_LIMITS_POSIX_H
-#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC
+#if SANITIZER_LINUX || SANITIZER_MAC
#include "sanitizer_internal_defs.h"
#include "sanitizer_platform.h"
-#if SANITIZER_FREEBSD
-// FreeBSD's dlopen() returns a pointer to an Obj_Entry structure that
-// incorporates the map structure.
-# define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \
- ((link_map*)((handle) == nullptr ? nullptr : ((char*)(handle) + 560)))
-// Get sys/_types.h, because that tells us whether 64-bit inodes are
-// used in struct dirent below.
-#include <sys/_types.h>
-#else
# define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) ((link_map*)(handle))
-#endif // !SANITIZER_FREEBSD
#ifndef __GLIBC_PREREQ
#define __GLIBC_PREREQ(x, y) 0
@@ -37,7 +28,7 @@
namespace __sanitizer {
extern unsigned struct_utsname_sz;
extern unsigned struct_stat_sz;
-#if !SANITIZER_FREEBSD && !SANITIZER_IOS
+#if !SANITIZER_IOS
extern unsigned struct_stat64_sz;
#endif
extern unsigned struct_rusage_sz;
@@ -57,8 +48,11 @@ namespace __sanitizer {
extern unsigned struct_sigevent_sz;
extern unsigned struct_sched_param_sz;
extern unsigned struct_statfs64_sz;
+ extern unsigned struct_regex_sz;
+ extern unsigned struct_regmatch_sz;
#if !SANITIZER_ANDROID
+ extern unsigned struct_fstab_sz;
extern unsigned struct_statfs_sz;
extern unsigned struct_sockaddr_sz;
extern unsigned ucontext_t_sz;
@@ -121,7 +115,7 @@ namespace __sanitizer {
const unsigned struct_kexec_segment_sz = 4 * sizeof(unsigned long);
#endif // SANITIZER_LINUX
-#if SANITIZER_LINUX || SANITIZER_FREEBSD
+#if SANITIZER_LINUX
#if defined(__powerpc64__) || defined(__s390__)
const unsigned struct___old_kernel_stat_sz = 0;
@@ -178,11 +172,9 @@ namespace __sanitizer {
int data;
#elif SANITIZER_LINUX
uptr data[4];
-#elif SANITIZER_FREEBSD
- u32 data[4];
#endif
};
-#endif // SANITIZER_LINUX || SANITIZER_FREEBSD
+#endif // SANITIZER_LINUX
#if SANITIZER_ANDROID
struct __sanitizer_struct_mallinfo {
@@ -304,35 +296,14 @@ namespace __sanitizer {
#endif
#endif
};
-#elif SANITIZER_FREEBSD
- struct __sanitizer_ipc_perm {
- unsigned int cuid;
- unsigned int cgid;
- unsigned int uid;
- unsigned int gid;
- unsigned short mode;
- unsigned short seq;
- long key;
- };
-
- struct __sanitizer_shmid_ds {
- __sanitizer_ipc_perm shm_perm;
- unsigned long shm_segsz;
- unsigned int shm_lpid;
- unsigned int shm_cpid;
- int shm_nattch;
- unsigned long shm_atime;
- unsigned long shm_dtime;
- unsigned long shm_ctime;
- };
#endif
-#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
+#if SANITIZER_LINUX && !SANITIZER_ANDROID
extern unsigned struct_msqid_ds_sz;
extern unsigned struct_mq_attr_sz;
extern unsigned struct_timex_sz;
extern unsigned struct_statvfs_sz;
-#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
+#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
struct __sanitizer_iovec {
void *iov_base;
@@ -382,7 +353,7 @@ namespace __sanitizer {
char *pw_passwd;
int pw_uid;
int pw_gid;
-#if SANITIZER_MAC || SANITIZER_FREEBSD
+#if SANITIZER_MAC
long pw_change;
char *pw_class;
#endif
@@ -391,12 +362,9 @@ namespace __sanitizer {
#endif
char *pw_dir;
char *pw_shell;
-#if SANITIZER_MAC || SANITIZER_FREEBSD
+#if SANITIZER_MAC
long pw_expire;
#endif
-#if SANITIZER_FREEBSD
- int pw_fields;
-#endif
};
struct __sanitizer_group {
@@ -466,7 +434,7 @@ namespace __sanitizer {
};
#endif
-#if SANITIZER_MAC || SANITIZER_FREEBSD
+#if SANITIZER_MAC
struct __sanitizer_msghdr {
void *msg_name;
unsigned msg_namelen;
@@ -512,17 +480,6 @@ namespace __sanitizer {
unsigned short d_reclen;
// more fields that we don't care about
};
-#elif SANITIZER_FREEBSD
- struct __sanitizer_dirent {
-#if defined(__INO64)
- unsigned long long d_fileno;
- unsigned long long d_off;
-#else
- unsigned int d_fileno;
-#endif
- unsigned short d_reclen;
- // more fields that we don't care about
- };
#elif SANITIZER_ANDROID || defined(__x86_64__)
struct __sanitizer_dirent {
unsigned long long d_ino;
@@ -548,20 +505,17 @@ namespace __sanitizer {
};
#endif
-// 'clock_t' is 32 bits wide on x64 FreeBSD
-#if SANITIZER_FREEBSD
- typedef int __sanitizer_clock_t;
-#elif defined(__x86_64__) && !defined(_LP64)
+#if defined(__x86_64__) && !defined(_LP64)
typedef long long __sanitizer_clock_t;
#else
typedef long __sanitizer_clock_t;
#endif
-#if SANITIZER_LINUX || SANITIZER_FREEBSD
+#if SANITIZER_LINUX
typedef int __sanitizer_clockid_t;
#endif
-#if SANITIZER_LINUX || SANITIZER_FREEBSD
+#if SANITIZER_LINUX
#if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__)\
|| defined(__mips__)
typedef unsigned __sanitizer___kernel_uid_t;
@@ -591,7 +545,7 @@ namespace __sanitizer {
#endif
// This thing depends on the platform. We are only interested in the upper
- // limit. Verified with a compiler assert in .cc.
+ // limit. Verified with a compiler assert in .cpp.
const int pthread_attr_t_max_sz = 128;
union __sanitizer_pthread_attr_t {
char size[pthread_attr_t_max_sz]; // NOLINT
@@ -611,11 +565,6 @@ namespace __sanitizer {
// The size is determined by looking at sizeof of real sigset_t on linux.
uptr val[128 / sizeof(uptr)];
};
-#elif SANITIZER_FREEBSD
- struct __sanitizer_sigset_t {
- // uint32_t * 4
- unsigned int __bits[4];
- };
#endif
struct __sanitizer_siginfo {
@@ -705,9 +654,7 @@ namespace __sanitizer {
};
#endif // !SANITIZER_ANDROID
-#if SANITIZER_FREEBSD
- typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t;
-#elif defined(__mips__)
+#if defined(__mips__)
struct __sanitizer_kernel_sigset_t {
uptr sig[2];
};
@@ -753,7 +700,7 @@ namespace __sanitizer {
extern int af_inet6;
uptr __sanitizer_in_addr_sz(int af);
-#if SANITIZER_LINUX || SANITIZER_FREEBSD
+#if SANITIZER_LINUX
struct __sanitizer_dl_phdr_info {
uptr dlpi_addr;
const char *dlpi_name;
@@ -769,7 +716,7 @@ namespace __sanitizer {
int ai_family;
int ai_socktype;
int ai_protocol;
-#if SANITIZER_ANDROID || SANITIZER_MAC || SANITIZER_FREEBSD
+#if SANITIZER_ANDROID || SANITIZER_MAC
unsigned ai_addrlen;
char *ai_canonname;
void *ai_addr;
@@ -795,7 +742,7 @@ namespace __sanitizer {
short revents;
};
-#if SANITIZER_ANDROID || SANITIZER_MAC || SANITIZER_FREEBSD
+#if SANITIZER_ANDROID || SANITIZER_MAC
typedef unsigned __sanitizer_nfds_t;
#else
typedef unsigned long __sanitizer_nfds_t;
@@ -815,23 +762,9 @@ namespace __sanitizer {
int (*gl_lstat)(const char *, void *);
int (*gl_stat)(const char *, void *);
};
-# elif SANITIZER_FREEBSD
- struct __sanitizer_glob_t {
- uptr gl_pathc;
- uptr gl_matchc;
- uptr gl_offs;
- int gl_flags;
- char **gl_pathv;
- int (*gl_errfunc)(const char*, int);
- void (*gl_closedir)(void *dirp);
- struct dirent *(*gl_readdir)(void *dirp);
- void *(*gl_opendir)(const char*);
- int (*gl_lstat)(const char*, void* /* struct stat* */);
- int (*gl_stat)(const char*, void* /* struct stat* */);
- };
-# endif // SANITIZER_FREEBSD
+# endif // SANITIZER_LINUX
-# if SANITIZER_LINUX || SANITIZER_FREEBSD
+# if SANITIZER_LINUX
extern int glob_nomatch;
extern int glob_altdirfunc;
# endif
@@ -843,10 +776,6 @@ namespace __sanitizer {
uptr we_wordc;
char **we_wordv;
uptr we_offs;
-#if SANITIZER_FREEBSD
- char *we_strings;
- uptr we_nbytes;
-#endif
};
#if SANITIZER_LINUX && !SANITIZER_ANDROID
@@ -900,7 +829,7 @@ namespace __sanitizer {
extern int ptrace_geteventmsg;
#endif
-#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
+#if SANITIZER_LINUX && !SANITIZER_ANDROID
extern unsigned struct_shminfo_sz;
extern unsigned struct_shm_info_sz;
extern int shmctl_ipc_stat;
@@ -1037,7 +966,7 @@ struct __sanitizer_cookie_io_functions_t {
extern unsigned struct_vt_stat_sz;
#endif // SANITIZER_LINUX
-#if SANITIZER_LINUX || SANITIZER_FREEBSD
+#if SANITIZER_LINUX
extern unsigned struct_copr_buffer_sz;
extern unsigned struct_copr_debug_buf_sz;
extern unsigned struct_copr_msg_sz;
@@ -1049,7 +978,7 @@ struct __sanitizer_cookie_io_functions_t {
extern unsigned struct_seq_event_rec_sz;
extern unsigned struct_synth_info_sz;
extern unsigned struct_vt_mode_sz;
-#endif // SANITIZER_LINUX || SANITIZER_FREEBSD
+#endif // SANITIZER_LINUX
#if SANITIZER_LINUX && !SANITIZER_ANDROID
extern unsigned struct_ax25_parms_struct_sz;
@@ -1071,7 +1000,9 @@ struct __sanitizer_cookie_io_functions_t {
extern unsigned struct_unimapinit_sz;
#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
-#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
+ extern const unsigned long __sanitizer_bufsiz;
+
+#if SANITIZER_LINUX && !SANITIZER_ANDROID
extern unsigned struct_audio_buf_info_sz;
extern unsigned struct_ppp_stats_sz;
#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
@@ -1131,7 +1062,7 @@ struct __sanitizer_cookie_io_functions_t {
extern unsigned IOCTL_TIOCSPGRP;
extern unsigned IOCTL_TIOCSTI;
extern unsigned IOCTL_TIOCSWINSZ;
-#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
+#if SANITIZER_LINUX && !SANITIZER_ANDROID
extern unsigned IOCTL_SIOCGETSGCNT;
extern unsigned IOCTL_SIOCGETVIFCNT;
#endif
@@ -1293,8 +1224,6 @@ struct __sanitizer_cookie_io_functions_t {
extern unsigned IOCTL_VT_RESIZE;
extern unsigned IOCTL_VT_RESIZEX;
extern unsigned IOCTL_VT_SENDSIG;
-#endif // SANITIZER_LINUX
-#if SANITIZER_LINUX || SANITIZER_FREEBSD
extern unsigned IOCTL_MTIOCGET;
extern unsigned IOCTL_MTIOCTOP;
extern unsigned IOCTL_SIOCADDRT;
@@ -1395,7 +1324,7 @@ struct __sanitizer_cookie_io_functions_t {
extern unsigned IOCTL_VT_RELDISP;
extern unsigned IOCTL_VT_SETMODE;
extern unsigned IOCTL_VT_WAITACTIVE;
-#endif // SANITIZER_LINUX || SANITIZER_FREEBSD
+#endif // SANITIZER_LINUX
#if SANITIZER_LINUX && !SANITIZER_ANDROID
extern unsigned IOCTL_CYGETDEFTHRESH;
@@ -1482,9 +1411,6 @@ struct __sanitizer_cookie_io_functions_t {
extern unsigned IOCTL_TIOCSERGETMULTI;
extern unsigned IOCTL_TIOCSERSETMULTI;
extern unsigned IOCTL_TIOCSSERIAL;
-#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
-
-#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID
extern unsigned IOCTL_GIO_SCRNMAP;
extern unsigned IOCTL_KDDISABIO;
extern unsigned IOCTL_KDENABIO;
@@ -1523,6 +1449,6 @@ struct __sanitizer_cookie_io_functions_t {
#define SIGACTION_SYMNAME sigaction
-#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC
+#endif // SANITIZER_LINUX || SANITIZER_MAC
#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cpp
index 00b0ffc..9717d98 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_platform_limits_solaris.cc ------------------------------===//
+//===-- sanitizer_platform_limits_solaris.cpp -----------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h
index 97788d6..ed3b7a0 100644
--- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h
+++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h
@@ -1,7 +1,8 @@
//===-- sanitizer_platform_limits_solaris.h -------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -235,7 +236,7 @@ typedef long __sanitizer_clock_t;
typedef int __sanitizer_clockid_t;
// This thing depends on the platform. We are only interested in the upper
-// limit. Verified with a compiler assert in .cc.
+// limit. Verified with a compiler assert in .cpp.
const int pthread_attr_t_max_sz = 128;
union __sanitizer_pthread_attr_t {
char size[pthread_attr_t_max_sz]; // NOLINT
diff --git a/libsanitizer/sanitizer_common/sanitizer_posix.cc b/libsanitizer/sanitizer_common/sanitizer_posix.cpp
index 71994ba..002bcb1 100644
--- a/libsanitizer/sanitizer_common/sanitizer_posix.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_posix.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_posix.cc ------------------------------------------------===//
+//===-- sanitizer_posix.cpp -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -16,6 +17,7 @@
#include "sanitizer_common.h"
#include "sanitizer_file.h"
+#include "sanitizer_flags.h"
#include "sanitizer_libc.h"
#include "sanitizer_posix.h"
#include "sanitizer_procmaps.h"
@@ -41,9 +43,8 @@ uptr GetMmapGranularity() {
void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) {
size = RoundUpTo(size, GetPageSizeCached());
- uptr res = internal_mmap(nullptr, size,
- PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON, -1, 0);
+ uptr res = MmapNamed(nullptr, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON, mem_type);
int reserrno;
if (UNLIKELY(internal_iserror(res, &reserrno)))
ReportMmapFailureAndDie(size, mem_type, "allocate", reserrno, raw_report);
@@ -64,9 +65,8 @@ void UnmapOrDie(void *addr, uptr size) {
void *MmapOrDieOnFatalError(uptr size, const char *mem_type) {
size = RoundUpTo(size, GetPageSizeCached());
- uptr res = internal_mmap(nullptr, size,
- PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON, -1, 0);
+ uptr res = MmapNamed(nullptr, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON, mem_type);
int reserrno;
if (UNLIKELY(internal_iserror(res, &reserrno))) {
if (reserrno == ENOMEM)
@@ -101,12 +101,9 @@ void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment,
}
void *MmapNoReserveOrDie(uptr size, const char *mem_type) {
- uptr PageSize = GetPageSizeCached();
- uptr p = internal_mmap(nullptr,
- RoundUpTo(size, PageSize),
- PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON | MAP_NORESERVE,
- -1, 0);
+ size = RoundUpTo(size, GetPageSizeCached());
+ uptr p = MmapNamed(nullptr, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, mem_type);
int reserrno;
if (UNLIKELY(internal_iserror(p, &reserrno)))
ReportMmapFailureAndDie(size, mem_type, "allocate noreserve", reserrno);
@@ -114,13 +111,12 @@ void *MmapNoReserveOrDie(uptr size, const char *mem_type) {
return (void *)p;
}
-void *MmapFixedImpl(uptr fixed_addr, uptr size, bool tolerate_enomem) {
- uptr PageSize = GetPageSizeCached();
- uptr p = internal_mmap((void*)(fixed_addr & ~(PageSize - 1)),
- RoundUpTo(size, PageSize),
- PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON | MAP_FIXED,
- -1, 0);
+static void *MmapFixedImpl(uptr fixed_addr, uptr size, bool tolerate_enomem,
+ const char *name) {
+ size = RoundUpTo(size, GetPageSizeCached());
+ fixed_addr = RoundDownTo(fixed_addr, GetPageSizeCached());
+ uptr p = MmapNamed((void *)fixed_addr, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANON | MAP_FIXED, name);
int reserrno;
if (UNLIKELY(internal_iserror(p, &reserrno))) {
if (tolerate_enomem && reserrno == ENOMEM)
@@ -134,12 +130,12 @@ void *MmapFixedImpl(uptr fixed_addr, uptr size, bool tolerate_enomem) {
return (void *)p;
}
-void *MmapFixedOrDie(uptr fixed_addr, uptr size) {
- return MmapFixedImpl(fixed_addr, size, false /*tolerate_enomem*/);
+void *MmapFixedOrDie(uptr fixed_addr, uptr size, const char *name) {
+ return MmapFixedImpl(fixed_addr, size, false /*tolerate_enomem*/, name);
}
-void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size) {
- return MmapFixedImpl(fixed_addr, size, true /*tolerate_enomem*/);
+void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size, const char *name) {
+ return MmapFixedImpl(fixed_addr, size, true /*tolerate_enomem*/, name);
}
bool MprotectNoAccess(uptr addr, uptr size) {
@@ -155,6 +151,8 @@ void MprotectMallocZones(void *addr, int prot) {}
#endif
fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *errno_p) {
+ if (ShouldMockFailureToOpen(filename))
+ return kInvalidFd;
int flags;
switch (mode) {
case RdOnly: flags = O_RDONLY; break;
@@ -164,7 +162,7 @@ fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *errno_p) {
fd_t res = internal_open(filename, flags, 0660);
if (internal_iserror(res, errno_p))
return kInvalidFd;
- return res;
+ return ReserveStandardFds(res);
}
void CloseFile(fd_t fd) {
@@ -191,11 +189,6 @@ bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written,
return true;
}
-bool RenameFile(const char *oldpath, const char *newpath, error_t *error_p) {
- uptr res = internal_rename(oldpath, newpath);
- return !internal_iserror(res, error_p);
-}
-
void *MapFileToMemory(const char *file_name, uptr *buff_size) {
fd_t fd = OpenFile(file_name, RdOnly);
CHECK(fd != kInvalidFd);
@@ -233,6 +226,8 @@ static inline bool IntervalsAreSeparate(uptr start1, uptr end1,
// memory).
bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) {
MemoryMappingLayout proc_maps(/*cache_enabled*/true);
+ if (proc_maps.Error())
+ return true; // and hope for the best
MemoryMappedSegment segment;
while (proc_maps.Next(&segment)) {
if (segment.start == segment.end) continue; // Empty range.
@@ -272,13 +267,8 @@ bool IsAbsolutePath(const char *path) {
void ReportFile::Write(const char *buffer, uptr length) {
SpinMutexLock l(mu);
- static const char *kWriteError =
- "ReportFile::Write() can't output requested buffer!\n";
ReopenIfNecessary();
- if (length != internal_write(fd, buffer, length)) {
- internal_write(fd, kWriteError, internal_strlen(kWriteError));
- Die();
- }
+ internal_write(fd, buffer, length);
}
bool GetCodeRangeForFile(const char *module, uptr *start, uptr *end) {
@@ -326,6 +316,73 @@ const char *SignalContext::Describe() const {
return "UNKNOWN SIGNAL";
}
+fd_t ReserveStandardFds(fd_t fd) {
+ CHECK_GE(fd, 0);
+ if (fd > 2)
+ return fd;
+ bool used[3];
+ internal_memset(used, 0, sizeof(used));
+ while (fd <= 2) {
+ used[fd] = true;
+ fd = internal_dup(fd);
+ }
+ for (int i = 0; i <= 2; ++i)
+ if (used[i])
+ internal_close(i);
+ return fd;
+}
+
+bool ShouldMockFailureToOpen(const char *path) {
+ return common_flags()->test_only_emulate_no_memorymap &&
+ internal_strncmp(path, "/proc/", 6) == 0;
+}
+
+#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_GO
+int GetNamedMappingFd(const char *name, uptr size, int *flags) {
+ if (!common_flags()->decorate_proc_maps || !name)
+ return -1;
+ char shmname[200];
+ CHECK(internal_strlen(name) < sizeof(shmname) - 10);
+ internal_snprintf(shmname, sizeof(shmname), "/dev/shm/%zu [%s]",
+ internal_getpid(), name);
+ int fd = ReserveStandardFds(
+ internal_open(shmname, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, S_IRWXU));
+ CHECK_GE(fd, 0);
+ int res = internal_ftruncate(fd, size);
+ CHECK_EQ(0, res);
+ res = internal_unlink(shmname);
+ CHECK_EQ(0, res);
+ *flags &= ~(MAP_ANON | MAP_ANONYMOUS);
+ return fd;
+}
+#else
+int GetNamedMappingFd(const char *name, uptr size, int *flags) {
+ return -1;
+}
+#endif
+
+#if SANITIZER_ANDROID
+#define PR_SET_VMA 0x53564d41
+#define PR_SET_VMA_ANON_NAME 0
+void DecorateMapping(uptr addr, uptr size, const char *name) {
+ if (!common_flags()->decorate_proc_maps || !name)
+ return;
+ internal_prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, addr, size, (uptr)name);
+}
+#else
+void DecorateMapping(uptr addr, uptr size, const char *name) {
+}
+#endif
+
+uptr MmapNamed(void *addr, uptr length, int prot, int flags, const char *name) {
+ int fd = GetNamedMappingFd(name, length, &flags);
+ uptr res = internal_mmap(addr, length, prot, flags, fd, 0);
+ if (!internal_iserror(res))
+ DecorateMapping(res, length, name);
+ return res;
+}
+
+
} // namespace __sanitizer
#endif // SANITIZER_POSIX
diff --git a/libsanitizer/sanitizer_common/sanitizer_posix.h b/libsanitizer/sanitizer_common/sanitizer_posix.h
index a013f35..6cf5ce7 100644
--- a/libsanitizer/sanitizer_common/sanitizer_posix.h
+++ b/libsanitizer/sanitizer_common/sanitizer_posix.h
@@ -1,7 +1,8 @@
//===-- sanitizer_posix.h -------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -14,6 +15,7 @@
// ----------- ATTENTION -------------
// This header should NOT include any other headers from sanitizer runtime.
#include "sanitizer_internal_defs.h"
+#include "sanitizer_platform_limits_freebsd.h"
#include "sanitizer_platform_limits_netbsd.h"
#include "sanitizer_platform_limits_openbsd.h"
#include "sanitizer_platform_limits_posix.h"
@@ -46,13 +48,18 @@ uptr internal_filesize(fd_t fd); // -1 on error.
uptr internal_stat(const char *path, void *buf);
uptr internal_lstat(const char *path, void *buf);
uptr internal_fstat(fd_t fd, void *buf);
+uptr internal_dup(int oldfd);
uptr internal_dup2(int oldfd, int newfd);
uptr internal_readlink(const char *path, char *buf, uptr bufsize);
uptr internal_unlink(const char *path);
uptr internal_rename(const char *oldpath, const char *newpath);
uptr internal_lseek(fd_t fd, OFF_T offset, int whence);
+#if SANITIZER_NETBSD
+uptr internal_ptrace(int request, int pid, void *addr, int data);
+#else
uptr internal_ptrace(int request, int pid, void *addr, void *data);
+#endif
uptr internal_waitpid(int pid, int *status, int options);
int internal_fork();
@@ -96,6 +103,23 @@ uptr internal_execve(const char *filename, char *const argv[],
bool IsStateDetached(int state);
+// Move the fd out of {0, 1, 2} range.
+fd_t ReserveStandardFds(fd_t fd);
+
+bool ShouldMockFailureToOpen(const char *path);
+
+// Create a non-file mapping with a given /proc/self/maps name.
+uptr MmapNamed(void *addr, uptr length, int prot, int flags, const char *name);
+
+// Platforms should implement at most one of these.
+// 1. Provide a pre-decorated file descriptor to use instead of an anonymous
+// mapping.
+int GetNamedMappingFd(const char *name, uptr size, int *flags);
+// 2. Add name to an existing anonymous mapping. The caller must keep *name
+// alive at least as long as the mapping exists.
+void DecorateMapping(uptr addr, uptr size, const char *name);
+
+
} // namespace __sanitizer
#endif // SANITIZER_POSIX_H
diff --git a/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp
index d2fd76a..1bbbf8a 100644
--- a/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_posix_libcdep.cc ----------------------------------------===//
+//===-- sanitizer_posix_libcdep.cpp ---------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -67,11 +68,12 @@ void ReleaseMemoryPagesToOS(uptr beg, uptr end) {
SANITIZER_MADVISE_DONTNEED);
}
-bool NoHugePagesInRegion(uptr addr, uptr size) {
+void SetShadowRegionHugePageMode(uptr addr, uptr size) {
#ifdef MADV_NOHUGEPAGE // May not be defined on old systems.
- return madvise((char *)addr, size, MADV_NOHUGEPAGE) == 0;
-#else
- return true;
+ if (common_flags()->no_huge_pages_for_shadow)
+ madvise((char *)addr, size, MADV_NOHUGEPAGE);
+ else
+ madvise((char *)addr, size, MADV_HUGEPAGE);
#endif // MADV_NOHUGEPAGE
}
@@ -92,10 +94,12 @@ static rlim_t getlim(int res) {
}
static void setlim(int res, rlim_t lim) {
- // The following magic is to prevent clang from replacing it with memset.
- volatile struct rlimit rlim;
+ struct rlimit rlim;
+ if (getrlimit(res, const_cast<struct rlimit *>(&rlim))) {
+ Report("ERROR: %s getrlimit() failed %d\n", SanitizerToolName, errno);
+ Die();
+ }
rlim.rlim_cur = lim;
- rlim.rlim_max = lim;
if (setrlimit(res, const_cast<struct rlimit *>(&rlim))) {
Report("ERROR: %s setrlimit() failed %d\n", SanitizerToolName, errno);
Die();
@@ -113,10 +117,6 @@ bool StackSizeIsUnlimited() {
return (stack_size == RLIM_INFINITY);
}
-uptr GetStackSizeLimitInBytes() {
- return (uptr)getlim(RLIMIT_STACK);
-}
-
void SetStackSizeLimitInBytes(uptr limit) {
setlim(RLIMIT_STACK, (rlim_t)limit);
CHECK(!StackSizeIsUnlimited());
@@ -304,37 +304,11 @@ void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {
MemoryMappingLayout::CacheMemoryMappings();
}
-#if SANITIZER_ANDROID || SANITIZER_GO
-int GetNamedMappingFd(const char *name, uptr size) {
- return -1;
-}
-#else
-int GetNamedMappingFd(const char *name, uptr size) {
- if (!common_flags()->decorate_proc_maps)
- return -1;
- char shmname[200];
- CHECK(internal_strlen(name) < sizeof(shmname) - 10);
- internal_snprintf(shmname, sizeof(shmname), "%zu [%s]", internal_getpid(),
- name);
- int fd = shm_open(shmname, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU);
- CHECK_GE(fd, 0);
- int res = internal_ftruncate(fd, size);
- CHECK_EQ(0, res);
- res = shm_unlink(shmname);
- CHECK_EQ(0, res);
- return fd;
-}
-#endif
-
bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) {
- int fd = name ? GetNamedMappingFd(name, size) : -1;
- unsigned flags = MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE;
- if (fd == -1) flags |= MAP_ANON;
-
- uptr PageSize = GetPageSizeCached();
- uptr p = internal_mmap((void *)(fixed_addr & ~(PageSize - 1)),
- RoundUpTo(size, PageSize), PROT_READ | PROT_WRITE,
- flags, fd, 0);
+ size = RoundUpTo(size, GetPageSizeCached());
+ fixed_addr = RoundDownTo(fixed_addr, GetPageSizeCached());
+ uptr p = MmapNamed((void *)fixed_addr, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE | MAP_ANON, name);
int reserrno;
if (internal_iserror(p, &reserrno)) {
Report("ERROR: %s failed to "
@@ -347,12 +321,8 @@ bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) {
}
uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) {
- // We don't pass `name` along because, when you enable `decorate_proc_maps`
- // AND actually use a named mapping AND are using a sanitizer intercepting
- // `open` (e.g. TSAN, ESAN), then you'll get a failure during initialization.
- // TODO(flowerhack): Fix the implementation of GetNamedMappingFd to solve
- // this problem.
- base_ = fixed_addr ? MmapFixedNoAccess(fixed_addr, size) : MmapNoAccess(size);
+ base_ = fixed_addr ? MmapFixedNoAccess(fixed_addr, size, name)
+ : MmapNoAccess(size);
size_ = size;
name_ = name;
(void)os_handle_; // unsupported
@@ -361,12 +331,14 @@ uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) {
// Uses fixed_addr for now.
// Will use offset instead once we've implemented this function for real.
-uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size) {
- return reinterpret_cast<uptr>(MmapFixedOrDieOnFatalError(fixed_addr, size));
+uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size, const char *name) {
+ return reinterpret_cast<uptr>(
+ MmapFixedOrDieOnFatalError(fixed_addr, size, name));
}
-uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr size) {
- return reinterpret_cast<uptr>(MmapFixedOrDie(fixed_addr, size));
+uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr size,
+ const char *name) {
+ return reinterpret_cast<uptr>(MmapFixedOrDie(fixed_addr, size, name));
}
void ReservedAddressRange::Unmap(uptr addr, uptr size) {
@@ -381,12 +353,9 @@ void ReservedAddressRange::Unmap(uptr addr, uptr size) {
}
void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name) {
- int fd = name ? GetNamedMappingFd(name, size) : -1;
- unsigned flags = MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE;
- if (fd == -1) flags |= MAP_ANON;
-
- return (void *)internal_mmap((void *)fixed_addr, size, PROT_NONE, flags, fd,
- 0);
+ return (void *)MmapNamed((void *)fixed_addr, size, PROT_NONE,
+ MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE | MAP_ANON,
+ name);
}
void *MmapNoAccess(uptr size) {
diff --git a/libsanitizer/sanitizer_common/sanitizer_printf.cc b/libsanitizer/sanitizer_common/sanitizer_printf.cpp
index 5da8c5f..9d1c544 100644
--- a/libsanitizer/sanitizer_common/sanitizer_printf.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_printf.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_printf.cc -----------------------------------------------===//
+//===-- sanitizer_printf.cpp ----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps.h b/libsanitizer/sanitizer_common/sanitizer_procmaps.h
index 606b292..0520271 100644
--- a/libsanitizer/sanitizer_common/sanitizer_procmaps.h
+++ b/libsanitizer/sanitizer_common/sanitizer_procmaps.h
@@ -1,7 +1,8 @@
//===-- sanitizer_procmaps.h ------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -68,6 +69,7 @@ class MemoryMappingLayout {
explicit MemoryMappingLayout(bool cache_enabled);
~MemoryMappingLayout();
bool Next(MemoryMappedSegment *segment);
+ bool Error() const;
void Reset();
// In some cases, e.g. when running under a sandbox on Linux, ASan is unable
// to obtain the memory mappings. It should fall back to pre-cached data
diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cc b/libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cpp
index b7887d9..02ff7c0 100644
--- a/libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_procmaps_bsd.cc -----------------------------------------===//
+//===-- sanitizer_procmaps_bsd.cpp ----------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -97,6 +98,7 @@ void ReadProcMaps(ProcSelfMapsBuff *proc_maps) {
}
bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
+ CHECK(!Error()); // can not fail
char *last = data_.proc_self_maps.data + data_.proc_self_maps.len;
if (data_.current >= last)
return false;
diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cc b/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cpp
index 24cf9f8..e0cb47f 100644
--- a/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_procmaps_common.cc --------------------------------------===//
+//===-- sanitizer_procmaps_common.cpp -------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -78,12 +79,14 @@ MemoryMappingLayout::MemoryMappingLayout(bool cache_enabled) {
ReadProcMaps(&data_.proc_self_maps);
if (cache_enabled && data_.proc_self_maps.mmaped_size == 0)
LoadFromCache();
- CHECK_GT(data_.proc_self_maps.mmaped_size, 0);
- CHECK_GT(data_.proc_self_maps.len, 0);
Reset();
}
+bool MemoryMappingLayout::Error() const {
+ return data_.current == nullptr;
+}
+
MemoryMappingLayout::~MemoryMappingLayout() {
// Only unmap the buffer if it is different from the cached one. Otherwise
// it will be unmapped when the cache is refreshed.
diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cc b/libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cpp
index f9092f4..c7af573 100644
--- a/libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_procmaps_linux.cc ---------------------------------------===//
+//===-- sanitizer_procmaps_linux.cpp --------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -29,6 +30,7 @@ static bool IsOneOf(char c, char c1, char c2) {
}
bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
+ if (Error()) return false; // simulate empty maps
char *last = data_.proc_self_maps.data + data_.proc_self_maps.len;
if (data_.current >= last) return false;
char *next_line =
diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cc b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp
index b0e68fd..ea72a57 100644
--- a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_procmaps_mac.cc -----------------------------------------===//
+//===-- sanitizer_procmaps_mac.cpp ----------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -86,6 +87,10 @@ MemoryMappingLayout::MemoryMappingLayout(bool cache_enabled) {
MemoryMappingLayout::~MemoryMappingLayout() {
}
+bool MemoryMappingLayout::Error() const {
+ return false;
+}
+
// More information about Mach-O headers can be found in mach-o/loader.h
// Each Mach-O image has a header (mach_header or mach_header_64) starting with
// a magic number, and a list of linker load commands directly following the
diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cc b/libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cpp
index 9e5e37e..8793423 100644
--- a/libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_procmaps_solaris.cc -------------------------------------===//
+//===-- sanitizer_procmaps_solaris.cpp ------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -21,11 +22,16 @@
namespace __sanitizer {
void ReadProcMaps(ProcSelfMapsBuff *proc_maps) {
- ReadFileToBuffer("/proc/self/xmap", &proc_maps->data, &proc_maps->mmaped_size,
- &proc_maps->len);
+ if (!ReadFileToBuffer("/proc/self/xmap", &proc_maps->data,
+ &proc_maps->mmaped_size, &proc_maps->len)) {
+ proc_maps->data = nullptr;
+ proc_maps->mmaped_size = 0;
+ proc_maps->len = 0;
+ }
}
bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
+ if (Error()) return false; // simulate empty maps
char *last = data_.proc_self_maps.data + data_.proc_self_maps.len;
if (data_.current >= last) return false;
@@ -44,9 +50,11 @@ bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
segment->protection |= kProtectionExecute;
if (segment->filename != NULL && segment->filename_size > 0) {
- internal_snprintf(segment->filename,
- Min(segment->filename_size, (uptr)PATH_MAX), "%s",
+ char proc_path[PATH_MAX + 1];
+
+ internal_snprintf(proc_path, sizeof(proc_path), "/proc/self/path/%s",
xmapentry->pr_mapname);
+ internal_readlink(proc_path, segment->filename, segment->filename_size);
}
data_.current += sizeof(prxmap_t);
diff --git a/libsanitizer/sanitizer_common/sanitizer_quarantine.h b/libsanitizer/sanitizer_common/sanitizer_quarantine.h
index 0ebe97d..992f231 100644
--- a/libsanitizer/sanitizer_common/sanitizer_quarantine.h
+++ b/libsanitizer/sanitizer_common/sanitizer_quarantine.h
@@ -1,7 +1,8 @@
//===-- sanitizer_quarantine.h ----------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_report_decorator.h b/libsanitizer/sanitizer_common/sanitizer_report_decorator.h
index b46a028..d276c2c 100644
--- a/libsanitizer/sanitizer_common/sanitizer_report_decorator.h
+++ b/libsanitizer/sanitizer_common/sanitizer_report_decorator.h
@@ -1,7 +1,8 @@
//===-- sanitizer_report_decorator.h ----------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_ring_buffer.h b/libsanitizer/sanitizer_common/sanitizer_ring_buffer.h
index 39ee631..2a46e93 100644
--- a/libsanitizer/sanitizer_common/sanitizer_ring_buffer.h
+++ b/libsanitizer/sanitizer_common/sanitizer_ring_buffer.h
@@ -1,7 +1,8 @@
//===-- sanitizer_ring_buffer.h ---------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -138,7 +139,7 @@ class CompactRingBuffer {
SetNext(next);
}
- T operator[](uptr Idx) const {
+ const T &operator[](uptr Idx) const {
CHECK_LT(Idx, size());
const T *Begin = (const T *)StartOfStorage();
sptr StorageIdx = Next() - Begin;
diff --git a/libsanitizer/sanitizer_common/sanitizer_rtems.cc b/libsanitizer/sanitizer_common/sanitizer_rtems.cpp
index 2792c59..0d2576c 100644
--- a/libsanitizer/sanitizer_common/sanitizer_rtems.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_rtems.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_rtems.cc ------------------------------------------------===//
+//===-- sanitizer_rtems.cpp -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -93,8 +94,10 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
*tls_addr = *tls_size = 0;
}
+void InitializePlatformEarly() {}
void MaybeReexec() {}
void CheckASLR() {}
+void CheckMPROTECT() {}
void DisableCoreDumperIfNecessary() {}
void InstallDeadlySignalHandlers(SignalHandlerType handler) {}
void SetAlternateSignalStack() {}
@@ -224,11 +227,6 @@ bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written,
return true;
}
-bool RenameFile(const char *oldpath, const char *newpath, error_t *error_p) {
- uptr res = rename(oldpath, newpath);
- return !internal_iserror(res, error_p);
-}
-
void ReleaseMemoryPagesToOS(uptr beg, uptr end) {}
void DumpProcessMap() {}
@@ -238,6 +236,7 @@ bool IsAccessibleMemoryRange(uptr beg, uptr size) {
}
char **GetArgv() { return nullptr; }
+char **GetEnviron() { return nullptr; }
const char *GetEnv(const char *name) {
return getenv(name);
diff --git a/libsanitizer/sanitizer_common/sanitizer_rtems.h b/libsanitizer/sanitizer_common/sanitizer_rtems.h
index dc64bbc..e8adfd5 100644
--- a/libsanitizer/sanitizer_common/sanitizer_rtems.h
+++ b/libsanitizer/sanitizer_common/sanitizer_rtems.h
@@ -1,7 +1,8 @@
//===-- sanitizer_rtems.h ---------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc
index 7ec6339..68d9eb6 100644
--- a/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_signal_interceptors.inc -----------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_solaris.cc b/libsanitizer/sanitizer_common/sanitizer_solaris.cpp
index 9d0c3d9..035f2d0 100644
--- a/libsanitizer/sanitizer_common/sanitizer_solaris.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_solaris.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_solaris.cc ----------------------------------------------===//
+//===-- sanitizer_solaris.cpp ---------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -87,11 +88,6 @@ uptr internal_open(const char *filename, int flags, u32 mode) {
return _REAL64(open)(filename, flags, mode);
}
-uptr OpenFile(const char *filename, bool write) {
- return internal_open(filename,
- write ? O_WRONLY | O_CREAT : O_RDONLY, 0660);
-}
-
DECLARE__REAL_AND_INTERNAL(uptr, read, fd_t fd, void *buf, uptr count) {
return _REAL(read)(fd, buf, count);
}
@@ -124,6 +120,10 @@ uptr internal_filesize(fd_t fd) {
return (uptr)st.st_size;
}
+DECLARE__REAL_AND_INTERNAL(uptr, dup, int oldfd) {
+ return _REAL(dup)(oldfd);
+}
+
DECLARE__REAL_AND_INTERNAL(uptr, dup2, int oldfd, int newfd) {
return _REAL(dup2)(oldfd, newfd);
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_stackdepot.cc b/libsanitizer/sanitizer_common/sanitizer_stackdepot.cpp
index d48f7d2..30073a9 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stackdepot.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_stackdepot.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_stackdepot.cc -------------------------------------------===//
+//===-- sanitizer_stackdepot.cpp ------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -12,6 +13,7 @@
#include "sanitizer_stackdepot.h"
#include "sanitizer_common.h"
+#include "sanitizer_hash.h"
#include "sanitizer_stackdepotbase.h"
namespace __sanitizer {
@@ -24,7 +26,7 @@ struct StackDepotNode {
u32 tag;
uptr stack[1]; // [size]
- static const u32 kTabSizeLog = 20;
+ static const u32 kTabSizeLog = SANITIZER_ANDROID ? 16 : 20;
// Lower kTabSizeLog bits are equal for all items in one bucket.
// We use these bits to store the per-stack use counter.
static const u32 kUseCountBits = kTabSizeLog;
@@ -48,23 +50,9 @@ struct StackDepotNode {
return sizeof(StackDepotNode) + (args.size - 1) * sizeof(uptr);
}
static u32 hash(const args_type &args) {
- // murmur2
- const u32 m = 0x5bd1e995;
- const u32 seed = 0x9747b28c;
- const u32 r = 24;
- u32 h = seed ^ (args.size * sizeof(uptr));
- for (uptr i = 0; i < args.size; i++) {
- u32 k = args.trace[i];
- k *= m;
- k ^= k >> r;
- k *= m;
- h *= m;
- h ^= k;
- }
- h ^= h >> 13;
- h *= m;
- h ^= h >> 15;
- return h;
+ MurMur2HashBuilder H(args.size * sizeof(uptr));
+ for (uptr i = 0; i < args.size; i++) H.add(args.trace[i]);
+ return H.get();
}
static bool is_valid(const args_type &args) {
return args.size > 0 && args.trace;
diff --git a/libsanitizer/sanitizer_common/sanitizer_stackdepot.h b/libsanitizer/sanitizer_common/sanitizer_stackdepot.h
index dfb5349..bf29cb9 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stackdepot.h
+++ b/libsanitizer/sanitizer_common/sanitizer_stackdepot.h
@@ -1,7 +1,8 @@
//===-- sanitizer_stackdepot.h ----------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -30,7 +31,7 @@ struct StackDepotHandle {
void inc_use_count_unsafe();
};
-const int kStackDepotMaxUseCount = 1U << 20;
+const int kStackDepotMaxUseCount = 1U << (SANITIZER_ANDROID ? 16 : 20);
StackDepotStats *StackDepotGetStats();
u32 StackDepotPut(StackTrace stack);
diff --git a/libsanitizer/sanitizer_common/sanitizer_stackdepotbase.h b/libsanitizer/sanitizer_common/sanitizer_stackdepotbase.h
index ab49328..ef1b4f7 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stackdepotbase.h
+++ b/libsanitizer/sanitizer_common/sanitizer_stackdepotbase.h
@@ -1,7 +1,8 @@
//===-- sanitizer_stackdepotbase.h ------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp
index f1c514d..ce75cbe 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_stacktrace.cc -------------------------------------------===//
+//===-- sanitizer_stacktrace.cpp ------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -47,6 +48,7 @@ void BufferedStackTrace::Init(const uptr *pcs, uptr cnt, uptr extra_top_pc) {
static inline uhwptr *GetCanonicFrame(uptr bp,
uptr stack_top,
uptr stack_bottom) {
+ CHECK_GT(stack_top, stack_bottom);
#ifdef __arm__
if (!IsValidFrame(bp, stack_top, stack_bottom)) return 0;
uhwptr *bp_prev = (uhwptr *)bp;
@@ -65,10 +67,11 @@ static inline uhwptr *GetCanonicFrame(uptr bp,
#endif
}
-void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top,
- uptr stack_bottom, u32 max_depth) {
- const uptr kPageSize = GetPageSizeCached();
+void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top,
+ uptr stack_bottom, u32 max_depth) {
+ // TODO(yln): add arg sanity check for stack_top/stack_bottom
CHECK_GE(max_depth, 2);
+ const uptr kPageSize = GetPageSizeCached();
trace_buffer[0] = pc;
size = 1;
if (stack_top < 4096) return; // Sanity check for stack top.
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.h b/libsanitizer/sanitizer_common/sanitizer_stacktrace.h
index 039b5d9..f1f29e9 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.h
+++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.h
@@ -1,7 +1,8 @@
//===-- sanitizer_stacktrace.h ----------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -15,6 +16,8 @@
namespace __sanitizer {
+struct BufferedStackTrace;
+
static const u32 kStackTraceMax = 256;
#if SANITIZER_LINUX && defined(__mips__)
@@ -57,7 +60,7 @@ struct StackTrace {
static bool WillUseFastUnwind(bool request_fast_unwind) {
if (!SANITIZER_CAN_FAST_UNWIND)
return false;
- else if (!SANITIZER_CAN_SLOW_UNWIND)
+ if (!SANITIZER_CAN_SLOW_UNWIND)
return true;
return request_fast_unwind;
}
@@ -95,6 +98,23 @@ struct BufferedStackTrace : public StackTrace {
BufferedStackTrace() : StackTrace(trace_buffer, 0), top_frame_bp(0) {}
void Init(const uptr *pcs, uptr cnt, uptr extra_top_pc = 0);
+
+ // Get the stack trace with the given pc and bp.
+ // The pc will be in the position 0 of the resulting stack trace.
+ // The bp may refer to the current frame or to the caller's frame.
+ void Unwind(uptr pc, uptr bp, void *context, bool request_fast,
+ u32 max_depth = kStackTraceMax) {
+ top_frame_bp = (max_depth > 0) ? bp : 0;
+ // Small max_depth optimization
+ if (max_depth <= 1) {
+ if (max_depth == 1)
+ trace_buffer[0] = pc;
+ size = max_depth;
+ return;
+ }
+ UnwindImpl(pc, bp, context, request_fast, max_depth);
+ }
+
void Unwind(u32 max_depth, uptr pc, uptr bp, void *context, uptr stack_top,
uptr stack_bottom, bool request_fast_unwind);
@@ -104,16 +124,23 @@ struct BufferedStackTrace : public StackTrace {
}
private:
- void FastUnwindStack(uptr pc, uptr bp, uptr stack_top, uptr stack_bottom,
- u32 max_depth);
- void SlowUnwindStack(uptr pc, u32 max_depth);
- void SlowUnwindStackWithContext(uptr pc, void *context,
- u32 max_depth);
+ // Every runtime defines its own implementation of this method
+ void UnwindImpl(uptr pc, uptr bp, void *context, bool request_fast,
+ u32 max_depth);
+
+ // UnwindFast/Slow have platform-specific implementations
+ void UnwindFast(uptr pc, uptr bp, uptr stack_top, uptr stack_bottom,
+ u32 max_depth);
+ void UnwindSlow(uptr pc, u32 max_depth);
+ void UnwindSlow(uptr pc, void *context, u32 max_depth);
+
void PopStackFrames(uptr count);
uptr LocatePcInTrace(uptr pc);
BufferedStackTrace(const BufferedStackTrace &) = delete;
void operator=(const BufferedStackTrace &) = delete;
+
+ friend class FastUnwindTest;
};
// Check if given pointer points into allocated stack area.
@@ -125,21 +152,23 @@ static inline bool IsValidFrame(uptr frame, uptr stack_top, uptr stack_bottom) {
// Use this macro if you want to print stack trace with the caller
// of the current function in the top frame.
-#define GET_CALLER_PC_BP_SP \
- uptr bp = GET_CURRENT_FRAME(); \
- uptr pc = GET_CALLER_PC(); \
- uptr local_stack; \
- uptr sp = (uptr)&local_stack
-
#define GET_CALLER_PC_BP \
uptr bp = GET_CURRENT_FRAME(); \
uptr pc = GET_CALLER_PC();
+#define GET_CALLER_PC_BP_SP \
+ GET_CALLER_PC_BP; \
+ uptr local_stack; \
+ uptr sp = (uptr)&local_stack
+
// Use this macro if you want to print stack trace with the current
// function in the top frame.
-#define GET_CURRENT_PC_BP_SP \
+#define GET_CURRENT_PC_BP \
uptr bp = GET_CURRENT_FRAME(); \
- uptr pc = StackTrace::GetCurrentPc(); \
+ uptr pc = StackTrace::GetCurrentPc()
+
+#define GET_CURRENT_PC_BP_SP \
+ GET_CURRENT_PC_BP; \
uptr local_stack; \
uptr sp = (uptr)&local_stack
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cpp
index ff08551..2c08274 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_stacktrace_libcdep.cc -----------------------------------===//
+//===-- sanitizer_stacktrace_libcdep.cpp ----------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -56,6 +57,8 @@ void StackTrace::Print() const {
void BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context,
uptr stack_top, uptr stack_bottom,
bool request_fast_unwind) {
+ // Ensures all call sites get what they requested.
+ CHECK_EQ(request_fast_unwind, WillUseFastUnwind(request_fast_unwind));
top_frame_bp = (max_depth > 0) ? bp : 0;
// Avoid doing any work for small max_depth.
if (max_depth == 0) {
@@ -70,14 +73,14 @@ void BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context,
if (!WillUseFastUnwind(request_fast_unwind)) {
#if SANITIZER_CAN_SLOW_UNWIND
if (context)
- SlowUnwindStackWithContext(pc, context, max_depth);
+ UnwindSlow(pc, context, max_depth);
else
- SlowUnwindStack(pc, max_depth);
+ UnwindSlow(pc, max_depth);
#else
UNREACHABLE("slow unwind requested but not available");
#endif
} else {
- FastUnwindStack(pc, bp, stack_top, stack_bottom, max_depth);
+ UnwindFast(pc, bp, stack_top, stack_bottom, max_depth);
}
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cpp
index 7e21c4b..150ff47 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_common.cc -----------------------------------------------===//
+//===-- sanitizer_common.cpp ----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -15,7 +16,7 @@
namespace __sanitizer {
-// sanitizer_symbolizer_markup.cc implements these differently.
+// sanitizer_symbolizer_markup.cpp implements these differently.
#if !SANITIZER_SYMBOLIZER_MARKUP
static const char *StripFunctionName(const char *function, const char *prefix) {
@@ -96,6 +97,8 @@ static const char *DemangleFunctionName(const char *function) {
return "pthread_equal";
if (!internal_strcmp(function, "__libc_thr_curcpu"))
return "pthread_curcpu_np";
+ if (!internal_strcmp(function, "__libc_thr_sigsetmask"))
+ return "pthread_sigmask";
#endif
return function;
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.h b/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.h
index cf3cd42..f7f7629 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.h
+++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.h
@@ -1,7 +1,8 @@
//===-- sanitizer_stacktrace_printer.h --------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cpp
index bd04d0f..34190fb 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_stacktrace_sparc.cc -------------------------------------===//
+//===-- sanitizer_stacktrace_sparc.cpp ------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -24,10 +25,11 @@
namespace __sanitizer {
-void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top,
- uptr stack_bottom, u32 max_depth) {
- const uptr kPageSize = GetPageSizeCached();
+void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top,
+ uptr stack_bottom, u32 max_depth) {
+ // TODO(yln): add arg sanity check for stack_top/stack_bottom
CHECK_GE(max_depth, 2);
+ const uptr kPageSize = GetPageSizeCached();
#if defined(__GNUC__)
// __builtin_return_address returns the address of the call instruction
// on the SPARC and not the return address, so we need to compensate.
@@ -50,11 +52,9 @@ void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top,
uptr prev_bp = GET_CURRENT_FRAME();
uptr next_bp = prev_bp;
unsigned int i = 0;
- while (next_bp != bp &&
- IsAligned(next_bp, sizeof(uhwptr)) &&
- i++ < 8) {
+ while (next_bp != bp && IsAligned(next_bp, sizeof(uhwptr)) && i++ < 8) {
prev_bp = next_bp;
- next_bp = (uptr) ((uhwptr *) next_bp)[14] + STACK_BIAS;
+ next_bp = (uptr)((uhwptr *)next_bp)[14] + STACK_BIAS;
}
if (next_bp == bp)
bp = prev_bp;
@@ -62,8 +62,7 @@ void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top,
// Goes up as we walk the stack.
uptr bottom = stack_bottom;
// Avoid infinite loop when frame == frame[0] by using frame > prev_frame.
- while (IsValidFrame(bp, stack_top, bottom) &&
- IsAligned(bp, sizeof(uhwptr)) &&
+ while (IsValidFrame(bp, stack_top, bottom) && IsAligned(bp, sizeof(uhwptr)) &&
size < max_depth) {
uhwptr pc1 = ((uhwptr *)bp)[15];
// Let's assume that any pointer in the 0th page is invalid and
@@ -74,10 +73,10 @@ void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top,
if (pc1 != pc) {
// %o7 contains the address of the call instruction and not the
// return address, so we need to compensate.
- trace_buffer[size++] = GetNextInstructionPc((uptr) pc1);
+ trace_buffer[size++] = GetNextInstructionPc((uptr)pc1);
}
bottom = bp;
- bp = (uptr) ((uhwptr *) bp)[14] + STACK_BIAS;
+ bp = (uptr)((uhwptr *)bp)[14] + STACK_BIAS;
}
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld.h b/libsanitizer/sanitizer_common/sanitizer_stoptheworld.h
index 8c3d2c0..4e42400 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld.h
+++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld.h
@@ -1,7 +1,8 @@
//===-- sanitizer_stoptheworld.h --------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp
index 635c573..b520dc8 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_stoptheworld_linux_libcdep.cc ---------------------------===//
+//===-- sanitizer_stoptheworld_linux_libcdep.cpp --------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cc b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cpp
index 6282694..9dffd21 100644
--- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_stoptheworld_mac.cc -------------------------------------===//
+//===-- sanitizer_stoptheworld_mac.cpp ------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp
new file mode 100644
index 0000000..5690d75
--- /dev/null
+++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp
@@ -0,0 +1,356 @@
+//===-- sanitizer_stoptheworld_netbsd_libcdep.cpp -------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// See sanitizer_stoptheworld.h for details.
+// This implementation was inspired by Markus Gutschke's linuxthreads.cc.
+//
+// This is a NetBSD variation of Linux stoptheworld implementation
+// See sanitizer_stoptheworld_linux_libcdep.cpp for code comments.
+//
+//===----------------------------------------------------------------------===//
+
+#include "sanitizer_platform.h"
+
+#if SANITIZER_NETBSD
+
+#include "sanitizer_stoptheworld.h"
+
+#include "sanitizer_atomic.h"
+#include "sanitizer_platform_limits_posix.h"
+
+#include <sys/types.h>
+
+#include <sys/ptrace.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+
+#include <machine/reg.h>
+
+#include <elf.h>
+#include <errno.h>
+#include <sched.h>
+#include <signal.h>
+#include <stddef.h>
+
+#define internal_sigaction_norestorer internal_sigaction
+
+#include "sanitizer_common.h"
+#include "sanitizer_flags.h"
+#include "sanitizer_libc.h"
+#include "sanitizer_linux.h"
+#include "sanitizer_mutex.h"
+#include "sanitizer_placement_new.h"
+
+namespace __sanitizer {
+
+class SuspendedThreadsListNetBSD : public SuspendedThreadsList {
+ public:
+ SuspendedThreadsListNetBSD() { thread_ids_.reserve(1024); }
+
+ tid_t GetThreadID(uptr index) const;
+ uptr ThreadCount() const;
+ bool ContainsTid(tid_t thread_id) const;
+ void Append(tid_t tid);
+
+ PtraceRegistersStatus GetRegistersAndSP(uptr index, uptr *buffer,
+ uptr *sp) const;
+ uptr RegisterCount() const;
+
+ private:
+ InternalMmapVector<tid_t> thread_ids_;
+};
+
+struct TracerThreadArgument {
+ StopTheWorldCallback callback;
+ void *callback_argument;
+ BlockingMutex mutex;
+ atomic_uintptr_t done;
+ uptr parent_pid;
+};
+
+class ThreadSuspender {
+ public:
+ explicit ThreadSuspender(pid_t pid, TracerThreadArgument *arg)
+ : arg(arg), pid_(pid) {
+ CHECK_GE(pid, 0);
+ }
+ bool SuspendAllThreads();
+ void ResumeAllThreads();
+ void KillAllThreads();
+ SuspendedThreadsListNetBSD &suspended_threads_list() {
+ return suspended_threads_list_;
+ }
+ TracerThreadArgument *arg;
+
+ private:
+ SuspendedThreadsListNetBSD suspended_threads_list_;
+ pid_t pid_;
+};
+
+void ThreadSuspender::ResumeAllThreads() {
+ int pterrno;
+ if (!internal_iserror(internal_ptrace(PT_DETACH, pid_, (void *)(uptr)1, 0),
+ &pterrno)) {
+ VReport(2, "Detached from process %d.\n", pid_);
+ } else {
+ VReport(1, "Could not detach from process %d (errno %d).\n", pid_, pterrno);
+ }
+}
+
+void ThreadSuspender::KillAllThreads() {
+ internal_ptrace(PT_KILL, pid_, nullptr, 0);
+}
+
+bool ThreadSuspender::SuspendAllThreads() {
+ int pterrno;
+ if (internal_iserror(internal_ptrace(PT_ATTACH, pid_, nullptr, 0),
+ &pterrno)) {
+ Printf("Could not attach to process %d (errno %d).\n", pid_, pterrno);
+ return false;
+ }
+
+ int status;
+ uptr waitpid_status;
+ HANDLE_EINTR(waitpid_status, internal_waitpid(pid_, &status, 0));
+
+ VReport(2, "Attached to process %d.\n", pid_);
+
+ struct ptrace_lwpinfo pl;
+ int val;
+ pl.pl_lwpid = 0;
+ while ((val = ptrace(PT_LWPINFO, pid_, (void *)&pl, sizeof(pl))) != -1 &&
+ pl.pl_lwpid != 0) {
+ suspended_threads_list_.Append(pl.pl_lwpid);
+ VReport(2, "Appended thread %d in process %d.\n", pl.pl_lwpid, pid_);
+ }
+ return true;
+}
+
+// Pointer to the ThreadSuspender instance for use in signal handler.
+static ThreadSuspender *thread_suspender_instance = nullptr;
+
+// Synchronous signals that should not be blocked.
+static const int kSyncSignals[] = {SIGABRT, SIGILL, SIGFPE, SIGSEGV,
+ SIGBUS, SIGXCPU, SIGXFSZ};
+
+static void TracerThreadDieCallback() {
+ ThreadSuspender *inst = thread_suspender_instance;
+ if (inst && stoptheworld_tracer_pid == internal_getpid()) {
+ inst->KillAllThreads();
+ thread_suspender_instance = nullptr;
+ }
+}
+
+// Signal handler to wake up suspended threads when the tracer thread dies.
+static void TracerThreadSignalHandler(int signum, __sanitizer_siginfo *siginfo,
+ void *uctx) {
+ SignalContext ctx(siginfo, uctx);
+ Printf("Tracer caught signal %d: addr=0x%zx pc=0x%zx sp=0x%zx\n", signum,
+ ctx.addr, ctx.pc, ctx.sp);
+ ThreadSuspender *inst = thread_suspender_instance;
+ if (inst) {
+ if (signum == SIGABRT)
+ inst->KillAllThreads();
+ else
+ inst->ResumeAllThreads();
+ RAW_CHECK(RemoveDieCallback(TracerThreadDieCallback));
+ thread_suspender_instance = nullptr;
+ atomic_store(&inst->arg->done, 1, memory_order_relaxed);
+ }
+ internal__exit((signum == SIGABRT) ? 1 : 2);
+}
+
+// Size of alternative stack for signal handlers in the tracer thread.
+static const int kHandlerStackSize = 8192;
+
+// This function will be run as a cloned task.
+static int TracerThread(void *argument) {
+ TracerThreadArgument *tracer_thread_argument =
+ (TracerThreadArgument *)argument;
+
+ // Check if parent is already dead.
+ if (internal_getppid() != tracer_thread_argument->parent_pid)
+ internal__exit(4);
+
+ // Wait for the parent thread to finish preparations.
+ tracer_thread_argument->mutex.Lock();
+ tracer_thread_argument->mutex.Unlock();
+
+ RAW_CHECK(AddDieCallback(TracerThreadDieCallback));
+
+ ThreadSuspender thread_suspender(internal_getppid(), tracer_thread_argument);
+ // Global pointer for the signal handler.
+ thread_suspender_instance = &thread_suspender;
+
+ // Alternate stack for signal handling.
+ InternalMmapVector<char> handler_stack_memory(kHandlerStackSize);
+ stack_t handler_stack;
+ internal_memset(&handler_stack, 0, sizeof(handler_stack));
+ handler_stack.ss_sp = handler_stack_memory.data();
+ handler_stack.ss_size = kHandlerStackSize;
+ internal_sigaltstack(&handler_stack, nullptr);
+
+ // Install our handler for synchronous signals. Other signals should be
+ // blocked by the mask we inherited from the parent thread.
+ for (uptr i = 0; i < ARRAY_SIZE(kSyncSignals); i++) {
+ __sanitizer_sigaction act;
+ internal_memset(&act, 0, sizeof(act));
+ act.sigaction = TracerThreadSignalHandler;
+ act.sa_flags = SA_ONSTACK | SA_SIGINFO;
+ internal_sigaction_norestorer(kSyncSignals[i], &act, 0);
+ }
+
+ int exit_code = 0;
+ if (!thread_suspender.SuspendAllThreads()) {
+ VReport(1, "Failed suspending threads.\n");
+ exit_code = 3;
+ } else {
+ tracer_thread_argument->callback(thread_suspender.suspended_threads_list(),
+ tracer_thread_argument->callback_argument);
+ thread_suspender.ResumeAllThreads();
+ exit_code = 0;
+ }
+ RAW_CHECK(RemoveDieCallback(TracerThreadDieCallback));
+ thread_suspender_instance = nullptr;
+ atomic_store(&tracer_thread_argument->done, 1, memory_order_relaxed);
+ return exit_code;
+}
+
+class ScopedStackSpaceWithGuard {
+ public:
+ explicit ScopedStackSpaceWithGuard(uptr stack_size) {
+ stack_size_ = stack_size;
+ guard_size_ = GetPageSizeCached();
+ // FIXME: Omitting MAP_STACK here works in current kernels but might break
+ // in the future.
+ guard_start_ =
+ (uptr)MmapOrDie(stack_size_ + guard_size_, "ScopedStackWithGuard");
+ CHECK(MprotectNoAccess((uptr)guard_start_, guard_size_));
+ }
+ ~ScopedStackSpaceWithGuard() {
+ UnmapOrDie((void *)guard_start_, stack_size_ + guard_size_);
+ }
+ void *Bottom() const {
+ return (void *)(guard_start_ + stack_size_ + guard_size_);
+ }
+
+ private:
+ uptr stack_size_;
+ uptr guard_size_;
+ uptr guard_start_;
+};
+
+static __sanitizer_sigset_t blocked_sigset;
+static __sanitizer_sigset_t old_sigset;
+
+struct ScopedSetTracerPID {
+ explicit ScopedSetTracerPID(uptr tracer_pid) {
+ stoptheworld_tracer_pid = tracer_pid;
+ stoptheworld_tracer_ppid = internal_getpid();
+ }
+ ~ScopedSetTracerPID() {
+ stoptheworld_tracer_pid = 0;
+ stoptheworld_tracer_ppid = 0;
+ }
+};
+
+void StopTheWorld(StopTheWorldCallback callback, void *argument) {
+ // Prepare the arguments for TracerThread.
+ struct TracerThreadArgument tracer_thread_argument;
+ tracer_thread_argument.callback = callback;
+ tracer_thread_argument.callback_argument = argument;
+ tracer_thread_argument.parent_pid = internal_getpid();
+ atomic_store(&tracer_thread_argument.done, 0, memory_order_relaxed);
+ const uptr kTracerStackSize = 2 * 1024 * 1024;
+ ScopedStackSpaceWithGuard tracer_stack(kTracerStackSize);
+
+ tracer_thread_argument.mutex.Lock();
+
+ internal_sigfillset(&blocked_sigset);
+ for (uptr i = 0; i < ARRAY_SIZE(kSyncSignals); i++)
+ internal_sigdelset(&blocked_sigset, kSyncSignals[i]);
+ int rv = internal_sigprocmask(SIG_BLOCK, &blocked_sigset, &old_sigset);
+ CHECK_EQ(rv, 0);
+ uptr tracer_pid = internal_clone(TracerThread, tracer_stack.Bottom(),
+ CLONE_VM | CLONE_FS | CLONE_FILES,
+ &tracer_thread_argument);
+ internal_sigprocmask(SIG_SETMASK, &old_sigset, 0);
+ int local_errno = 0;
+ if (internal_iserror(tracer_pid, &local_errno)) {
+ VReport(1, "Failed spawning a tracer thread (errno %d).\n", local_errno);
+ tracer_thread_argument.mutex.Unlock();
+ } else {
+ ScopedSetTracerPID scoped_set_tracer_pid(tracer_pid);
+
+ tracer_thread_argument.mutex.Unlock();
+
+ while (atomic_load(&tracer_thread_argument.done, memory_order_relaxed) == 0)
+ sched_yield();
+
+ for (;;) {
+ uptr waitpid_status = internal_waitpid(tracer_pid, nullptr, __WALL);
+ if (!internal_iserror(waitpid_status, &local_errno))
+ break;
+ if (local_errno == EINTR)
+ continue;
+ VReport(1, "Waiting on the tracer thread failed (errno %d).\n",
+ local_errno);
+ break;
+ }
+ }
+}
+
+tid_t SuspendedThreadsListNetBSD::GetThreadID(uptr index) const {
+ CHECK_LT(index, thread_ids_.size());
+ return thread_ids_[index];
+}
+
+uptr SuspendedThreadsListNetBSD::ThreadCount() const {
+ return thread_ids_.size();
+}
+
+bool SuspendedThreadsListNetBSD::ContainsTid(tid_t thread_id) const {
+ for (uptr i = 0; i < thread_ids_.size(); i++) {
+ if (thread_ids_[i] == thread_id)
+ return true;
+ }
+ return false;
+}
+
+void SuspendedThreadsListNetBSD::Append(tid_t tid) {
+ thread_ids_.push_back(tid);
+}
+
+PtraceRegistersStatus SuspendedThreadsListNetBSD::GetRegistersAndSP(
+ uptr index, uptr *buffer, uptr *sp) const {
+ lwpid_t tid = GetThreadID(index);
+ pid_t ppid = internal_getppid();
+ struct reg regs;
+ int pterrno;
+ bool isErr =
+ internal_iserror(internal_ptrace(PT_GETREGS, ppid, &regs, tid), &pterrno);
+ if (isErr) {
+ VReport(1,
+ "Could not get registers from process %d thread %d (errno %d).\n",
+ ppid, tid, pterrno);
+ return pterrno == ESRCH ? REGISTERS_UNAVAILABLE_FATAL
+ : REGISTERS_UNAVAILABLE;
+ }
+
+ *sp = PTRACE_REG_SP(&regs);
+ internal_memcpy(buffer, &regs, sizeof(regs));
+
+ return REGISTERS_AVAILABLE;
+}
+
+uptr SuspendedThreadsListNetBSD::RegisterCount() const {
+ return sizeof(struct reg) / sizeof(uptr);
+}
+} // namespace __sanitizer
+
+#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_suppressions.cc b/libsanitizer/sanitizer_common/sanitizer_suppressions.cpp
index 6c682a1..44c83a6 100644
--- a/libsanitizer/sanitizer_common/sanitizer_suppressions.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_suppressions.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_suppressions.cc -----------------------------------------===//
+//===-- sanitizer_suppressions.cpp ----------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -29,6 +30,7 @@ SuppressionContext::SuppressionContext(const char *suppression_types[],
internal_memset(has_suppression_type_, 0, suppression_types_num_);
}
+#if !SANITIZER_FUCHSIA
static bool GetPathAssumingFileIsRelativeToExec(const char *file_path,
/*out*/char *new_file_path,
uptr new_file_path_size) {
@@ -45,20 +47,30 @@ static bool GetPathAssumingFileIsRelativeToExec(const char *file_path,
return false;
}
+static const char *FindFile(const char *file_path,
+ /*out*/char *new_file_path,
+ uptr new_file_path_size) {
+ // If we cannot find the file, check if its location is relative to
+ // the location of the executable.
+ if (!FileExists(file_path) && !IsAbsolutePath(file_path) &&
+ GetPathAssumingFileIsRelativeToExec(file_path, new_file_path,
+ new_file_path_size)) {
+ return new_file_path;
+ }
+ return file_path;
+}
+#else
+static const char *FindFile(const char *file_path, char *, uptr) {
+ return file_path;
+}
+#endif
+
void SuppressionContext::ParseFromFile(const char *filename) {
if (filename[0] == '\0')
return;
-#if !SANITIZER_FUCHSIA
- // If we cannot find the file, check if its location is relative to
- // the location of the executable.
InternalScopedString new_file_path(kMaxPathLength);
- if (!FileExists(filename) && !IsAbsolutePath(filename) &&
- GetPathAssumingFileIsRelativeToExec(filename, new_file_path.data(),
- new_file_path.size())) {
- filename = new_file_path.data();
- }
-#endif // !SANITIZER_FUCHSIA
+ filename = FindFile(filename, new_file_path.data(), new_file_path.size());
// Read the file.
VPrintf(1, "%s: reading suppressions file at %s\n",
@@ -92,7 +104,7 @@ bool SuppressionContext::Match(const char *str, const char *type,
}
static const char *StripPrefix(const char *str, const char *prefix) {
- while (str && *str == *prefix) {
+ while (*str && *str == *prefix) {
str++;
prefix++;
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_suppressions.h b/libsanitizer/sanitizer_common/sanitizer_suppressions.h
index ed6d7ba..f9da7af 100644
--- a/libsanitizer/sanitizer_common/sanitizer_suppressions.h
+++ b/libsanitizer/sanitizer_common/sanitizer_suppressions.h
@@ -1,7 +1,8 @@
//===-- sanitizer_suppressions.h --------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer.cpp
index 9d3e011..ce2ece5f 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_symbolizer.cc -------------------------------------------===//
+//===-- sanitizer_symbolizer.cpp ------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -65,6 +66,16 @@ void DataInfo::Clear() {
internal_memset(this, 0, sizeof(DataInfo));
}
+void FrameInfo::Clear() {
+ InternalFree(module);
+ for (LocalInfo &local : locals) {
+ InternalFree(local.function_name);
+ InternalFree(local.name);
+ InternalFree(local.decl_file);
+ }
+ locals.clear();
+}
+
Symbolizer *Symbolizer::symbolizer_;
StaticSpinMutex Symbolizer::init_mu_;
LowLevelAllocator Symbolizer::symbolizer_allocator_;
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer.h
index ef2fb4a..51648e2 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer.h
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer.h
@@ -1,7 +1,8 @@
//===-- sanitizer_symbolizer.h ----------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -19,6 +20,7 @@
#include "sanitizer_common.h"
#include "sanitizer_mutex.h"
+#include "sanitizer_vector.h"
namespace __sanitizer {
@@ -76,6 +78,32 @@ struct DataInfo {
void Clear();
};
+struct LocalInfo {
+ char *function_name = nullptr;
+ char *name = nullptr;
+ char *decl_file = nullptr;
+ unsigned decl_line = 0;
+
+ bool has_frame_offset = false;
+ bool has_size = false;
+ bool has_tag_offset = false;
+
+ sptr frame_offset;
+ uptr size;
+ uptr tag_offset;
+
+ void Clear();
+};
+
+struct FrameInfo {
+ char *module;
+ uptr module_offset;
+ ModuleArch module_arch;
+
+ InternalMmapVector<LocalInfo> locals;
+ void Clear();
+};
+
class SymbolizerTool;
class Symbolizer final {
@@ -88,6 +116,7 @@ class Symbolizer final {
// all inlined functions, if necessary).
SymbolizedStack *SymbolizePC(uptr address);
bool SymbolizeData(uptr address, DataInfo *info);
+ bool SymbolizeFrame(uptr address, FrameInfo *info);
// The module names Symbolizer returns are stable and unique for every given
// module. It is safe to store and compare them as pointers.
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.h
index 2f68075..c4061e3 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.h
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.h
@@ -1,7 +1,8 @@
//===-- sanitizer_symbolizer_fuchsia.h -----------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -33,6 +34,9 @@ constexpr const char *kFormatData = "{{{data:%p}}}";
// One frame in a backtrace (printed on a line by itself).
constexpr const char *kFormatFrame = "{{{bt:%u:%p}}}";
+// Dump trigger element.
+#define FORMAT_DUMPFILE "{{{dumpfile:%s:%s}}}"
+
} // namespace __sanitizer
#endif // SANITIZER_SYMBOLIZER_FUCHSIA_H
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h
index eae7509..3031f28 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h
@@ -1,7 +1,8 @@
//===-- sanitizer_symbolizer_internal.h -------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -14,6 +15,7 @@
#include "sanitizer_symbolizer.h"
#include "sanitizer_file.h"
+#include "sanitizer_vector.h"
namespace __sanitizer {
@@ -57,6 +59,10 @@ class SymbolizerTool {
UNIMPLEMENTED();
}
+ virtual bool SymbolizeFrame(uptr addr, FrameInfo *info) {
+ return false;
+ }
+
virtual void Flush() {}
// Return nullptr to fallback to the default platform-specific demangler.
@@ -74,26 +80,27 @@ class SymbolizerProcess {
const char *SendCommand(const char *command);
protected:
+ /// The maximum number of arguments required to invoke a tool process.
+ static const unsigned kArgVMax = 6;
+
+ // Customizable by subclasses.
+ virtual bool StartSymbolizerSubprocess();
+ virtual bool ReadFromSymbolizer(char *buffer, uptr max_length);
+
+ private:
virtual bool ReachedEndOfOutput(const char *buffer, uptr length) const {
UNIMPLEMENTED();
}
- /// The maximum number of arguments required to invoke a tool process.
- enum { kArgVMax = 6 };
-
/// Fill in an argv array to invoke the child process.
virtual void GetArgV(const char *path_to_binary,
const char *(&argv)[kArgVMax]) const {
UNIMPLEMENTED();
}
- virtual bool ReadFromSymbolizer(char *buffer, uptr max_length);
-
- private:
bool Restart();
const char *SendCommandImpl(const char *command);
bool WriteToSymbolizer(const char *buffer, uptr length);
- bool StartSymbolizerSubprocess();
const char *path_;
fd_t input_fd_;
@@ -119,12 +126,13 @@ class LLVMSymbolizer : public SymbolizerTool {
explicit LLVMSymbolizer(const char *path, LowLevelAllocator *allocator);
bool SymbolizePC(uptr addr, SymbolizedStack *stack) override;
-
bool SymbolizeData(uptr addr, DataInfo *info) override;
+ bool SymbolizeFrame(uptr addr, FrameInfo *info) override;
private:
- const char *FormatAndSendCommand(bool is_data, const char *module_name,
- uptr module_offset, ModuleArch arch);
+ const char *FormatAndSendCommand(const char *command_prefix,
+ const char *module_name, uptr module_offset,
+ ModuleArch arch);
LLVMSymbolizerProcess *symbolizer_process_;
static const uptr kBufferSize = 16 * 1024;
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cpp
index eebc30b..27ed222 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_symbolizer_libbacktrace.cc ------------------------------===//
+//===-- sanitizer_symbolizer_libbacktrace.cpp -----------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.h
index ab1d6f9..e2a0f71 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.h
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.h
@@ -1,7 +1,8 @@
//===-- sanitizer_symbolizer_libbacktrace.h ---------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
index 9e57bb6..742b974 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_symbolizer_libcdep.cc -----------------------------------===//
+//===-- sanitizer_symbolizer_libcdep.cpp ----------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -24,7 +25,7 @@ Symbolizer *Symbolizer::GetOrInit() {
return symbolizer_;
}
-// See sanitizer_symbolizer_markup.cc.
+// See sanitizer_symbolizer_markup.cpp.
#if !SANITIZER_SYMBOLIZER_MARKUP
const char *ExtractToken(const char *str, const char *delims, char **result) {
@@ -57,6 +58,16 @@ const char *ExtractUptr(const char *str, const char *delims, uptr *result) {
return ret;
}
+const char *ExtractSptr(const char *str, const char *delims, sptr *result) {
+ char *buff;
+ const char *ret = ExtractToken(str, delims, &buff);
+ if (buff != 0) {
+ *result = (sptr)internal_atoll(buff);
+ }
+ InternalFree(buff);
+ return ret;
+}
+
const char *ExtractTokenUpToDelimiter(const char *str, const char *delimiter,
char **result) {
const char *found_delimiter = internal_strstr(str, delimiter);
@@ -111,6 +122,22 @@ bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) {
return true;
}
+bool Symbolizer::SymbolizeFrame(uptr addr, FrameInfo *info) {
+ BlockingMutexLock l(&mu_);
+ const char *module_name;
+ if (!FindModuleNameAndOffsetForAddress(
+ addr, &module_name, &info->module_offset, &info->module_arch))
+ return false;
+ info->module = internal_strdup(module_name);
+ for (auto &tool : tools_) {
+ SymbolizerScope sym_scope(this);
+ if (tool.SymbolizeFrame(addr, info)) {
+ return true;
+ }
+ }
+ return true;
+}
+
bool Symbolizer::GetModuleNameAndOffsetForPC(uptr pc, const char **module_name,
uptr *module_address) {
BlockingMutexLock l(&mu_);
@@ -342,10 +369,38 @@ void ParseSymbolizeDataOutput(const char *str, DataInfo *info) {
str = ExtractUptr(str, "\n", &info->size);
}
+static void ParseSymbolizeFrameOutput(const char *str,
+ InternalMmapVector<LocalInfo> *locals) {
+ if (internal_strncmp(str, "??", 2) == 0)
+ return;
+
+ while (*str) {
+ LocalInfo local;
+ str = ExtractToken(str, "\n", &local.function_name);
+ str = ExtractToken(str, "\n", &local.name);
+
+ AddressInfo addr;
+ str = ParseFileLineInfo(&addr, str);
+ local.decl_file = addr.file;
+ local.decl_line = addr.line;
+
+ local.has_frame_offset = internal_strncmp(str, "??", 2) != 0;
+ str = ExtractSptr(str, " ", &local.frame_offset);
+
+ local.has_size = internal_strncmp(str, "??", 2) != 0;
+ str = ExtractUptr(str, " ", &local.size);
+
+ local.has_tag_offset = internal_strncmp(str, "??", 2) != 0;
+ str = ExtractUptr(str, "\n", &local.tag_offset);
+
+ locals->push_back(local);
+ }
+}
+
bool LLVMSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
AddressInfo *info = &stack->info;
const char *buf = FormatAndSendCommand(
- /*is_data*/ false, info->module, info->module_offset, info->module_arch);
+ "CODE", info->module, info->module_offset, info->module_arch);
if (buf) {
ParseSymbolizePCOutput(buf, stack);
return true;
@@ -355,7 +410,7 @@ bool LLVMSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) {
bool LLVMSymbolizer::SymbolizeData(uptr addr, DataInfo *info) {
const char *buf = FormatAndSendCommand(
- /*is_data*/ true, info->module, info->module_offset, info->module_arch);
+ "DATA", info->module, info->module_offset, info->module_arch);
if (buf) {
ParseSymbolizeDataOutput(buf, info);
info->start += (addr - info->module_offset); // Add the base address.
@@ -364,22 +419,31 @@ bool LLVMSymbolizer::SymbolizeData(uptr addr, DataInfo *info) {
return false;
}
-const char *LLVMSymbolizer::FormatAndSendCommand(bool is_data,
+bool LLVMSymbolizer::SymbolizeFrame(uptr addr, FrameInfo *info) {
+ const char *buf = FormatAndSendCommand(
+ "FRAME", info->module, info->module_offset, info->module_arch);
+ if (buf) {
+ ParseSymbolizeFrameOutput(buf, &info->locals);
+ return true;
+ }
+ return false;
+}
+
+const char *LLVMSymbolizer::FormatAndSendCommand(const char *command_prefix,
const char *module_name,
uptr module_offset,
ModuleArch arch) {
CHECK(module_name);
- const char *is_data_str = is_data ? "DATA " : "";
if (arch == kModuleArchUnknown) {
- if (internal_snprintf(buffer_, kBufferSize, "%s\"%s\" 0x%zx\n", is_data_str,
- module_name,
+ if (internal_snprintf(buffer_, kBufferSize, "%s \"%s\" 0x%zx\n",
+ command_prefix, module_name,
module_offset) >= static_cast<int>(kBufferSize)) {
Report("WARNING: Command buffer too small");
return nullptr;
}
} else {
- if (internal_snprintf(buffer_, kBufferSize, "%s\"%s:%s\" 0x%zx\n",
- is_data_str, module_name, ModuleArchToString(arch),
+ if (internal_snprintf(buffer_, kBufferSize, "%s \"%s:%s\" 0x%zx\n",
+ command_prefix, module_name, ModuleArchToString(arch),
module_offset) >= static_cast<int>(kBufferSize)) {
Report("WARNING: Command buffer too small");
return nullptr;
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cpp
index 249ccdf..7bc4b0c 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_symbolizer_mac.cc ---------------------------------------===//
+//===-- sanitizer_symbolizer_mac.cpp --------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -56,6 +57,11 @@ class AtosSymbolizerProcess : public SymbolizerProcess {
}
private:
+ virtual bool StartSymbolizerSubprocess() override {
+ // Configure sandbox before starting atos process.
+ return SymbolizerProcess::StartSymbolizerSubprocess();
+ }
+
bool ReachedEndOfOutput(const char *buffer, uptr length) const override {
return (length >= 1 && buffer[length - 1] == '\n');
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.h
index 240c538..6852137 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.h
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.h
@@ -1,7 +1,8 @@
//===-- sanitizer_symbolizer_mac.h ------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_markup.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_markup.cpp
index 3897aab..57b4d0c 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_markup.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_markup.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_symbolizer_markup.cc ------------------------------------===//
+//===-- sanitizer_symbolizer_markup.cpp -----------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -116,7 +117,7 @@ _Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
: _URC_NO_REASON);
}
-void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) {
+void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) {
CHECK_GE(max_depth, 2);
size = 0;
UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)};
@@ -131,9 +132,9 @@ void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) {
trace_buffer[0] = pc;
}
-void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context,
- u32 max_depth) {
- CHECK_NE(context, nullptr);
+void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
+ CHECK(context);
+ CHECK_GE(max_depth, 2);
UNREACHABLE("signal context doesn't exist");
}
#endif // SANITIZER_CAN_SLOW_UNWIND
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
index 750e89e..43e6a6d 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_symbolizer_posix_libcdep.cc -----------------------------===//
+//===-- sanitizer_symbolizer_posix_libcdep.cpp ----------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp
index 1157724..a8b449b 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_symbolizer_report.cc ------------------------------------===//
+//===-- sanitizer_symbolizer_report.cpp -----------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
@@ -102,9 +103,11 @@ void ReportMmapWriteExec(int prot) {
GET_CALLER_PC_BP_SP;
(void)sp;
bool fast = common_flags()->fast_unwind_on_fatal;
- if (fast)
+ if (StackTrace::WillUseFastUnwind(fast)) {
GetThreadStackTopAndBottom(false, &top, &bottom);
- stack->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, fast);
+ stack->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, true);
+ } else
+ stack->Unwind(kStackTraceMax, pc, 0, nullptr, 0, 0, false);
Printf("%s", d.Warning());
Report("WARNING: %s: writable-executable page usage\n", SanitizerToolName);
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_rtems.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_rtems.h
index 2afd01e..3371092 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_rtems.h
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_rtems.h
@@ -1,7 +1,8 @@
//===-- sanitizer_symbolizer_rtems.h -----------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cpp
index 3b45512..2808779 100644
--- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_symbolizer_win.cc ---------------------------------------===//
+//===-- sanitizer_symbolizer_win.cpp --------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -34,6 +35,9 @@ namespace {
class WinSymbolizerTool : public SymbolizerTool {
public:
+ // The constructor is provided to avoid synthesized memsets.
+ WinSymbolizerTool() {}
+
bool SymbolizePC(uptr addr, SymbolizedStack *stack) override;
bool SymbolizeData(uptr addr, DataInfo *info) override {
return false;
diff --git a/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc b/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc
index 0c3b7f9..a43ce3e 100644
--- a/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_syscall_generic.inc ---------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_syscall_linux_aarch64.inc b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_aarch64.inc
index 64d6322..56c5e99 100644
--- a/libsanitizer/sanitizer_common/sanitizer_syscall_linux_aarch64.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_aarch64.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_syscall_linux_aarch64.inc --------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_syscall_linux_arm.inc b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_arm.inc
index 71ac0d5..121a944 100644
--- a/libsanitizer/sanitizer_common/sanitizer_syscall_linux_arm.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_arm.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_syscall_linux_arm.inc -------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_syscall_linux_x86_64.inc b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_x86_64.inc
index b610d66..67e8686 100644
--- a/libsanitizer/sanitizer_common/sanitizer_syscall_linux_x86_64.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_x86_64.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_syscall_linux_x86_64.inc ----------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_syscalls_netbsd.inc b/libsanitizer/sanitizer_common/sanitizer_syscalls_netbsd.inc
index 4fd4d06..21b5216 100644
--- a/libsanitizer/sanitizer_common/sanitizer_syscalls_netbsd.inc
+++ b/libsanitizer/sanitizer_common/sanitizer_syscalls_netbsd.inc
@@ -1,7 +1,8 @@
//===-- sanitizer_syscalls_netbsd.inc ---------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -41,8 +42,8 @@
// DO NOT EDIT! THIS FILE HAS BEEN GENERATED!
//
// Generated with: generate_netbsd_syscalls.awk
-// Generated date: 2018-03-03
-// Generated from: syscalls.master,v 1.291 2018/01/06 16:41:23 kamil Exp
+// Generated date: 2018-10-30
+// Generated from: syscalls.master,v 1.293 2018/07/31 13:00:13 rjs Exp
//
//===----------------------------------------------------------------------===//
@@ -1452,7 +1453,15 @@ PRE_SYSCALL(fpathconf)(long long fd_, long long name_) { /* Nothing to do */ }
POST_SYSCALL(fpathconf)(long long res, long long fd_, long long name_) {
/* Nothing to do */
}
-/* syscall 193 has been skipped */
+PRE_SYSCALL(getsockopt2)
+(long long s_, long long level_, long long name_, void *val_, void *avalsize_) {
+ /* TODO */
+}
+POST_SYSCALL(getsockopt2)
+(long long res, long long s_, long long level_, long long name_, void *val_,
+ void *avalsize_) {
+ /* TODO */
+}
PRE_SYSCALL(getrlimit)(long long which_, void *rlp_) {
PRE_WRITE(rlp_, struct_rlimit_sz);
}
@@ -2339,20 +2348,8 @@ POST_SYSCALL(__sigaction_sigtramp)
PRE_READ(nsa_, sizeof(__sanitizer_sigaction));
}
}
-PRE_SYSCALL(pmc_get_info)(long long ctr_, long long op_, void *args_) {
- /* TODO */
-}
-POST_SYSCALL(pmc_get_info)
-(long long res, long long ctr_, long long op_, void *args_) {
- /* TODO */
-}
-PRE_SYSCALL(pmc_control)(long long ctr_, long long op_, void *args_) {
- /* TODO */
-}
-POST_SYSCALL(pmc_control)
-(long long res, long long ctr_, long long op_, void *args_) {
- /* TODO */
-}
+/* syscall 341 has been skipped */
+/* syscall 342 has been skipped */
PRE_SYSCALL(rasctl)(void *addr_, long long len_, long long op_) {
/* Nothing to do */
}
@@ -3693,18 +3690,18 @@ POST_SYSCALL(recvmmsg)
PRE_SYSCALL(sendmmsg)
(long long s_, void *mmsg_, long long vlen_, long long flags_) {
struct __sanitizer_mmsghdr *mmsg = (struct __sanitizer_mmsghdr *)mmsg_;
- unsigned int vlen = (vlen_ > 1024 ? 1024 : vlen_);
if (mmsg) {
- PRE_READ(mmsg, sizeof(struct __sanitizer_mmsghdr) * vlen);
+ PRE_READ(mmsg, sizeof(struct __sanitizer_mmsghdr) *
+ (vlen_ > 1024 ? 1024 : vlen_));
}
}
POST_SYSCALL(sendmmsg)
(long long res, long long s_, void *mmsg_, long long vlen_, long long flags_) {
struct __sanitizer_mmsghdr *mmsg = (struct __sanitizer_mmsghdr *)mmsg_;
- unsigned int vlen = (vlen_ > 1024 ? 1024 : vlen_);
if (res >= 0) {
if (mmsg) {
- POST_READ(mmsg, sizeof(struct __sanitizer_mmsghdr) * vlen);
+ POST_READ(mmsg, sizeof(struct __sanitizer_mmsghdr) *
+ (vlen_ > 1024 ? 1024 : vlen_));
}
}
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_termination.cc b/libsanitizer/sanitizer_common/sanitizer_termination.cpp
index 79754fa..e588c93 100644
--- a/libsanitizer/sanitizer_common/sanitizer_termination.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_termination.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_termination.cc --------------------------------*- C++ -*-===//
+//===-- sanitizer_termination.cpp -------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
diff --git a/libsanitizer/sanitizer_common/sanitizer_thread_registry.cc b/libsanitizer/sanitizer_common/sanitizer_thread_registry.cpp
index 0ab1ec3..f2c6f27 100644
--- a/libsanitizer/sanitizer_common/sanitizer_thread_registry.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_thread_registry.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_thread_registry.cc --------------------------------------===//
+//===-- sanitizer_thread_registry.cpp -------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -16,8 +17,8 @@ namespace __sanitizer {
ThreadContextBase::ThreadContextBase(u32 tid)
: tid(tid), unique_id(0), reuse_count(), os_id(0), user_id(0),
- status(ThreadStatusInvalid),
- detached(false), workerthread(false), parent_tid(0), next(0) {
+ status(ThreadStatusInvalid), detached(false),
+ thread_type(ThreadType::Regular), parent_tid(0), next(0) {
name[0] = '\0';
atomic_store(&thread_destroyed, 0, memory_order_release);
}
@@ -69,11 +70,11 @@ void ThreadContextBase::SetFinished() {
OnFinished();
}
-void ThreadContextBase::SetStarted(tid_t _os_id, bool _workerthread,
+void ThreadContextBase::SetStarted(tid_t _os_id, ThreadType _thread_type,
void *arg) {
status = ThreadStatusRunning;
os_id = _os_id;
- workerthread = _workerthread;
+ thread_type = _thread_type;
OnStarted(arg);
}
@@ -301,7 +302,7 @@ void ThreadRegistry::FinishThread(u32 tid) {
tctx->SetDestroyed();
}
-void ThreadRegistry::StartThread(u32 tid, tid_t os_id, bool workerthread,
+void ThreadRegistry::StartThread(u32 tid, tid_t os_id, ThreadType thread_type,
void *arg) {
BlockingMutexLock l(&mtx_);
running_threads_++;
@@ -309,7 +310,7 @@ void ThreadRegistry::StartThread(u32 tid, tid_t os_id, bool workerthread,
ThreadContextBase *tctx = threads_[tid];
CHECK_NE(tctx, 0);
CHECK_EQ(ThreadStatusCreated, tctx->status);
- tctx->SetStarted(os_id, workerthread, arg);
+ tctx->SetStarted(os_id, thread_type, arg);
}
void ThreadRegistry::QuarantinePush(ThreadContextBase *tctx) {
@@ -336,4 +337,15 @@ ThreadContextBase *ThreadRegistry::QuarantinePop() {
return tctx;
}
+void ThreadRegistry::SetThreadUserId(u32 tid, uptr user_id) {
+ BlockingMutexLock l(&mtx_);
+ CHECK_LT(tid, n_contexts_);
+ ThreadContextBase *tctx = threads_[tid];
+ CHECK_NE(tctx, 0);
+ CHECK_NE(tctx->status, ThreadStatusInvalid);
+ CHECK_NE(tctx->status, ThreadStatusDead);
+ CHECK_EQ(tctx->user_id, 0);
+ tctx->user_id = user_id;
+}
+
} // namespace __sanitizer
diff --git a/libsanitizer/sanitizer_common/sanitizer_thread_registry.h b/libsanitizer/sanitizer_common/sanitizer_thread_registry.h
index 7dba28c..493aa98 100644
--- a/libsanitizer/sanitizer_common/sanitizer_thread_registry.h
+++ b/libsanitizer/sanitizer_common/sanitizer_thread_registry.h
@@ -1,7 +1,8 @@
//===-- sanitizer_thread_registry.h -----------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -27,6 +28,12 @@ enum ThreadStatus {
ThreadStatusDead // Joined, but some info is still available.
};
+enum class ThreadType {
+ Regular, // Normal thread
+ Worker, // macOS Grand Central Dispatch (GCD) worker thread
+ Fiber, // Fiber
+};
+
// Generic thread context. Specific sanitizer tools may inherit from it.
// If thread is dead, context may optionally be reused for a new thread.
class ThreadContextBase {
@@ -43,7 +50,7 @@ class ThreadContextBase {
ThreadStatus status;
bool detached;
- bool workerthread;
+ ThreadType thread_type;
u32 parent_tid;
ThreadContextBase *next; // For storing thread contexts in a list.
@@ -55,7 +62,7 @@ class ThreadContextBase {
void SetDead();
void SetJoined(void *arg);
void SetFinished();
- void SetStarted(tid_t _os_id, bool _workerthread, void *arg);
+ void SetStarted(tid_t _os_id, ThreadType _thread_type, void *arg);
void SetCreated(uptr _user_id, u64 _unique_id, bool _detached,
u32 _parent_tid, void *arg);
void Reset();
@@ -119,7 +126,8 @@ class ThreadRegistry {
void DetachThread(u32 tid, void *arg);
void JoinThread(u32 tid, void *arg);
void FinishThread(u32 tid);
- void StartThread(u32 tid, tid_t os_id, bool workerthread, void *arg);
+ void StartThread(u32 tid, tid_t os_id, ThreadType thread_type, void *arg);
+ void SetThreadUserId(u32 tid, uptr user_id);
private:
const ThreadContextFactory context_factory_;
diff --git a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cc b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cpp
index f1482c2..9ca898a 100644
--- a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_tls_get_addr.cc -----------------------------------------===//
+//===-- sanitizer_tls_get_addr.cpp ----------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.h b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.h
index 19c8472..c7cd5a8 100644
--- a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.h
+++ b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.h
@@ -1,7 +1,8 @@
//===-- sanitizer_tls_get_addr.h --------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -41,7 +42,7 @@ struct DTLS {
uptr dtv_size;
DTV *dtv; // dtv_size elements, allocated by MmapOrDie.
- // Auxiliary fields, don't access them outside sanitizer_tls_get_addr.cc
+ // Auxiliary fields, don't access them outside sanitizer_tls_get_addr.cpp
uptr last_memalign_size;
uptr last_memalign_ptr;
};
diff --git a/libsanitizer/sanitizer_common/sanitizer_type_traits.cpp b/libsanitizer/sanitizer_common/sanitizer_type_traits.cpp
new file mode 100644
index 0000000..5ee37d7
--- /dev/null
+++ b/libsanitizer/sanitizer_common/sanitizer_type_traits.cpp
@@ -0,0 +1,20 @@
+//===-- sanitizer_type_traits.cpp -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements a subset of C++ type traits. This is so we can avoid depending
+// on system C++ headers.
+//
+//===----------------------------------------------------------------------===//
+#include "sanitizer_type_traits.h"
+
+namespace __sanitizer {
+
+const bool true_type::value;
+const bool false_type::value;
+
+} // namespace __sanitizer
diff --git a/libsanitizer/sanitizer_common/sanitizer_type_traits.h b/libsanitizer/sanitizer_common/sanitizer_type_traits.h
new file mode 100644
index 0000000..2a58d98
--- /dev/null
+++ b/libsanitizer/sanitizer_common/sanitizer_type_traits.h
@@ -0,0 +1,62 @@
+//===-- sanitizer_type_traits.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements a subset of C++ type traits. This is so we can avoid depending
+// on system C++ headers.
+//
+//===----------------------------------------------------------------------===//
+#ifndef SANITIZER_TYPE_TRAITS_H
+#define SANITIZER_TYPE_TRAITS_H
+
+namespace __sanitizer {
+
+struct true_type {
+ static const bool value = true;
+};
+
+struct false_type {
+ static const bool value = false;
+};
+
+// is_same<T, U>
+//
+// Type trait to compare if types are the same.
+// E.g.
+//
+// ```
+// is_same<int,int>::value - True
+// is_same<int,char>::value - False
+// ```
+template <typename T, typename U>
+struct is_same : public false_type {};
+
+template <typename T>
+struct is_same<T, T> : public true_type {};
+
+// conditional<B, T, F>
+//
+// Defines type as T if B is true or as F otherwise.
+// E.g. the following is true
+//
+// ```
+// is_same<int, conditional<true, int, double>::type>::value
+// is_same<double, conditional<false, int, double>::type>::value
+// ```
+template <bool B, class T, class F>
+struct conditional {
+ using type = T;
+};
+
+template <class T, class F>
+struct conditional<false, T, F> {
+ using type = F;
+};
+
+} // namespace __sanitizer
+
+#endif
diff --git a/libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp
index 44f12c4..1a43759 100644
--- a/libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_unwind_linux_libcdep.cc ---------------------------------===//
+//===-- sanitizer_unwind_linux_libcdep.cpp --------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -26,7 +27,7 @@
namespace __sanitizer {
-//------------------------- SlowUnwindStack -----------------------------------
+//---------------------------- UnwindSlow --------------------------------------
typedef struct {
uptr absolute_pc;
@@ -95,7 +96,7 @@ uptr Unwind_GetIP(struct _Unwind_Context *ctx) {
// Clear the Thumb bit.
return val & ~(uptr)1;
#else
- return _Unwind_GetIP(ctx);
+ return (uptr)_Unwind_GetIP(ctx);
#endif
}
@@ -118,7 +119,7 @@ _Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) {
return UNWIND_CONTINUE;
}
-void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) {
+void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) {
CHECK_GE(max_depth, 2);
size = 0;
UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)};
@@ -143,11 +144,11 @@ void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) {
#endif
}
-void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context,
- u32 max_depth) {
+void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
+ CHECK(context);
CHECK_GE(max_depth, 2);
if (!unwind_backtrace_signal_arch) {
- SlowUnwindStack(pc, max_depth);
+ UnwindSlow(pc, max_depth);
return;
}
diff --git a/libsanitizer/sanitizer_common/sanitizer_unwind_win.cc b/libsanitizer/sanitizer_common/sanitizer_unwind_win.cpp
index 8ea62fa..8e06940 100644
--- a/libsanitizer/sanitizer_common/sanitizer_unwind_win.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_unwind_win.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_unwind_win.cc -------------------------------------------===//
+//===-- sanitizer_unwind_win.cpp ------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -23,7 +24,7 @@
using namespace __sanitizer;
#if !SANITIZER_GO
-void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) {
+void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) {
CHECK_GE(max_depth, 2);
// FIXME: CaptureStackBackTrace might be too slow for us.
// FIXME: Compare with StackWalk64.
@@ -38,8 +39,9 @@ void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) {
PopStackFrames(pc_location);
}
-void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context,
- u32 max_depth) {
+void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) {
+ CHECK(context);
+ CHECK_GE(max_depth, 2);
CONTEXT ctx = *(CONTEXT *)context;
STACKFRAME64 stack_frame;
memset(&stack_frame, 0, sizeof(stack_frame));
diff --git a/libsanitizer/sanitizer_common/sanitizer_vector.h b/libsanitizer/sanitizer_common/sanitizer_vector.h
index ad6510b..4b9ae7d 100644
--- a/libsanitizer/sanitizer_common/sanitizer_vector.h
+++ b/libsanitizer/sanitizer_common/sanitizer_vector.h
@@ -1,7 +1,8 @@
//===-- sanitizer_vector.h -------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_win.cc b/libsanitizer/sanitizer_common/sanitizer_win.cpp
index ebc6c50..c98e3d4 100644
--- a/libsanitizer/sanitizer_common/sanitizer_win.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_win.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_win.cc --------------------------------------------------===//
+//===-- sanitizer_win.cpp -------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -30,6 +31,18 @@
#if defined(PSAPI_VERSION) && PSAPI_VERSION == 1
#pragma comment(lib, "psapi")
#endif
+#if SANITIZER_WIN_TRACE
+#include <traceloggingprovider.h>
+// Windows trace logging provider init
+#pragma comment(lib, "advapi32.lib")
+TRACELOGGING_DECLARE_PROVIDER(g_asan_provider);
+// GUID must be the same in utils/AddressSanitizerLoggingProvider.wprp
+TRACELOGGING_DEFINE_PROVIDER(g_asan_provider, "AddressSanitizerLoggingProvider",
+ (0x6c6c766d, 0x3846, 0x4e6a, 0xa4, 0xfb, 0x5b,
+ 0x53, 0x0b, 0xd0, 0xf3, 0xfa));
+#else
+#define TraceLoggingUnregister(x)
+#endif
// A macro to tell the compiler that this part of the code cannot be reached,
// if the compiler supports this feature. Since we're using this in
@@ -228,7 +241,7 @@ bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) {
// Memory space mapped by 'MmapFixedOrDie' must have been reserved by
// 'MmapFixedNoAccess'.
-void *MmapFixedOrDie(uptr fixed_addr, uptr size) {
+void *MmapFixedOrDie(uptr fixed_addr, uptr size, const char *name) {
void *p = VirtualAlloc((LPVOID)fixed_addr, size,
MEM_COMMIT, PAGE_READWRITE);
if (p == 0) {
@@ -242,11 +255,12 @@ void *MmapFixedOrDie(uptr fixed_addr, uptr size) {
// Uses fixed_addr for now.
// Will use offset instead once we've implemented this function for real.
-uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size) {
+uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size, const char *name) {
return reinterpret_cast<uptr>(MmapFixedOrDieOnFatalError(fixed_addr, size));
}
-uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr size) {
+uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr size,
+ const char *name) {
return reinterpret_cast<uptr>(MmapFixedOrDie(fixed_addr, size));
}
@@ -259,7 +273,7 @@ void ReservedAddressRange::Unmap(uptr addr, uptr size) {
UnmapOrDie(reinterpret_cast<void*>(addr), size);
}
-void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size) {
+void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size, const char *name) {
void *p = VirtualAlloc((LPVOID)fixed_addr, size,
MEM_COMMIT, PAGE_READWRITE);
if (p == 0) {
@@ -315,9 +329,8 @@ void ReleaseMemoryPagesToOS(uptr beg, uptr end) {
// FIXME: add madvise-analog when we move to 64-bits.
}
-bool NoHugePagesInRegion(uptr addr, uptr size) {
+void SetShadowRegionHugePageMode(uptr addr, uptr size) {
// FIXME: probably similar to ReleaseMemoryToOS.
- return true;
}
bool DontDumpShadowMemory(uptr addr, uptr length) {
@@ -485,8 +498,14 @@ bool IsPathSeparator(const char c) {
return c == '\\' || c == '/';
}
+static bool IsAlpha(char c) {
+ c = ToLower(c);
+ return c >= 'a' && c <= 'z';
+}
+
bool IsAbsolutePath(const char *path) {
- UNIMPLEMENTED();
+ return path != nullptr && IsAlpha(path[0]) && path[1] == ':' &&
+ IsPathSeparator(path[2]);
}
void SleepForSeconds(int seconds) {
@@ -644,6 +663,7 @@ int Atexit(void (*function)(void)) {
}
static int RunAtexit() {
+ TraceLoggingUnregister(g_asan_provider);
int ret = 0;
for (uptr i = 0; i < atexit_functions.size(); ++i) {
ret |= atexit(atexit_functions[i]);
@@ -735,16 +755,13 @@ bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written,
}
}
-bool RenameFile(const char *oldpath, const char *newpath, error_t *error_p) {
- UNIMPLEMENTED();
-}
-
uptr internal_sched_yield() {
Sleep(0);
return 0;
}
void internal__exit(int exitcode) {
+ TraceLoggingUnregister(g_asan_provider);
// ExitProcess runs some finalizers, so use TerminateProcess to avoid that.
// The debugger doesn't stop on TerminateProcess like it does on ExitProcess,
// so add our own breakpoint here.
@@ -1006,6 +1023,10 @@ void CheckVMASize() {
// Do nothing.
}
+void InitializePlatformEarly() {
+ // Do nothing.
+}
+
void MaybeReexec() {
// No need to re-exec on Windows.
}
@@ -1014,17 +1035,26 @@ void CheckASLR() {
// Do nothing
}
+void CheckMPROTECT() {
+ // Do nothing
+}
+
char **GetArgv() {
// FIXME: Actually implement this function.
return 0;
}
+char **GetEnviron() {
+ // FIXME: Actually implement this function.
+ return 0;
+}
+
pid_t StartSubprocess(const char *program, const char *const argv[],
fd_t stdin_fd, fd_t stdout_fd, fd_t stderr_fd) {
// FIXME: implement on this platform
// Should be implemented based on
// SymbolizerProcess::StarAtSymbolizerSubprocess
- // from lib/sanitizer_common/sanitizer_symbolizer_win.cc.
+ // from lib/sanitizer_common/sanitizer_symbolizer_win.cpp.
return -1;
}
@@ -1053,6 +1083,32 @@ u32 GetNumberOfCPUs() {
return sysinfo.dwNumberOfProcessors;
}
+#if SANITIZER_WIN_TRACE
+// TODO(mcgov): Rename this project-wide to PlatformLogInit
+void AndroidLogInit(void) {
+ HRESULT hr = TraceLoggingRegister(g_asan_provider);
+ if (!SUCCEEDED(hr))
+ return;
+}
+
+void SetAbortMessage(const char *) {}
+
+void LogFullErrorReport(const char *buffer) {
+ if (common_flags()->log_to_syslog) {
+ InternalMmapVector<wchar_t> filename;
+ DWORD filename_length = 0;
+ do {
+ filename.resize(filename.size() + 0x100);
+ filename_length =
+ GetModuleFileNameW(NULL, filename.begin(), filename.size());
+ } while (filename_length >= filename.size());
+ TraceLoggingWrite(g_asan_provider, "AsanReportEvent",
+ TraceLoggingValue(filename.begin(), "ExecutableName"),
+ TraceLoggingValue(buffer, "AsanReportContents"));
+ }
+}
+#endif // SANITIZER_WIN_TRACE
+
} // namespace __sanitizer
#endif // _WIN32
diff --git a/libsanitizer/sanitizer_common/sanitizer_win.h b/libsanitizer/sanitizer_common/sanitizer_win.h
index c2d53a4..ff8939c 100644
--- a/libsanitizer/sanitizer_common/sanitizer_win.h
+++ b/libsanitizer/sanitizer_common/sanitizer_win.h
@@ -1,7 +1,8 @@
//===-- sanitizer_win.h -----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_win_defs.h b/libsanitizer/sanitizer_common/sanitizer_win_defs.h
index 1b1a86c..bcd94a0 100644
--- a/libsanitizer/sanitizer_common/sanitizer_win_defs.h
+++ b/libsanitizer/sanitizer_common/sanitizer_win_defs.h
@@ -1,7 +1,8 @@
//===-- sanitizer_win_defs.h ------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.cc b/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.cpp
index 6577a36..aa0eb4d 100644
--- a/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_win_dll_thunk.cc ----------------------------------------===//
+//===-- sanitizer_win_dll_thunk.cpp ---------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// This file defines a family of thunks that should be statically linked into
diff --git a/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.h b/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.h
index 5a475e0..48c73c4 100644
--- a/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.h
+++ b/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.h
@@ -1,7 +1,8 @@
//===-- sanitizer_win_dll_thunk.h -----------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// This header provide helper macros to delegate calls to the shared runtime
diff --git a/libsanitizer/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cc b/libsanitizer/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cpp
index f3b3037..87c032c 100644
--- a/libsanitizer/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cpp
@@ -1,7 +1,8 @@
-//===-- santizer_win_dynamic_runtime_thunk.cc -----------------------------===//
+//===-- santizer_win_dynamic_runtime_thunk.cpp ----------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -17,3 +18,9 @@
#define INTERFACE_WEAK_FUNCTION(Name) WIN_WEAK_IMPORT_DEF(Name)
#include "sanitizer_common_interface.inc"
#endif // SANITIZER_DYNAMIC_RUNTIME_THUNK
+
+namespace __sanitizer {
+// Add one, otherwise unused, external symbol to this object file so that the
+// Visual C++ linker includes it and reads the .drective section.
+void ForceWholeArchiveIncludeForSanitizerCommon() {}
+}
diff --git a/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cc b/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cpp
index 3ee428b..a6f34c2 100644
--- a/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cpp
@@ -1,7 +1,8 @@
-//===-- sanitizer_win_weak_interception.cc --------------------------------===//
+//===-- sanitizer_win_weak_interception.cpp -------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// This module should be included in the sanitizer when it is implemented as a
diff --git a/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.h b/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.h
index 873f9b8..5e4d8b8 100644
--- a/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.h
+++ b/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.h
@@ -1,7 +1,8 @@
//===-- sanitizer_win_weak_interception.h ---------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// This header provide helper macros to delegate calls of weak functions to the
diff --git a/libsanitizer/tsan/Makefile.am b/libsanitizer/tsan/Makefile.am
index 753cb8f..1ca9b68 100644
--- a/libsanitizer/tsan/Makefile.am
+++ b/libsanitizer/tsan/Makefile.am
@@ -14,40 +14,39 @@ toolexeclib_LTLIBRARIES = libtsan.la
nodist_toolexeclib_HEADERS = libtsan_preinit.o
tsan_files = \
- tsan_clock.cc \
- tsan_debugging.cc \
- tsan_external.cc \
- tsan_fd.cc \
- tsan_flags.cc \
- tsan_ignoreset.cc \
- tsan_interceptors.cc \
- tsan_interceptors_mac.cc \
- tsan_interface_ann.cc \
- tsan_interface_atomic.cc \
- tsan_interface.cc \
- tsan_interface_java.cc \
- tsan_libdispatch_mac.cc \
- tsan_malloc_mac.cc \
- tsan_md5.cc \
- tsan_mman.cc \
- tsan_mutex.cc \
- tsan_mutexset.cc \
- tsan_new_delete.cc \
- tsan_platform_linux.cc \
- tsan_platform_mac.cc \
- tsan_platform_posix.cc \
- tsan_platform_windows.cc \
- tsan_report.cc \
- tsan_rtl.cc \
- tsan_rtl_mutex.cc \
- tsan_rtl_proc.cc \
- tsan_rtl_report.cc \
- tsan_rtl_thread.cc \
- tsan_stack_trace.cc \
- tsan_stat.cc \
- tsan_suppressions.cc \
- tsan_symbolize.cc \
- tsan_sync.cc
+ tsan_clock.cpp \
+ tsan_debugging.cpp \
+ tsan_external.cpp \
+ tsan_fd.cpp \
+ tsan_flags.cpp \
+ tsan_ignoreset.cpp \
+ tsan_interceptors.cpp \
+ tsan_interceptors_mac.cpp \
+ tsan_interface_ann.cpp \
+ tsan_interface_atomic.cpp \
+ tsan_interface.cpp \
+ tsan_interface_java.cpp \
+ tsan_malloc_mac.cpp \
+ tsan_md5.cpp \
+ tsan_mman.cpp \
+ tsan_mutex.cpp \
+ tsan_mutexset.cpp \
+ tsan_new_delete.cpp \
+ tsan_platform_linux.cpp \
+ tsan_platform_mac.cpp \
+ tsan_platform_posix.cpp \
+ tsan_platform_windows.cpp \
+ tsan_report.cpp \
+ tsan_rtl.cpp \
+ tsan_rtl_mutex.cpp \
+ tsan_rtl_proc.cpp \
+ tsan_rtl_report.cpp \
+ tsan_rtl_thread.cpp \
+ tsan_stack_trace.cpp \
+ tsan_stat.cpp \
+ tsan_suppressions.cpp \
+ tsan_symbolize.cpp \
+ tsan_sync.cpp
libtsan_la_SOURCES = $(tsan_files)
EXTRA_libtsan_la_SOURCES = tsan_rtl_amd64.S tsan_rtl_aarch64.S tsan_rtl_mips64.S tsan_rtl_ppc64.S
diff --git a/libsanitizer/tsan/Makefile.in b/libsanitizer/tsan/Makefile.in
index cb4f0f9..cae00ab 100644
--- a/libsanitizer/tsan/Makefile.in
+++ b/libsanitizer/tsan/Makefile.in
@@ -148,10 +148,9 @@ am__objects_1 = tsan_clock.lo tsan_debugging.lo tsan_external.lo \
tsan_fd.lo tsan_flags.lo tsan_ignoreset.lo \
tsan_interceptors.lo tsan_interceptors_mac.lo \
tsan_interface_ann.lo tsan_interface_atomic.lo \
- tsan_interface.lo tsan_interface_java.lo \
- tsan_libdispatch_mac.lo tsan_malloc_mac.lo tsan_md5.lo \
- tsan_mman.lo tsan_mutex.lo tsan_mutexset.lo tsan_new_delete.lo \
- tsan_platform_linux.lo tsan_platform_mac.lo \
+ tsan_interface.lo tsan_interface_java.lo tsan_malloc_mac.lo \
+ tsan_md5.lo tsan_mman.lo tsan_mutex.lo tsan_mutexset.lo \
+ tsan_new_delete.lo tsan_platform_linux.lo tsan_platform_mac.lo \
tsan_platform_posix.lo tsan_platform_windows.lo tsan_report.lo \
tsan_rtl.lo tsan_rtl_mutex.lo tsan_rtl_proc.lo \
tsan_rtl_report.lo tsan_rtl_thread.lo tsan_stack_trace.lo \
@@ -416,40 +415,39 @@ ACLOCAL_AMFLAGS = -I m4
toolexeclib_LTLIBRARIES = libtsan.la
nodist_toolexeclib_HEADERS = libtsan_preinit.o
tsan_files = \
- tsan_clock.cc \
- tsan_debugging.cc \
- tsan_external.cc \
- tsan_fd.cc \
- tsan_flags.cc \
- tsan_ignoreset.cc \
- tsan_interceptors.cc \
- tsan_interceptors_mac.cc \
- tsan_interface_ann.cc \
- tsan_interface_atomic.cc \
- tsan_interface.cc \
- tsan_interface_java.cc \
- tsan_libdispatch_mac.cc \
- tsan_malloc_mac.cc \
- tsan_md5.cc \
- tsan_mman.cc \
- tsan_mutex.cc \
- tsan_mutexset.cc \
- tsan_new_delete.cc \
- tsan_platform_linux.cc \
- tsan_platform_mac.cc \
- tsan_platform_posix.cc \
- tsan_platform_windows.cc \
- tsan_report.cc \
- tsan_rtl.cc \
- tsan_rtl_mutex.cc \
- tsan_rtl_proc.cc \
- tsan_rtl_report.cc \
- tsan_rtl_thread.cc \
- tsan_stack_trace.cc \
- tsan_stat.cc \
- tsan_suppressions.cc \
- tsan_symbolize.cc \
- tsan_sync.cc
+ tsan_clock.cpp \
+ tsan_debugging.cpp \
+ tsan_external.cpp \
+ tsan_fd.cpp \
+ tsan_flags.cpp \
+ tsan_ignoreset.cpp \
+ tsan_interceptors.cpp \
+ tsan_interceptors_mac.cpp \
+ tsan_interface_ann.cpp \
+ tsan_interface_atomic.cpp \
+ tsan_interface.cpp \
+ tsan_interface_java.cpp \
+ tsan_malloc_mac.cpp \
+ tsan_md5.cpp \
+ tsan_mman.cpp \
+ tsan_mutex.cpp \
+ tsan_mutexset.cpp \
+ tsan_new_delete.cpp \
+ tsan_platform_linux.cpp \
+ tsan_platform_mac.cpp \
+ tsan_platform_posix.cpp \
+ tsan_platform_windows.cpp \
+ tsan_report.cpp \
+ tsan_rtl.cpp \
+ tsan_rtl_mutex.cpp \
+ tsan_rtl_proc.cpp \
+ tsan_rtl_report.cpp \
+ tsan_rtl_thread.cpp \
+ tsan_stack_trace.cpp \
+ tsan_stat.cpp \
+ tsan_suppressions.cpp \
+ tsan_symbolize.cpp \
+ tsan_sync.cpp
libtsan_la_SOURCES = $(tsan_files)
EXTRA_libtsan_la_SOURCES = tsan_rtl_amd64.S tsan_rtl_aarch64.S tsan_rtl_mips64.S tsan_rtl_ppc64.S
@@ -506,7 +504,7 @@ MAKEOVERRIDES =
all: all-am
.SUFFIXES:
-.SUFFIXES: .S .cc .lo .o .obj
+.SUFFIXES: .S .cpp .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
@@ -593,7 +591,6 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_interface_ann.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_interface_atomic.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_interface_java.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_libdispatch_mac.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_malloc_mac.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_md5.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_mman.Plo@am__quote@
@@ -641,21 +638,21 @@ distclean-compile:
@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $<
-.cc.o:
+.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
-.cc.obj:
+.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-.cc.lo:
+.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
diff --git a/libsanitizer/tsan/tsan_clock.cc b/libsanitizer/tsan/tsan_clock.cpp
index c2b5b58..4b7aa06 100644
--- a/libsanitizer/tsan/tsan_clock.cc
+++ b/libsanitizer/tsan/tsan_clock.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_clock.cc -----------------------------------------------------===//
+//===-- tsan_clock.cpp ----------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -39,7 +40,7 @@
// release(dst);
// }
//
-// Conformance to this model is extensively verified in tsan_clock_test.cc.
+// Conformance to this model is extensively verified in tsan_clock_test.cpp.
// However, the implementation is significantly more complex. The complexity
// allows to implement important classes of use cases in O(1) instead of O(N).
//
diff --git a/libsanitizer/tsan/tsan_clock.h b/libsanitizer/tsan/tsan_clock.h
index c8eb8ee..6a1d15a 100644
--- a/libsanitizer/tsan/tsan_clock.h
+++ b/libsanitizer/tsan/tsan_clock.h
@@ -1,7 +1,8 @@
//===-- tsan_clock.h --------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_debugging.cc b/libsanitizer/tsan/tsan_debugging.cpp
index 722b6c1..d3d6255 100644
--- a/libsanitizer/tsan/tsan_debugging.cc
+++ b/libsanitizer/tsan/tsan_debugging.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_debugging.cc -------------------------------------------------===//
+//===-- tsan_debugging.cpp ------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -18,31 +19,37 @@
using namespace __tsan;
static const char *ReportTypeDescription(ReportType typ) {
- if (typ == ReportTypeRace) return "data-race";
- if (typ == ReportTypeVptrRace) return "data-race-vptr";
- if (typ == ReportTypeUseAfterFree) return "heap-use-after-free";
- if (typ == ReportTypeVptrUseAfterFree) return "heap-use-after-free-vptr";
- if (typ == ReportTypeExternalRace) return "external-race";
- if (typ == ReportTypeThreadLeak) return "thread-leak";
- if (typ == ReportTypeMutexDestroyLocked) return "locked-mutex-destroy";
- if (typ == ReportTypeMutexDoubleLock) return "mutex-double-lock";
- if (typ == ReportTypeMutexInvalidAccess) return "mutex-invalid-access";
- if (typ == ReportTypeMutexBadUnlock) return "mutex-bad-unlock";
- if (typ == ReportTypeMutexBadReadLock) return "mutex-bad-read-lock";
- if (typ == ReportTypeMutexBadReadUnlock) return "mutex-bad-read-unlock";
- if (typ == ReportTypeSignalUnsafe) return "signal-unsafe-call";
- if (typ == ReportTypeErrnoInSignal) return "errno-in-signal-handler";
- if (typ == ReportTypeDeadlock) return "lock-order-inversion";
- return "";
+ switch (typ) {
+ case ReportTypeRace: return "data-race";
+ case ReportTypeVptrRace: return "data-race-vptr";
+ case ReportTypeUseAfterFree: return "heap-use-after-free";
+ case ReportTypeVptrUseAfterFree: return "heap-use-after-free-vptr";
+ case ReportTypeExternalRace: return "external-race";
+ case ReportTypeThreadLeak: return "thread-leak";
+ case ReportTypeMutexDestroyLocked: return "locked-mutex-destroy";
+ case ReportTypeMutexDoubleLock: return "mutex-double-lock";
+ case ReportTypeMutexInvalidAccess: return "mutex-invalid-access";
+ case ReportTypeMutexBadUnlock: return "mutex-bad-unlock";
+ case ReportTypeMutexBadReadLock: return "mutex-bad-read-lock";
+ case ReportTypeMutexBadReadUnlock: return "mutex-bad-read-unlock";
+ case ReportTypeSignalUnsafe: return "signal-unsafe-call";
+ case ReportTypeErrnoInSignal: return "errno-in-signal-handler";
+ case ReportTypeDeadlock: return "lock-order-inversion";
+ // No default case so compiler warns us if we miss one
+ }
+ UNREACHABLE("missing case");
}
static const char *ReportLocationTypeDescription(ReportLocationType typ) {
- if (typ == ReportLocationGlobal) return "global";
- if (typ == ReportLocationHeap) return "heap";
- if (typ == ReportLocationStack) return "stack";
- if (typ == ReportLocationTLS) return "tls";
- if (typ == ReportLocationFD) return "fd";
- return "";
+ switch (typ) {
+ case ReportLocationGlobal: return "global";
+ case ReportLocationHeap: return "heap";
+ case ReportLocationStack: return "stack";
+ case ReportLocationTLS: return "tls";
+ case ReportLocationFD: return "fd";
+ // No default case so compiler warns us if we miss one
+ }
+ UNREACHABLE("missing case");
}
static void CopyTrace(SymbolizedStack *first_frame, void **trace,
diff --git a/libsanitizer/tsan/tsan_defs.h b/libsanitizer/tsan/tsan_defs.h
index 2c7eda6..293d7de 100644
--- a/libsanitizer/tsan/tsan_defs.h
+++ b/libsanitizer/tsan/tsan_defs.h
@@ -1,7 +1,8 @@
//===-- tsan_defs.h ---------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_dense_alloc.h b/libsanitizer/tsan/tsan_dense_alloc.h
index 197b96f..64fc50e 100644
--- a/libsanitizer/tsan/tsan_dense_alloc.h
+++ b/libsanitizer/tsan/tsan_dense_alloc.h
@@ -1,7 +1,8 @@
//===-- tsan_dense_alloc.h --------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_dispatch_defs.h b/libsanitizer/tsan/tsan_dispatch_defs.h
new file mode 100644
index 0000000..6f1d1f7
--- /dev/null
+++ b/libsanitizer/tsan/tsan_dispatch_defs.h
@@ -0,0 +1,66 @@
+//===-- tsan_dispatch_defs.h ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of ThreadSanitizer (TSan), a race detector.
+//
+//===----------------------------------------------------------------------===//
+#ifndef TSAN_DISPATCH_DEFS_H
+#define TSAN_DISPATCH_DEFS_H
+
+#include "sanitizer_common/sanitizer_internal_defs.h"
+
+typedef struct dispatch_object_s {} *dispatch_object_t;
+
+#define DISPATCH_DECL(name) \
+ typedef struct name##_s : public dispatch_object_s {} *name##_t
+
+DISPATCH_DECL(dispatch_queue);
+DISPATCH_DECL(dispatch_source);
+DISPATCH_DECL(dispatch_group);
+DISPATCH_DECL(dispatch_data);
+DISPATCH_DECL(dispatch_semaphore);
+DISPATCH_DECL(dispatch_io);
+
+typedef void (*dispatch_function_t)(void *arg);
+typedef void (^dispatch_block_t)(void);
+typedef void (^dispatch_io_handler_t)(bool done, dispatch_data_t data,
+ int error);
+
+typedef long dispatch_once_t; // NOLINT
+typedef __sanitizer::u64 dispatch_time_t;
+typedef int dispatch_fd_t; // NOLINT
+typedef unsigned long dispatch_io_type_t; // NOLINT
+typedef unsigned long dispatch_io_close_flags_t; // NOLINT
+
+extern "C" {
+void *dispatch_get_context(dispatch_object_t object);
+void dispatch_retain(dispatch_object_t object);
+void dispatch_release(dispatch_object_t object);
+
+extern const dispatch_block_t _dispatch_data_destructor_free;
+extern const dispatch_block_t _dispatch_data_destructor_munmap;
+} // extern "C"
+
+#define DISPATCH_DATA_DESTRUCTOR_DEFAULT nullptr
+#define DISPATCH_DATA_DESTRUCTOR_FREE _dispatch_data_destructor_free
+#define DISPATCH_DATA_DESTRUCTOR_MUNMAP _dispatch_data_destructor_munmap
+
+#if __has_attribute(noescape)
+ #define DISPATCH_NOESCAPE __attribute__((__noescape__))
+#else
+ #define DISPATCH_NOESCAPE
+#endif
+
+// Data types used in dispatch APIs
+typedef unsigned long size_t; // NOLINT
+typedef unsigned long uintptr_t; // NOLINT
+typedef __sanitizer::s64 off_t;
+typedef __sanitizer::u16 mode_t;
+typedef long long_t; // NOLINT
+
+#endif // TSAN_DISPATCH_DEFS_H
diff --git a/libsanitizer/tsan/tsan_external.cc b/libsanitizer/tsan/tsan_external.cpp
index 3dddc3a..efc1013 100644
--- a/libsanitizer/tsan/tsan_external.cc
+++ b/libsanitizer/tsan/tsan_external.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_external.cc --------------------------------------------------===//
+//===-- tsan_external.cpp -------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_fd.cc b/libsanitizer/tsan/tsan_fd.cpp
index effa35d..db01d80 100644
--- a/libsanitizer/tsan/tsan_fd.cc
+++ b/libsanitizer/tsan/tsan_fd.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_fd.cc --------------------------------------------------------===//
+//===-- tsan_fd.cpp -------------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_fd.h b/libsanitizer/tsan/tsan_fd.h
index 4d9236c..ce4f2f7 100644
--- a/libsanitizer/tsan/tsan_fd.h
+++ b/libsanitizer/tsan/tsan_fd.h
@@ -1,7 +1,8 @@
//===-- tsan_fd.h -----------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_flags.cc b/libsanitizer/tsan/tsan_flags.cpp
index 4217691..44bf325 100644
--- a/libsanitizer/tsan/tsan_flags.cc
+++ b/libsanitizer/tsan/tsan_flags.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_flags.cc -----------------------------------------------------===//
+//===-- tsan_flags.cpp ----------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -48,7 +49,7 @@ void RegisterTsanFlags(FlagParser *parser, Flags *f) {
&f->second_deadlock_stack);
}
-void InitializeFlags(Flags *f, const char *env) {
+void InitializeFlags(Flags *f, const char *env, const char *env_option_name) {
SetCommonFlagsDefaults();
{
// Override some common flags defaults.
@@ -59,8 +60,7 @@ void InitializeFlags(Flags *f, const char *env) {
// Does not work as expected for Go: runtime handles SIGABRT and crashes.
cf.abort_on_error = false;
// Go does not have mutexes.
- } else {
- cf.detect_deadlocks = true;
+ cf.detect_deadlocks = false;
}
cf.print_suppressions = false;
cf.stack_trace_format = " #%n %f %S %M";
@@ -91,9 +91,9 @@ void InitializeFlags(Flags *f, const char *env) {
ubsan_parser.ParseString(ubsan_default_options);
#endif
// Override from command line.
- parser.ParseString(env);
+ parser.ParseString(env, env_option_name);
#if TSAN_CONTAINS_UBSAN
- ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
+ ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS");
#endif
// Sanity check.
diff --git a/libsanitizer/tsan/tsan_flags.h b/libsanitizer/tsan/tsan_flags.h
index 35b0efc..da27d5b 100644
--- a/libsanitizer/tsan/tsan_flags.h
+++ b/libsanitizer/tsan/tsan_flags.h
@@ -1,7 +1,8 @@
//===-- tsan_flags.h --------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -26,7 +27,8 @@ struct Flags : DDFlags {
void ParseFromString(const char *str);
};
-void InitializeFlags(Flags *flags, const char *env);
+void InitializeFlags(Flags *flags, const char *env,
+ const char *env_option_name = nullptr);
} // namespace __tsan
#endif // TSAN_FLAGS_H
diff --git a/libsanitizer/tsan/tsan_flags.inc b/libsanitizer/tsan/tsan_flags.inc
index e9873f1..bfb74b6 100644
--- a/libsanitizer/tsan/tsan_flags.inc
+++ b/libsanitizer/tsan/tsan_flags.inc
@@ -1,7 +1,8 @@
//===-- tsan_flags.inc ------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -75,8 +76,6 @@ TSAN_FLAG(int, io_sync, 1,
TSAN_FLAG(bool, die_after_fork, true,
"Die after multi-threaded fork if the child creates new threads.")
TSAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
-TSAN_FLAG(bool, ignore_interceptors_accesses, false,
- "Ignore reads and writes from all interceptors.")
TSAN_FLAG(bool, ignore_noninstrumented_modules, SANITIZER_MAC ? true : false,
"Interceptors should only detect races when called from instrumented "
"modules.")
diff --git a/libsanitizer/tsan/tsan_ignoreset.cc b/libsanitizer/tsan/tsan_ignoreset.cpp
index f0aec42..f6e41f6 100644
--- a/libsanitizer/tsan/tsan_ignoreset.cc
+++ b/libsanitizer/tsan/tsan_ignoreset.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_ignoreset.cc -------------------------------------------------===//
+//===-- tsan_ignoreset.cpp ------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_ignoreset.h b/libsanitizer/tsan/tsan_ignoreset.h
index 5a250b7..3e318bd 100644
--- a/libsanitizer/tsan/tsan_ignoreset.h
+++ b/libsanitizer/tsan/tsan_ignoreset.h
@@ -1,7 +1,8 @@
//===-- tsan_ignoreset.h ----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_interceptors.cc b/libsanitizer/tsan/tsan_interceptors.cpp
index 069df59..9e1b9ed 100644
--- a/libsanitizer/tsan/tsan_interceptors.cc
+++ b/libsanitizer/tsan/tsan_interceptors.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_interceptors.cc ----------------------------------------------===//
+//===-- tsan_interceptors.cpp ---------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -40,17 +41,15 @@ using namespace __tsan; // NOLINT
#if SANITIZER_NETBSD
#define dirfd(dirp) (*(int *)(dirp))
-#define fileno_unlocked fileno
+#define fileno_unlocked(fp) \
+ (((__sanitizer_FILE*)fp)->_file == -1 ? -1 : \
+ (int)(unsigned short)(((__sanitizer_FILE*)fp)->_file)) // NOLINT
-#if _LP64
-#define __sF_size 152
-#else
-#define __sF_size 88
-#endif
-
-#define stdout ((char*)&__sF + (__sF_size * 1))
-#define stderr ((char*)&__sF + (__sF_size * 2))
+#define stdout ((__sanitizer_FILE*)&__sF[1])
+#define stderr ((__sanitizer_FILE*)&__sF[2])
+#define nanosleep __nanosleep50
+#define vfork __vfork14
#endif
#if SANITIZER_ANDROID
@@ -92,8 +91,8 @@ DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr size)
DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr)
extern "C" void *pthread_self();
extern "C" void _exit(int status);
-extern "C" int fileno_unlocked(void *stream);
#if !SANITIZER_NETBSD
+extern "C" int fileno_unlocked(void *stream);
extern "C" int dirfd(void *dirp);
#endif
#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_NETBSD
@@ -154,7 +153,7 @@ const int SIG_SETMASK = 2;
#endif
#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED \
- (!cur_thread()->is_inited)
+ (cur_thread_init(), !cur_thread()->is_inited)
namespace __tsan {
struct SignalDesc {
@@ -224,6 +223,16 @@ void InitializeLibIgnore() {
libignore()->OnLibraryLoaded(0);
}
+// The following two hooks can be used by for cooperative scheduling when
+// locking.
+#ifdef TSAN_EXTERNAL_HOOKS
+void OnPotentiallyBlockingRegionBegin();
+void OnPotentiallyBlockingRegionEnd();
+#else
+SANITIZER_WEAK_CXX_DEFAULT_IMPL void OnPotentiallyBlockingRegionBegin() {}
+SANITIZER_WEAK_CXX_DEFAULT_IMPL void OnPotentiallyBlockingRegionEnd() {}
+#endif
+
} // namespace __tsan
static ThreadSignalContext *SigCtx(ThreadState *thr) {
@@ -244,8 +253,7 @@ ScopedInterceptor::ScopedInterceptor(ThreadState *thr, const char *fname,
if (!thr_->ignore_interceptors) FuncEntry(thr, pc);
DPrintf("#%d: intercept %s()\n", thr_->tid, fname);
ignoring_ =
- !thr_->in_ignored_lib && (flags()->ignore_interceptors_accesses ||
- libignore()->IsIgnored(pc, &in_ignored_lib_));
+ !thr_->in_ignored_lib && libignore()->IsIgnored(pc, &in_ignored_lib_);
EnableIgnores();
}
@@ -390,7 +398,7 @@ static int setup_at_exit_wrapper(ThreadState *thr, uptr pc, void(*f)(),
#if !SANITIZER_ANDROID
TSAN_INTERCEPTOR(int, atexit, void (*f)()) {
- if (UNLIKELY(cur_thread()->in_symbolizer))
+ if (in_symbolizer())
return 0;
// We want to setup the atexit callback even if we are in ignored lib
// or after fork.
@@ -400,7 +408,7 @@ TSAN_INTERCEPTOR(int, atexit, void (*f)()) {
#endif
TSAN_INTERCEPTOR(int, __cxa_atexit, void (*f)(void *a), void *arg, void *dso) {
- if (UNLIKELY(cur_thread()->in_symbolizer))
+ if (in_symbolizer())
return 0;
SCOPED_TSAN_INTERCEPTOR(__cxa_atexit, f, arg, dso);
return setup_at_exit_wrapper(thr, pc, (void(*)())f, arg, dso);
@@ -446,7 +454,7 @@ static void on_exit_wrapper(int status, void *arg) {
}
TSAN_INTERCEPTOR(int, on_exit, void(*f)(int, void*), void *arg) {
- if (UNLIKELY(cur_thread()->in_symbolizer))
+ if (in_symbolizer())
return 0;
SCOPED_TSAN_INTERCEPTOR(on_exit, f, arg);
AtExitCtx *ctx = (AtExitCtx*)InternalAlloc(sizeof(AtExitCtx));
@@ -478,7 +486,7 @@ static void JmpBufGarbageCollect(ThreadState *thr, uptr sp) {
}
}
-static void SetJmp(ThreadState *thr, uptr sp, uptr mangled_sp) {
+static void SetJmp(ThreadState *thr, uptr sp) {
if (!thr->is_inited) // called from libc guts during bootstrap
return;
// Cleanup old bufs.
@@ -486,7 +494,6 @@ static void SetJmp(ThreadState *thr, uptr sp, uptr mangled_sp) {
// Remember the buf.
JmpBuf *buf = thr->jmp_bufs.PushBack();
buf->sp = sp;
- buf->mangled_sp = mangled_sp;
buf->shadow_stack_pos = thr->shadow_stack_pos;
ThreadSignalContext *sctx = SigCtx(thr);
buf->int_signal_send = sctx ? sctx->int_signal_send : 0;
@@ -498,32 +505,11 @@ static void SetJmp(ThreadState *thr, uptr sp, uptr mangled_sp) {
}
static void LongJmp(ThreadState *thr, uptr *env) {
-#ifdef __powerpc__
- uptr mangled_sp = env[0];
-#elif SANITIZER_FREEBSD
- uptr mangled_sp = env[2];
-#elif SANITIZER_NETBSD
- uptr mangled_sp = env[6];
-#elif SANITIZER_MAC
-# ifdef __aarch64__
- uptr mangled_sp =
- (GetMacosVersion() >= MACOS_VERSION_MOJAVE) ? env[12] : env[13];
-# else
- uptr mangled_sp = env[2];
-# endif
-#elif SANITIZER_LINUX
-# ifdef __aarch64__
- uptr mangled_sp = env[13];
-# elif defined(__mips64)
- uptr mangled_sp = env[1];
-# else
- uptr mangled_sp = env[6];
-# endif
-#endif
- // Find the saved buf by mangled_sp.
+ uptr sp = ExtractLongJmpSp(env);
+ // Find the saved buf with matching sp.
for (uptr i = 0; i < thr->jmp_bufs.Size(); i++) {
JmpBuf *buf = &thr->jmp_bufs[i];
- if (buf->mangled_sp == mangled_sp) {
+ if (buf->sp == sp) {
CHECK_GE(thr->shadow_stack_pos, buf->shadow_stack_pos);
// Unwind the stack.
while (thr->shadow_stack_pos > buf->shadow_stack_pos)
@@ -545,8 +531,9 @@ static void LongJmp(ThreadState *thr, uptr *env) {
}
// FIXME: put everything below into a common extern "C" block?
-extern "C" void __tsan_setjmp(uptr sp, uptr mangled_sp) {
- SetJmp(cur_thread(), sp, mangled_sp);
+extern "C" void __tsan_setjmp(uptr sp) {
+ cur_thread_init();
+ SetJmp(cur_thread(), sp);
}
#if SANITIZER_MAC
@@ -656,7 +643,7 @@ TSAN_INTERCEPTOR(void, _longjmp, uptr *env, int val) {
#if !SANITIZER_MAC
TSAN_INTERCEPTOR(void*, malloc, uptr size) {
- if (UNLIKELY(cur_thread()->in_symbolizer))
+ if (in_symbolizer())
return InternalAlloc(size);
void *p = 0;
{
@@ -673,7 +660,7 @@ TSAN_INTERCEPTOR(void*, __libc_memalign, uptr align, uptr sz) {
}
TSAN_INTERCEPTOR(void*, calloc, uptr size, uptr n) {
- if (UNLIKELY(cur_thread()->in_symbolizer))
+ if (in_symbolizer())
return InternalCalloc(size, n);
void *p = 0;
{
@@ -685,7 +672,7 @@ TSAN_INTERCEPTOR(void*, calloc, uptr size, uptr n) {
}
TSAN_INTERCEPTOR(void*, realloc, void *p, uptr size) {
- if (UNLIKELY(cur_thread()->in_symbolizer))
+ if (in_symbolizer())
return InternalRealloc(p, size);
if (p)
invoke_free_hook(p);
@@ -697,10 +684,23 @@ TSAN_INTERCEPTOR(void*, realloc, void *p, uptr size) {
return p;
}
+TSAN_INTERCEPTOR(void*, reallocarray, void *p, uptr size, uptr n) {
+ if (in_symbolizer())
+ return InternalReallocArray(p, size, n);
+ if (p)
+ invoke_free_hook(p);
+ {
+ SCOPED_INTERCEPTOR_RAW(reallocarray, p, size, n);
+ p = user_reallocarray(thr, pc, p, size, n);
+ }
+ invoke_malloc_hook(p, size);
+ return p;
+}
+
TSAN_INTERCEPTOR(void, free, void *p) {
if (p == 0)
return;
- if (UNLIKELY(cur_thread()->in_symbolizer))
+ if (in_symbolizer())
return InternalFree(p);
invoke_free_hook(p);
SCOPED_INTERCEPTOR_RAW(free, p);
@@ -710,7 +710,7 @@ TSAN_INTERCEPTOR(void, free, void *p) {
TSAN_INTERCEPTOR(void, cfree, void *p) {
if (p == 0)
return;
- if (UNLIKELY(cur_thread()->in_symbolizer))
+ if (in_symbolizer())
return InternalFree(p);
invoke_free_hook(p);
SCOPED_INTERCEPTOR_RAW(cfree, p);
@@ -799,14 +799,14 @@ TSAN_INTERCEPTOR(void*, memalign, uptr align, uptr sz) {
#if !SANITIZER_MAC
TSAN_INTERCEPTOR(void*, aligned_alloc, uptr align, uptr sz) {
- if (UNLIKELY(cur_thread()->in_symbolizer))
+ if (in_symbolizer())
return InternalAlloc(sz, nullptr, align);
SCOPED_INTERCEPTOR_RAW(aligned_alloc, align, sz);
return user_aligned_alloc(thr, pc, align, sz);
}
TSAN_INTERCEPTOR(void*, valloc, uptr sz) {
- if (UNLIKELY(cur_thread()->in_symbolizer))
+ if (in_symbolizer())
return InternalAlloc(sz, nullptr, GetPageSizeCached());
SCOPED_INTERCEPTOR_RAW(valloc, sz);
return user_valloc(thr, pc, sz);
@@ -815,7 +815,7 @@ TSAN_INTERCEPTOR(void*, valloc, uptr sz) {
#if SANITIZER_LINUX
TSAN_INTERCEPTOR(void*, pvalloc, uptr sz) {
- if (UNLIKELY(cur_thread()->in_symbolizer)) {
+ if (in_symbolizer()) {
uptr PageSize = GetPageSizeCached();
sz = sz ? RoundUpTo(sz, PageSize) : PageSize;
return InternalAlloc(sz, nullptr, PageSize);
@@ -830,7 +830,7 @@ TSAN_INTERCEPTOR(void*, pvalloc, uptr sz) {
#if !SANITIZER_MAC
TSAN_INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr sz) {
- if (UNLIKELY(cur_thread()->in_symbolizer)) {
+ if (in_symbolizer()) {
void *p = InternalAlloc(sz, nullptr, align);
if (!p)
return errno_ENOMEM;
@@ -862,6 +862,8 @@ TSAN_INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr sz) {
// Used in thread-safe function static initialization.
STDCXX_INTERCEPTOR(int, __cxa_guard_acquire, atomic_uint32_t *g) {
SCOPED_INTERCEPTOR_RAW(__cxa_guard_acquire, g);
+ OnPotentiallyBlockingRegionBegin();
+ auto on_exit = at_scope_exit(&OnPotentiallyBlockingRegionEnd);
for (;;) {
u32 cmp = atomic_load(g, memory_order_acquire);
if (cmp == 0) {
@@ -932,6 +934,7 @@ extern "C" void *__tsan_thread_start_func(void *arg) {
void *param = p->param;
int tid = 0;
{
+ cur_thread_init();
ThreadState *thr = cur_thread();
// Thread-local state is not initialized yet.
ScopedIgnoreInterceptors ignore;
@@ -948,7 +951,7 @@ extern "C" void *__tsan_thread_start_func(void *arg) {
internal_sched_yield();
Processor *proc = ProcCreate();
ProcWire(proc, thr);
- ThreadStart(thr, tid, GetTid(), /*workerthread*/ false);
+ ThreadStart(thr, tid, GetTid(), ThreadType::Regular);
atomic_store(&p->tid, 0, memory_order_release);
}
void *res = callback(param);
@@ -1040,6 +1043,45 @@ TSAN_INTERCEPTOR(int, pthread_detach, void *th) {
return res;
}
+TSAN_INTERCEPTOR(void, pthread_exit, void *retval) {
+ {
+ SCOPED_INTERCEPTOR_RAW(pthread_exit, retval);
+#if !SANITIZER_MAC && !SANITIZER_ANDROID
+ CHECK_EQ(thr, &cur_thread_placeholder);
+#endif
+ }
+ REAL(pthread_exit)(retval);
+}
+
+#if SANITIZER_LINUX
+TSAN_INTERCEPTOR(int, pthread_tryjoin_np, void *th, void **ret) {
+ SCOPED_TSAN_INTERCEPTOR(pthread_tryjoin_np, th, ret);
+ int tid = ThreadTid(thr, pc, (uptr)th);
+ ThreadIgnoreBegin(thr, pc);
+ int res = REAL(pthread_tryjoin_np)(th, ret);
+ ThreadIgnoreEnd(thr, pc);
+ if (res == 0)
+ ThreadJoin(thr, pc, tid);
+ else
+ ThreadNotJoined(thr, pc, tid, (uptr)th);
+ return res;
+}
+
+TSAN_INTERCEPTOR(int, pthread_timedjoin_np, void *th, void **ret,
+ const struct timespec *abstime) {
+ SCOPED_TSAN_INTERCEPTOR(pthread_timedjoin_np, th, ret, abstime);
+ int tid = ThreadTid(thr, pc, (uptr)th);
+ ThreadIgnoreBegin(thr, pc);
+ int res = BLOCK_REAL(pthread_timedjoin_np)(th, ret, abstime);
+ ThreadIgnoreEnd(thr, pc);
+ if (res == 0)
+ ThreadJoin(thr, pc, tid);
+ else
+ ThreadNotJoined(thr, pc, tid, (uptr)th);
+ return res;
+}
+#endif
+
// Problem:
// NPTL implementation of pthread_cond has 2 versions (2.2.5 and 2.3.2).
// pthread_cond_t has different size in the different versions.
@@ -1115,7 +1157,7 @@ static int cond_wait(ThreadState *thr, uptr pc, ScopedInterceptor *si,
CondMutexUnlockCtx arg = {si, thr, pc, m};
int res = 0;
// This ensures that we handle mutex lock even in case of pthread_cancel.
- // See test/tsan/cond_cancel.cc.
+ // See test/tsan/cond_cancel.cpp.
{
// Enable signal delivery while the thread is blocked.
BlockingCall bc(thr);
@@ -1935,6 +1977,7 @@ static bool is_sync_signal(ThreadSignalContext *sctx, int sig) {
void ALWAYS_INLINE rtl_generic_sighandler(bool sigact, int sig,
__sanitizer_siginfo *info,
void *ctx) {
+ cur_thread_init();
ThreadState *thr = cur_thread();
ThreadSignalContext *sctx = SigCtx(thr);
if (sig < 0 || sig >= kSigCount) {
@@ -2051,7 +2094,7 @@ TSAN_INTERCEPTOR(int, getaddrinfo, void *node, void *service,
}
TSAN_INTERCEPTOR(int, fork, int fake) {
- if (UNLIKELY(cur_thread()->in_symbolizer))
+ if (in_symbolizer())
return REAL(fork)(fake);
SCOPED_INTERCEPTOR_RAW(fork, fake);
ForkBefore(thr, pc);
@@ -2164,23 +2207,12 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc,
#include "sanitizer_common/sanitizer_platform_interceptors.h"
// Causes interceptor recursion (getaddrinfo() and fopen())
#undef SANITIZER_INTERCEPT_GETADDRINFO
-// There interceptors do not seem to be strictly necessary for tsan.
-// But we see cases where the interceptors consume 70% of execution time.
-// Memory blocks passed to fgetgrent_r are "written to" by tsan several times.
-// First, there is some recursion (getgrnam_r calls fgetgrent_r), and each
-// function "writes to" the buffer. Then, the same memory is "written to"
-// twice, first as buf and then as pwbufp (both of them refer to the same
-// addresses).
-#undef SANITIZER_INTERCEPT_GETPWENT
-#undef SANITIZER_INTERCEPT_GETPWENT_R
-#undef SANITIZER_INTERCEPT_FGETPWENT
-#undef SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
-#undef SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
// We define our own.
#if SANITIZER_INTERCEPT_TLS_GET_ADDR
#define NEED_TLS_GET_ADDR
#endif
#undef SANITIZER_INTERCEPT_TLS_GET_ADDR
+#undef SANITIZER_INTERCEPT_PTHREAD_SIGMASK
#define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
@@ -2209,7 +2241,8 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc,
(void) ctx;
#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) \
- Acquire(thr, pc, File2addr(path)); \
+ if (path) \
+ Acquire(thr, pc, File2addr(path)); \
if (file) { \
int fd = fileno_unlocked(file); \
if (fd >= 0) FdFileCreate(thr, pc, fd); \
@@ -2558,6 +2591,8 @@ TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_wrlock, void *m)
TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_trywrlock, void *m)
TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_unlock, void *m)
TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(int, once, void *o, void (*f)())
+TSAN_INTERCEPTOR_NETBSD_ALIAS_THR2(int, sigsetmask, sigmask, int a, void *b,
+ void *c)
namespace __tsan {
@@ -2577,6 +2612,9 @@ static void unreachable() {
}
#endif
+// Define default implementation since interception of libdispatch is optional.
+SANITIZER_WEAK_ATTRIBUTE void InitializeLibdispatchInterceptors() {}
+
void InitializeInterceptors() {
#if !SANITIZER_MAC
// We need to setup it early, because functions like dlsym() can call it.
@@ -2594,18 +2632,18 @@ void InitializeInterceptors() {
InitializeCommonInterceptors();
InitializeSignalInterceptors();
+ InitializeLibdispatchInterceptors();
#if !SANITIZER_MAC
// We can not use TSAN_INTERCEPT to get setjmp addr,
// because it does &setjmp and setjmp is not present in some versions of libc.
- using __interception::GetRealFunctionAddress;
- GetRealFunctionAddress(TSAN_STRING_SETJMP,
- (uptr*)&REAL(setjmp_symname), 0, 0);
- GetRealFunctionAddress("_setjmp", (uptr*)&REAL(_setjmp), 0, 0);
- GetRealFunctionAddress(TSAN_STRING_SIGSETJMP,
- (uptr*)&REAL(sigsetjmp_symname), 0, 0);
+ using __interception::InterceptFunction;
+ InterceptFunction(TSAN_STRING_SETJMP, (uptr*)&REAL(setjmp_symname), 0, 0);
+ InterceptFunction("_setjmp", (uptr*)&REAL(_setjmp), 0, 0);
+ InterceptFunction(TSAN_STRING_SIGSETJMP, (uptr*)&REAL(sigsetjmp_symname), 0,
+ 0);
#if !SANITIZER_NETBSD
- GetRealFunctionAddress("__sigsetjmp", (uptr*)&REAL(__sigsetjmp), 0, 0);
+ InterceptFunction("__sigsetjmp", (uptr*)&REAL(__sigsetjmp), 0, 0);
#endif
#endif
@@ -2619,6 +2657,7 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(__libc_memalign);
TSAN_INTERCEPT(calloc);
TSAN_INTERCEPT(realloc);
+ TSAN_INTERCEPT(reallocarray);
TSAN_INTERCEPT(free);
TSAN_INTERCEPT(cfree);
TSAN_INTERCEPT(munmap);
@@ -2634,6 +2673,11 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(pthread_create);
TSAN_INTERCEPT(pthread_join);
TSAN_INTERCEPT(pthread_detach);
+ TSAN_INTERCEPT(pthread_exit);
+ #if SANITIZER_LINUX
+ TSAN_INTERCEPT(pthread_tryjoin_np);
+ TSAN_INTERCEPT(pthread_timedjoin_np);
+ #endif
TSAN_INTERCEPT_VER(pthread_cond_init, PTHREAD_ABI_BASE);
TSAN_INTERCEPT_VER(pthread_cond_signal, PTHREAD_ABI_BASE);
@@ -2767,6 +2811,7 @@ void InitializeInterceptors() {
TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_trywrlock);
TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_unlock);
TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS_THR(once);
+ TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS_THR(sigsetmask);
FdInit();
}
diff --git a/libsanitizer/tsan/tsan_interceptors.h b/libsanitizer/tsan/tsan_interceptors.h
index 959a394..88d1edd 100644
--- a/libsanitizer/tsan/tsan_interceptors.h
+++ b/libsanitizer/tsan/tsan_interceptors.h
@@ -21,9 +21,17 @@ class ScopedInterceptor {
LibIgnore *libignore();
+#if !SANITIZER_GO
+INLINE bool in_symbolizer() {
+ cur_thread_init();
+ return UNLIKELY(cur_thread()->in_symbolizer);
+}
+#endif
+
} // namespace __tsan
#define SCOPED_INTERCEPTOR_RAW(func, ...) \
+ cur_thread_init(); \
ThreadState *thr = cur_thread(); \
const uptr caller_pc = GET_CALLER_PC(); \
ScopedInterceptor si(thr, #func, caller_pc); \
@@ -56,9 +64,13 @@ LibIgnore *libignore();
# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(ret, func, ...) \
TSAN_INTERCEPTOR(ret, __libc_thr_##func, __VA_ARGS__) \
ALIAS(WRAPPER_NAME(pthread_##func));
+# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR2(ret, func, func2, ...) \
+ TSAN_INTERCEPTOR(ret, __libc_thr_##func, __VA_ARGS__) \
+ ALIAS(WRAPPER_NAME(pthread_##func2));
#else
# define TSAN_INTERCEPTOR_NETBSD_ALIAS(ret, func, ...)
# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(ret, func, ...)
+# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR2(ret, func, func2, ...)
#endif
#endif // TSAN_INTERCEPTORS_H
diff --git a/libsanitizer/tsan/tsan_interceptors_mac.cc b/libsanitizer/tsan/tsan_interceptors_mac.cpp
index 1df6ac2..c2083f8 100644
--- a/libsanitizer/tsan/tsan_interceptors_mac.cc
+++ b/libsanitizer/tsan/tsan_interceptors_mac.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_interceptors_mac.cc ------------------------------------------===//
+//===-- tsan_interceptors_mac.cpp -----------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -17,8 +18,12 @@
#include "tsan_interceptors.h"
#include "tsan_interface.h"
#include "tsan_interface_ann.h"
+#include "sanitizer_common/sanitizer_addrhashmap.h"
+#include <errno.h>
#include <libkern/OSAtomic.h>
+#include <objc/objc-sync.h>
+#include <sys/ucontext.h>
#if defined(__has_include) && __has_include(<xpc/xpc.h>)
#include <xpc/xpc.h>
@@ -26,6 +31,11 @@
typedef long long_t; // NOLINT
+extern "C" {
+int getcontext(ucontext_t *ucp) __attribute__((returns_twice));
+int setcontext(const ucontext_t *ucp);
+}
+
namespace __tsan {
// The non-barrier versions of OSAtomic* functions are semantically mo_relaxed,
@@ -292,41 +302,87 @@ TSAN_INTERCEPTOR(void, xpc_connection_cancel, xpc_connection_t connection) {
#endif // #if defined(__has_include) && __has_include(<xpc/xpc.h>)
-// Is the Obj-C object a tagged pointer (i.e. isn't really a valid pointer and
-// contains data in the pointers bits instead)?
-static bool IsTaggedObjCPointer(void *obj) {
+// Determines whether the Obj-C object pointer is a tagged pointer. Tagged
+// pointers encode the object data directly in their pointer bits and do not
+// have an associated memory allocation. The Obj-C runtime uses tagged pointers
+// to transparently optimize small objects.
+static bool IsTaggedObjCPointer(id obj) {
const uptr kPossibleTaggedBits = 0x8000000000000001ull;
return ((uptr)obj & kPossibleTaggedBits) != 0;
}
-// Return an address on which we can synchronize (Acquire and Release) for a
-// Obj-C tagged pointer (which is not a valid pointer). Ideally should be a
-// derived address from 'obj', but for now just return the same global address.
-// TODO(kubamracek): Return different address for different pointers.
-static uptr SyncAddressForTaggedPointer(void *obj) {
- (void)obj;
- static u64 addr;
- return (uptr)&addr;
+// Returns an address which can be used to inform TSan about synchronization
+// points (MutexLock/Unlock). The TSan infrastructure expects this to be a valid
+// address in the process space. We do a small allocation here to obtain a
+// stable address (the array backing the hash map can change). The memory is
+// never free'd (leaked) and allocation and locking are slow, but this code only
+// runs for @synchronized with tagged pointers, which is very rare.
+static uptr GetOrCreateSyncAddress(uptr addr, ThreadState *thr, uptr pc) {
+ typedef AddrHashMap<uptr, 5> Map;
+ static Map Addresses;
+ Map::Handle h(&Addresses, addr);
+ if (h.created()) {
+ ThreadIgnoreBegin(thr, pc);
+ *h = (uptr) user_alloc(thr, pc, /*size=*/1);
+ ThreadIgnoreEnd(thr, pc);
+ }
+ return *h;
}
-// Address on which we can synchronize for an Objective-C object. Supports
-// tagged pointers.
-static uptr SyncAddressForObjCObject(void *obj) {
- if (IsTaggedObjCPointer(obj)) return SyncAddressForTaggedPointer(obj);
+// Returns an address on which we can synchronize given an Obj-C object pointer.
+// For normal object pointers, this is just the address of the object in memory.
+// Tagged pointers are not backed by an actual memory allocation, so we need to
+// synthesize a valid address.
+static uptr SyncAddressForObjCObject(id obj, ThreadState *thr, uptr pc) {
+ if (IsTaggedObjCPointer(obj))
+ return GetOrCreateSyncAddress((uptr)obj, thr, pc);
return (uptr)obj;
}
-TSAN_INTERCEPTOR(int, objc_sync_enter, void *obj) {
+TSAN_INTERCEPTOR(int, objc_sync_enter, id obj) {
SCOPED_TSAN_INTERCEPTOR(objc_sync_enter, obj);
+ if (!obj) return REAL(objc_sync_enter)(obj);
+ uptr addr = SyncAddressForObjCObject(obj, thr, pc);
+ MutexPreLock(thr, pc, addr, MutexFlagWriteReentrant);
int result = REAL(objc_sync_enter)(obj);
- if (obj) Acquire(thr, pc, SyncAddressForObjCObject(obj));
+ CHECK_EQ(result, OBJC_SYNC_SUCCESS);
+ MutexPostLock(thr, pc, addr, MutexFlagWriteReentrant);
return result;
}
-TSAN_INTERCEPTOR(int, objc_sync_exit, void *obj) {
- SCOPED_TSAN_INTERCEPTOR(objc_sync_enter, obj);
- if (obj) Release(thr, pc, SyncAddressForObjCObject(obj));
- return REAL(objc_sync_exit)(obj);
+TSAN_INTERCEPTOR(int, objc_sync_exit, id obj) {
+ SCOPED_TSAN_INTERCEPTOR(objc_sync_exit, obj);
+ if (!obj) return REAL(objc_sync_exit)(obj);
+ uptr addr = SyncAddressForObjCObject(obj, thr, pc);
+ MutexUnlock(thr, pc, addr);
+ int result = REAL(objc_sync_exit)(obj);
+ if (result != OBJC_SYNC_SUCCESS) MutexInvalidAccess(thr, pc, addr);
+ return result;
+}
+
+TSAN_INTERCEPTOR(int, swapcontext, ucontext_t *oucp, const ucontext_t *ucp) {
+ {
+ SCOPED_INTERCEPTOR_RAW(swapcontext, oucp, ucp);
+ }
+ // Bacause of swapcontext() semantics we have no option but to copy its
+ // impementation here
+ if (!oucp || !ucp) {
+ errno = EINVAL;
+ return -1;
+ }
+ ThreadState *thr = cur_thread();
+ const int UCF_SWAPPED = 0x80000000;
+ oucp->uc_onstack &= ~UCF_SWAPPED;
+ thr->ignore_interceptors++;
+ int ret = getcontext(oucp);
+ if (!(oucp->uc_onstack & UCF_SWAPPED)) {
+ thr->ignore_interceptors--;
+ if (!ret) {
+ oucp->uc_onstack |= UCF_SWAPPED;
+ ret = setcontext(ucp);
+ }
+ }
+ return ret;
}
// On macOS, libc++ is always linked dynamically, so intercepting works the
diff --git a/libsanitizer/tsan/tsan_interface.cc b/libsanitizer/tsan/tsan_interface.cpp
index d98ff15..845d8c8 100644
--- a/libsanitizer/tsan/tsan_interface.cc
+++ b/libsanitizer/tsan/tsan_interface.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_interface.cc -------------------------------------------------===//
+//===-- tsan_interface.cpp ------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -23,6 +24,7 @@ typedef u32 uint32_t;
typedef u64 uint64_t;
void __tsan_init() {
+ cur_thread_init();
Initialize(cur_thread());
}
@@ -122,6 +124,31 @@ void __sanitizer_unaligned_store64(uu64 *addr, u64 v) {
__tsan_unaligned_write8(addr);
*addr = v;
}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void *__tsan_get_current_fiber() {
+ return cur_thread();
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void *__tsan_create_fiber(unsigned flags) {
+ return FiberCreate(cur_thread(), CALLERPC, flags);
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __tsan_destroy_fiber(void *fiber) {
+ FiberDestroy(cur_thread(), CALLERPC, static_cast<ThreadState *>(fiber));
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __tsan_switch_to_fiber(void *fiber, unsigned flags) {
+ FiberSwitch(cur_thread(), CALLERPC, static_cast<ThreadState *>(fiber), flags);
+}
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void __tsan_set_fiber_name(void *fiber, const char *name) {
+ ThreadSetName(static_cast<ThreadState *>(fiber), name);
+}
} // extern "C"
void __tsan_acquire(void *addr) {
diff --git a/libsanitizer/tsan/tsan_interface.h b/libsanitizer/tsan/tsan_interface.h
index bb097b9..fac5780 100644
--- a/libsanitizer/tsan/tsan_interface.h
+++ b/libsanitizer/tsan/tsan_interface.h
@@ -1,7 +1,8 @@
//===-- tsan_interface.h ----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -198,7 +199,7 @@ __extension__ typedef __int128 a128;
#endif
// Part of ABI, do not change.
-// http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/atomic?view=markup
+// https://github.com/llvm/llvm-project/blob/master/libcxx/include/atomic
typedef enum {
mo_relaxed,
mo_consume,
diff --git a/libsanitizer/tsan/tsan_interface_ann.cc b/libsanitizer/tsan/tsan_interface_ann.cpp
index 3e2b7c8..288485c 100644
--- a/libsanitizer/tsan/tsan_interface_ann.cc
+++ b/libsanitizer/tsan/tsan_interface_ann.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_interface_ann.cc ---------------------------------------------===//
+//===-- tsan_interface_ann.cpp --------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_interface_ann.h b/libsanitizer/tsan/tsan_interface_ann.h
index 45c1835..458d61f 100644
--- a/libsanitizer/tsan/tsan_interface_ann.h
+++ b/libsanitizer/tsan/tsan_interface_ann.h
@@ -1,7 +1,8 @@
//===-- tsan_interface_ann.h ------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_interface_atomic.cc b/libsanitizer/tsan/tsan_interface_atomic.cpp
index c175d61..730a8e6 100644
--- a/libsanitizer/tsan/tsan_interface_atomic.cc
+++ b/libsanitizer/tsan/tsan_interface_atomic.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_interface_atomic.cc ------------------------------------------===//
+//===-- tsan_interface_atomic.cpp -----------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -473,7 +474,7 @@ static morder convert_morder(morder mo) {
#define SCOPED_ATOMIC(func, ...) \
ThreadState *const thr = cur_thread(); \
- if (thr->ignore_sync || thr->ignore_interceptors) { \
+ if (UNLIKELY(thr->ignore_sync || thr->ignore_interceptors)) { \
ProcessPendingSignals(thr); \
return NoTsanAtomic##func(__VA_ARGS__); \
} \
diff --git a/libsanitizer/tsan/tsan_interface_inl.h b/libsanitizer/tsan/tsan_interface_inl.h
index bf70cdc..bf4a165 100644
--- a/libsanitizer/tsan/tsan_interface_inl.h
+++ b/libsanitizer/tsan/tsan_interface_inl.h
@@ -1,7 +1,8 @@
//===-- tsan_interface_inl.h ------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_interface_java.cc b/libsanitizer/tsan/tsan_interface_java.cpp
index d3f35a9..7d3d32f 100644
--- a/libsanitizer/tsan/tsan_interface_java.cc
+++ b/libsanitizer/tsan/tsan_interface_java.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_interface_java.cc --------------------------------------------===//
+//===-- tsan_interface_java.cpp -------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_interface_java.h b/libsanitizer/tsan/tsan_interface_java.h
index 2dd49f0..93e67bd 100644
--- a/libsanitizer/tsan/tsan_interface_java.h
+++ b/libsanitizer/tsan/tsan_interface_java.h
@@ -1,7 +1,8 @@
//===-- tsan_interface_java.h -----------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -17,7 +18,7 @@
// For volatile memory accesses and atomic operations JVM is intended to use
// standard atomics API: __tsan_atomicN_load/store/etc.
//
-// For usage examples see lit_tests/java_*.cc
+// For usage examples see lit_tests/java_*.cpp
//===----------------------------------------------------------------------===//
#ifndef TSAN_INTERFACE_JAVA_H
#define TSAN_INTERFACE_JAVA_H
diff --git a/libsanitizer/tsan/tsan_libdispatch_mac.cc b/libsanitizer/tsan/tsan_libdispatch.cpp
index f7e08d4..5e86ddc 100644
--- a/libsanitizer/tsan/tsan_libdispatch_mac.cc
+++ b/libsanitizer/tsan/tsan_libdispatch.cpp
@@ -1,36 +1,25 @@
-//===-- tsan_libdispatch_mac.cc -------------------------------------------===//
+//===-- tsan_libdispatch.cpp ----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of ThreadSanitizer (TSan), a race detector.
//
-// Mac-specific libdispatch (GCD) support.
+// Support for intercepting libdispatch (GCD).
//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_MAC
-
#include "sanitizer_common/sanitizer_common.h"
#include "interception/interception.h"
#include "tsan_interceptors.h"
-#include "tsan_platform.h"
#include "tsan_rtl.h"
-#include <Block.h>
-#include <dispatch/dispatch.h>
-#include <pthread.h>
-
-// DISPATCH_NOESCAPE is not defined prior to XCode 8.
-#ifndef DISPATCH_NOESCAPE
-#define DISPATCH_NOESCAPE
-#endif
-
-typedef long long_t; // NOLINT
+#include "tsan_dispatch_defs.h"
namespace __tsan {
+ typedef u16 uint16_t;
typedef struct {
dispatch_queue_t queue;
@@ -40,7 +29,7 @@ typedef struct {
bool submitted_synchronously;
bool is_barrier_block;
uptr non_queue_sync_object;
-} tsan_block_context_t;
+} block_context_t;
// The offsets of different fields of the dispatch_queue_t structure, exported
// by libdispatch.dylib.
@@ -84,13 +73,11 @@ static dispatch_queue_t GetTargetQueueFromSource(dispatch_source_t source) {
return tq;
}
-static tsan_block_context_t *AllocContext(ThreadState *thr, uptr pc,
- dispatch_queue_t queue,
- void *orig_context,
- dispatch_function_t orig_work) {
- tsan_block_context_t *new_context =
- (tsan_block_context_t *)user_alloc_internal(thr, pc,
- sizeof(tsan_block_context_t));
+static block_context_t *AllocContext(ThreadState *thr, uptr pc,
+ dispatch_queue_t queue, void *orig_context,
+ dispatch_function_t orig_work) {
+ block_context_t *new_context =
+ (block_context_t *)user_alloc_internal(thr, pc, sizeof(block_context_t));
new_context->queue = queue;
new_context->orig_context = orig_context;
new_context->orig_work = orig_work;
@@ -109,7 +96,7 @@ static tsan_block_context_t *AllocContext(ThreadState *thr, uptr pc,
bool serial_task = context->is_barrier_block || is_queue_serial
static void dispatch_sync_pre_execute(ThreadState *thr, uptr pc,
- tsan_block_context_t *context) {
+ block_context_t *context) {
uptr submit_sync = (uptr)context;
Acquire(thr, pc, submit_sync);
@@ -124,7 +111,7 @@ static void dispatch_sync_pre_execute(ThreadState *thr, uptr pc,
}
static void dispatch_sync_post_execute(ThreadState *thr, uptr pc,
- tsan_block_context_t *context) {
+ block_context_t *context) {
uptr submit_sync = (uptr)context;
if (context->submitted_synchronously) Release(thr, pc, submit_sync);
@@ -140,7 +127,7 @@ static void dispatch_sync_post_execute(ThreadState *thr, uptr pc,
static void dispatch_callback_wrap(void *param) {
SCOPED_INTERCEPTOR_RAW(dispatch_callback_wrap);
- tsan_block_context_t *context = (tsan_block_context_t *)param;
+ block_context_t *context = (block_context_t *)param;
dispatch_sync_pre_execute(thr, pc, context);
@@ -164,13 +151,13 @@ static void invoke_and_release_block(void *param) {
Block_release(block);
}
-#define DISPATCH_INTERCEPT_B(name, barrier) \
+#define DISPATCH_INTERCEPT_ASYNC_B(name, barrier) \
TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, dispatch_block_t block) { \
SCOPED_TSAN_INTERCEPTOR(name, q, block); \
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \
dispatch_block_t heap_block = Block_copy(block); \
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); \
- tsan_block_context_t *new_context = \
+ block_context_t *new_context = \
AllocContext(thr, pc, q, heap_block, &invoke_and_release_block); \
new_context->is_barrier_block = barrier; \
Release(thr, pc, (uptr)new_context); \
@@ -183,7 +170,7 @@ static void invoke_and_release_block(void *param) {
TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, \
DISPATCH_NOESCAPE dispatch_block_t block) { \
SCOPED_TSAN_INTERCEPTOR(name, q, block); \
- tsan_block_context_t new_context = { \
+ block_context_t new_context = { \
q, block, &invoke_block, false, true, barrier, 0}; \
Release(thr, pc, (uptr)&new_context); \
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \
@@ -192,11 +179,11 @@ static void invoke_and_release_block(void *param) {
Acquire(thr, pc, (uptr)&new_context); \
}
-#define DISPATCH_INTERCEPT_F(name, barrier) \
+#define DISPATCH_INTERCEPT_ASYNC_F(name, barrier) \
TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, void *context, \
dispatch_function_t work) { \
SCOPED_TSAN_INTERCEPTOR(name, q, context, work); \
- tsan_block_context_t *new_context = \
+ block_context_t *new_context = \
AllocContext(thr, pc, q, context, work); \
new_context->is_barrier_block = barrier; \
Release(thr, pc, (uptr)new_context); \
@@ -209,7 +196,7 @@ static void invoke_and_release_block(void *param) {
TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, void *context, \
dispatch_function_t work) { \
SCOPED_TSAN_INTERCEPTOR(name, q, context, work); \
- tsan_block_context_t new_context = { \
+ block_context_t new_context = { \
q, context, work, false, true, barrier, 0}; \
Release(thr, pc, (uptr)&new_context); \
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \
@@ -218,18 +205,21 @@ static void invoke_and_release_block(void *param) {
Acquire(thr, pc, (uptr)&new_context); \
}
+#define DISPATCH_INTERCEPT(name, barrier) \
+ DISPATCH_INTERCEPT_ASYNC_F(name##_async_f, barrier) \
+ DISPATCH_INTERCEPT_ASYNC_B(name##_async, barrier) \
+ DISPATCH_INTERCEPT_SYNC_F(name##_sync_f, barrier) \
+ DISPATCH_INTERCEPT_SYNC_B(name##_sync, barrier)
+
// We wrap dispatch_async, dispatch_sync and friends where we allocate a new
// context, which is used to synchronize (we release the context before
// submitting, and the callback acquires it before executing the original
// callback).
-DISPATCH_INTERCEPT_B(dispatch_async, false)
-DISPATCH_INTERCEPT_B(dispatch_barrier_async, true)
-DISPATCH_INTERCEPT_F(dispatch_async_f, false)
-DISPATCH_INTERCEPT_F(dispatch_barrier_async_f, true)
-DISPATCH_INTERCEPT_SYNC_B(dispatch_sync, false)
-DISPATCH_INTERCEPT_SYNC_B(dispatch_barrier_sync, true)
-DISPATCH_INTERCEPT_SYNC_F(dispatch_sync_f, false)
-DISPATCH_INTERCEPT_SYNC_F(dispatch_barrier_sync_f, true)
+DISPATCH_INTERCEPT(dispatch, false)
+DISPATCH_INTERCEPT(dispatch_barrier, true)
+
+DECLARE_REAL(void, dispatch_after_f, dispatch_time_t when,
+ dispatch_queue_t queue, void *context, dispatch_function_t work)
TSAN_INTERCEPTOR(void, dispatch_after, dispatch_time_t when,
dispatch_queue_t queue, dispatch_block_t block) {
@@ -237,7 +227,7 @@ TSAN_INTERCEPTOR(void, dispatch_after, dispatch_time_t when,
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
dispatch_block_t heap_block = Block_copy(block);
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
- tsan_block_context_t *new_context =
+ block_context_t *new_context =
AllocContext(thr, pc, queue, heap_block, &invoke_and_release_block);
Release(thr, pc, (uptr)new_context);
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
@@ -322,9 +312,12 @@ TSAN_INTERCEPTOR(long_t, dispatch_group_wait, dispatch_group_t group,
return result;
}
+// Used, but not intercepted.
+extern "C" void dispatch_group_enter(dispatch_group_t group);
+
TSAN_INTERCEPTOR(void, dispatch_group_leave, dispatch_group_t group) {
SCOPED_TSAN_INTERCEPTOR(dispatch_group_leave, group);
- // Acquired in the group noticifaction callback in dispatch_group_notify[_f].
+ // Acquired in the group notification callback in dispatch_group_notify[_f].
Release(thr, pc, (uptr)group);
REAL(dispatch_group_leave)(group);
}
@@ -334,10 +327,10 @@ TSAN_INTERCEPTOR(void, dispatch_group_async, dispatch_group_t group,
SCOPED_TSAN_INTERCEPTOR(dispatch_group_async, group, queue, block);
dispatch_retain(group);
dispatch_group_enter(group);
- __block dispatch_block_t block_copy = (dispatch_block_t)_Block_copy(block);
+ __block dispatch_block_t block_copy = (dispatch_block_t)Block_copy(block);
WRAP(dispatch_async)(queue, ^(void) {
block_copy();
- _Block_release(block_copy);
+ Block_release(block_copy);
WRAP(dispatch_group_leave)(group);
dispatch_release(group);
});
@@ -356,6 +349,9 @@ TSAN_INTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group,
});
}
+DECLARE_REAL(void, dispatch_group_notify_f, dispatch_group_t group,
+ dispatch_queue_t q, void *context, dispatch_function_t work)
+
TSAN_INTERCEPTOR(void, dispatch_group_notify, dispatch_group_t group,
dispatch_queue_t q, dispatch_block_t block) {
SCOPED_TSAN_INTERCEPTOR(dispatch_group_notify, group, q, block);
@@ -375,7 +371,7 @@ TSAN_INTERCEPTOR(void, dispatch_group_notify, dispatch_group_t group,
block();
});
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
- tsan_block_context_t *new_context =
+ block_context_t *new_context =
AllocContext(thr, pc, q, heap_block, &invoke_and_release_block);
new_context->is_barrier_block = true;
Release(thr, pc, (uptr)new_context);
@@ -393,7 +389,7 @@ TSAN_INTERCEPTOR(void, dispatch_source_set_event_handler,
if (handler == nullptr)
return REAL(dispatch_source_set_event_handler)(source, nullptr);
dispatch_queue_t q = GetTargetQueueFromSource(source);
- __block tsan_block_context_t new_context = {
+ __block block_context_t new_context = {
q, handler, &invoke_block, false, false, false, 0 };
dispatch_block_t new_handler = Block_copy(^(void) {
new_context.orig_context = handler; // To explicitly capture "handler".
@@ -422,7 +418,7 @@ TSAN_INTERCEPTOR(void, dispatch_source_set_cancel_handler,
if (handler == nullptr)
return REAL(dispatch_source_set_cancel_handler)(source, nullptr);
dispatch_queue_t q = GetTargetQueueFromSource(source);
- __block tsan_block_context_t new_context = {
+ __block block_context_t new_context = {
q, handler, &invoke_block, false, false, false, 0};
dispatch_block_t new_handler = Block_copy(^(void) {
new_context.orig_context = handler; // To explicitly capture "handler".
@@ -453,7 +449,7 @@ TSAN_INTERCEPTOR(void, dispatch_source_set_registration_handler,
if (handler == nullptr)
return REAL(dispatch_source_set_registration_handler)(source, nullptr);
dispatch_queue_t q = GetTargetQueueFromSource(source);
- __block tsan_block_context_t new_context = {
+ __block block_context_t new_context = {
q, handler, &invoke_block, false, false, false, 0};
dispatch_block_t new_handler = Block_copy(^(void) {
new_context.orig_context = handler; // To explicitly capture "handler".
@@ -482,34 +478,54 @@ TSAN_INTERCEPTOR(void, dispatch_apply, size_t iterations,
DISPATCH_NOESCAPE void (^block)(size_t)) {
SCOPED_TSAN_INTERCEPTOR(dispatch_apply, iterations, queue, block);
- void *parent_to_child_sync = nullptr;
- uptr parent_to_child_sync_uptr = (uptr)&parent_to_child_sync;
- void *child_to_parent_sync = nullptr;
- uptr child_to_parent_sync_uptr = (uptr)&child_to_parent_sync;
+ u8 sync1, sync2;
+ uptr parent_to_child_sync = (uptr)&sync1;
+ uptr child_to_parent_sync = (uptr)&sync2;
- Release(thr, pc, parent_to_child_sync_uptr);
+ Release(thr, pc, parent_to_child_sync);
void (^new_block)(size_t) = ^(size_t iteration) {
SCOPED_INTERCEPTOR_RAW(dispatch_apply);
- Acquire(thr, pc, parent_to_child_sync_uptr);
+ Acquire(thr, pc, parent_to_child_sync);
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
block(iteration);
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
- Release(thr, pc, child_to_parent_sync_uptr);
+ Release(thr, pc, child_to_parent_sync);
};
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
REAL(dispatch_apply)(iterations, queue, new_block);
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
- Acquire(thr, pc, child_to_parent_sync_uptr);
+ Acquire(thr, pc, child_to_parent_sync);
+}
+
+static void invoke_block_iteration(void *param, size_t iteration) {
+ auto block = (void (^)(size_t)) param;
+ block(iteration);
}
TSAN_INTERCEPTOR(void, dispatch_apply_f, size_t iterations,
dispatch_queue_t queue, void *context,
void (*work)(void *, size_t)) {
SCOPED_TSAN_INTERCEPTOR(dispatch_apply_f, iterations, queue, context, work);
+
+ // Unfortunately, we cannot delegate to dispatch_apply, since libdispatch
+ // implements dispatch_apply in terms of dispatch_apply_f.
+ u8 sync1, sync2;
+ uptr parent_to_child_sync = (uptr)&sync1;
+ uptr child_to_parent_sync = (uptr)&sync2;
+
+ Release(thr, pc, parent_to_child_sync);
void (^new_block)(size_t) = ^(size_t iteration) {
+ SCOPED_INTERCEPTOR_RAW(dispatch_apply_f);
+ Acquire(thr, pc, parent_to_child_sync);
+ SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
work(context, iteration);
+ SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
+ Release(thr, pc, child_to_parent_sync);
};
- WRAP(dispatch_apply)(iterations, queue, new_block);
+ SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
+ REAL(dispatch_apply_f)(iterations, queue, new_block, invoke_block_iteration);
+ SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
+ Acquire(thr, pc, child_to_parent_sync);
}
DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr)
@@ -529,7 +545,7 @@ TSAN_INTERCEPTOR(dispatch_data_t, dispatch_data_create, const void *buffer,
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START();
dispatch_block_t heap_block = Block_copy(destructor);
SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END();
- tsan_block_context_t *new_context =
+ block_context_t *new_context =
AllocContext(thr, pc, q, heap_block, &invoke_and_release_block);
uptr submit_sync = (uptr)new_context;
Release(thr, pc, submit_sync);
@@ -544,7 +560,7 @@ typedef void (^cleanup_handler_t)(int error);
TSAN_INTERCEPTOR(void, dispatch_read, dispatch_fd_t fd, size_t length,
dispatch_queue_t q, fd_handler_t h) {
SCOPED_TSAN_INTERCEPTOR(dispatch_read, fd, length, q, h);
- __block tsan_block_context_t new_context = {
+ __block block_context_t new_context = {
q, nullptr, &invoke_block, false, false, false, 0};
fd_handler_t new_h = Block_copy(^(dispatch_data_t data, int error) {
new_context.orig_context = ^(void) {
@@ -561,7 +577,7 @@ TSAN_INTERCEPTOR(void, dispatch_read, dispatch_fd_t fd, size_t length,
TSAN_INTERCEPTOR(void, dispatch_write, dispatch_fd_t fd, dispatch_data_t data,
dispatch_queue_t q, fd_handler_t h) {
SCOPED_TSAN_INTERCEPTOR(dispatch_write, fd, data, q, h);
- __block tsan_block_context_t new_context = {
+ __block block_context_t new_context = {
q, nullptr, &invoke_block, false, false, false, 0};
fd_handler_t new_h = Block_copy(^(dispatch_data_t data, int error) {
new_context.orig_context = ^(void) {
@@ -578,7 +594,7 @@ TSAN_INTERCEPTOR(void, dispatch_write, dispatch_fd_t fd, dispatch_data_t data,
TSAN_INTERCEPTOR(void, dispatch_io_read, dispatch_io_t channel, off_t offset,
size_t length, dispatch_queue_t q, dispatch_io_handler_t h) {
SCOPED_TSAN_INTERCEPTOR(dispatch_io_read, channel, offset, length, q, h);
- __block tsan_block_context_t new_context = {
+ __block block_context_t new_context = {
q, nullptr, &invoke_block, false, false, false, 0};
dispatch_io_handler_t new_h =
Block_copy(^(bool done, dispatch_data_t data, int error) {
@@ -597,7 +613,7 @@ TSAN_INTERCEPTOR(void, dispatch_io_write, dispatch_io_t channel, off_t offset,
dispatch_data_t data, dispatch_queue_t q,
dispatch_io_handler_t h) {
SCOPED_TSAN_INTERCEPTOR(dispatch_io_write, channel, offset, data, q, h);
- __block tsan_block_context_t new_context = {
+ __block block_context_t new_context = {
q, nullptr, &invoke_block, false, false, false, 0};
dispatch_io_handler_t new_h =
Block_copy(^(bool done, dispatch_data_t data, int error) {
@@ -615,7 +631,7 @@ TSAN_INTERCEPTOR(void, dispatch_io_write, dispatch_io_t channel, off_t offset,
TSAN_INTERCEPTOR(void, dispatch_io_barrier, dispatch_io_t channel,
dispatch_block_t barrier) {
SCOPED_TSAN_INTERCEPTOR(dispatch_io_barrier, channel, barrier);
- __block tsan_block_context_t new_context = {
+ __block block_context_t new_context = {
nullptr, nullptr, &invoke_block, false, false, false, 0};
new_context.non_queue_sync_object = (uptr)channel;
new_context.is_barrier_block = true;
@@ -635,7 +651,7 @@ TSAN_INTERCEPTOR(dispatch_io_t, dispatch_io_create, dispatch_io_type_t type,
dispatch_fd_t fd, dispatch_queue_t q, cleanup_handler_t h) {
SCOPED_TSAN_INTERCEPTOR(dispatch_io_create, type, fd, q, h);
__block dispatch_io_t new_channel = nullptr;
- __block tsan_block_context_t new_context = {
+ __block block_context_t new_context = {
q, nullptr, &invoke_block, false, false, false, 0};
cleanup_handler_t new_h = Block_copy(^(int error) {
{
@@ -660,7 +676,7 @@ TSAN_INTERCEPTOR(dispatch_io_t, dispatch_io_create_with_path,
SCOPED_TSAN_INTERCEPTOR(dispatch_io_create_with_path, type, path, oflag, mode,
q, h);
__block dispatch_io_t new_channel = nullptr;
- __block tsan_block_context_t new_context = {
+ __block block_context_t new_context = {
q, nullptr, &invoke_block, false, false, false, 0};
cleanup_handler_t new_h = Block_copy(^(int error) {
{
@@ -685,7 +701,7 @@ TSAN_INTERCEPTOR(dispatch_io_t, dispatch_io_create_with_io,
cleanup_handler_t h) {
SCOPED_TSAN_INTERCEPTOR(dispatch_io_create_with_io, type, io, q, h);
__block dispatch_io_t new_channel = nullptr;
- __block tsan_block_context_t new_context = {
+ __block block_context_t new_context = {
q, nullptr, &invoke_block, false, false, false, 0};
cleanup_handler_t new_h = Block_copy(^(int error) {
{
@@ -720,6 +736,46 @@ TSAN_INTERCEPTOR(void, dispatch_resume, dispatch_object_t o) {
return REAL(dispatch_resume)(o);
}
-} // namespace __tsan
+void InitializeLibdispatchInterceptors() {
+ INTERCEPT_FUNCTION(dispatch_async);
+ INTERCEPT_FUNCTION(dispatch_async_f);
+ INTERCEPT_FUNCTION(dispatch_sync);
+ INTERCEPT_FUNCTION(dispatch_sync_f);
+ INTERCEPT_FUNCTION(dispatch_barrier_async);
+ INTERCEPT_FUNCTION(dispatch_barrier_async_f);
+ INTERCEPT_FUNCTION(dispatch_barrier_sync);
+ INTERCEPT_FUNCTION(dispatch_barrier_sync_f);
+ INTERCEPT_FUNCTION(dispatch_after);
+ INTERCEPT_FUNCTION(dispatch_after_f);
+ INTERCEPT_FUNCTION(dispatch_once);
+ INTERCEPT_FUNCTION(dispatch_once_f);
+ INTERCEPT_FUNCTION(dispatch_semaphore_signal);
+ INTERCEPT_FUNCTION(dispatch_semaphore_wait);
+ INTERCEPT_FUNCTION(dispatch_group_wait);
+ INTERCEPT_FUNCTION(dispatch_group_leave);
+ INTERCEPT_FUNCTION(dispatch_group_async);
+ INTERCEPT_FUNCTION(dispatch_group_async_f);
+ INTERCEPT_FUNCTION(dispatch_group_notify);
+ INTERCEPT_FUNCTION(dispatch_group_notify_f);
+ INTERCEPT_FUNCTION(dispatch_source_set_event_handler);
+ INTERCEPT_FUNCTION(dispatch_source_set_event_handler_f);
+ INTERCEPT_FUNCTION(dispatch_source_set_cancel_handler);
+ INTERCEPT_FUNCTION(dispatch_source_set_cancel_handler_f);
+ INTERCEPT_FUNCTION(dispatch_source_set_registration_handler);
+ INTERCEPT_FUNCTION(dispatch_source_set_registration_handler_f);
+ INTERCEPT_FUNCTION(dispatch_apply);
+ INTERCEPT_FUNCTION(dispatch_apply_f);
+ INTERCEPT_FUNCTION(dispatch_data_create);
+ INTERCEPT_FUNCTION(dispatch_read);
+ INTERCEPT_FUNCTION(dispatch_write);
+ INTERCEPT_FUNCTION(dispatch_io_read);
+ INTERCEPT_FUNCTION(dispatch_io_write);
+ INTERCEPT_FUNCTION(dispatch_io_barrier);
+ INTERCEPT_FUNCTION(dispatch_io_create);
+ INTERCEPT_FUNCTION(dispatch_io_create_with_path);
+ INTERCEPT_FUNCTION(dispatch_io_create_with_io);
+ INTERCEPT_FUNCTION(dispatch_io_close);
+ INTERCEPT_FUNCTION(dispatch_resume);
+}
-#endif // SANITIZER_MAC
+} // namespace __tsan
diff --git a/libsanitizer/tsan/tsan_malloc_mac.cc b/libsanitizer/tsan/tsan_malloc_mac.cpp
index 618fa2d..0e861bf 100644
--- a/libsanitizer/tsan/tsan_malloc_mac.cc
+++ b/libsanitizer/tsan/tsan_malloc_mac.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_malloc_mac.cc ------------------------------------------------===//
+//===-- tsan_malloc_mac.cpp -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -27,19 +28,19 @@ using namespace __tsan;
void *p = \
user_memalign(cur_thread(), StackTrace::GetCurrentPc(), alignment, size)
#define COMMON_MALLOC_MALLOC(size) \
- if (cur_thread()->in_symbolizer) return InternalAlloc(size); \
+ if (in_symbolizer()) return InternalAlloc(size); \
SCOPED_INTERCEPTOR_RAW(malloc, size); \
void *p = user_alloc(thr, pc, size)
#define COMMON_MALLOC_REALLOC(ptr, size) \
- if (cur_thread()->in_symbolizer) return InternalRealloc(ptr, size); \
+ if (in_symbolizer()) return InternalRealloc(ptr, size); \
SCOPED_INTERCEPTOR_RAW(realloc, ptr, size); \
void *p = user_realloc(thr, pc, ptr, size)
#define COMMON_MALLOC_CALLOC(count, size) \
- if (cur_thread()->in_symbolizer) return InternalCalloc(count, size); \
+ if (in_symbolizer()) return InternalCalloc(count, size); \
SCOPED_INTERCEPTOR_RAW(calloc, size, count); \
void *p = user_calloc(thr, pc, size, count)
#define COMMON_MALLOC_POSIX_MEMALIGN(memptr, alignment, size) \
- if (cur_thread()->in_symbolizer) { \
+ if (in_symbolizer()) { \
void *p = InternalAlloc(size, nullptr, alignment); \
if (!p) return errno_ENOMEM; \
*memptr = p; \
@@ -48,12 +49,12 @@ using namespace __tsan;
SCOPED_INTERCEPTOR_RAW(posix_memalign, memptr, alignment, size); \
int res = user_posix_memalign(thr, pc, memptr, alignment, size);
#define COMMON_MALLOC_VALLOC(size) \
- if (cur_thread()->in_symbolizer) \
+ if (in_symbolizer()) \
return InternalAlloc(size, nullptr, GetPageSizeCached()); \
SCOPED_INTERCEPTOR_RAW(valloc, size); \
void *p = user_valloc(thr, pc, size)
#define COMMON_MALLOC_FREE(ptr) \
- if (cur_thread()->in_symbolizer) return InternalFree(ptr); \
+ if (in_symbolizer()) return InternalFree(ptr); \
SCOPED_INTERCEPTOR_RAW(free, ptr); \
user_free(thr, pc, ptr)
#define COMMON_MALLOC_SIZE(ptr) uptr size = user_alloc_usable_size(ptr);
@@ -62,6 +63,8 @@ using namespace __tsan;
(void)zone_name; \
Report("mz_realloc(%p) -- attempting to realloc unallocated memory.\n", ptr);
#define COMMON_MALLOC_NAMESPACE __tsan
+#define COMMON_MALLOC_HAS_ZONE_ENUMERATOR 0
+#define COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT 0
#include "sanitizer_common/sanitizer_malloc_mac.inc"
diff --git a/libsanitizer/tsan/tsan_md5.cc b/libsanitizer/tsan/tsan_md5.cpp
index f299dfc..d146e1c 100644
--- a/libsanitizer/tsan/tsan_md5.cc
+++ b/libsanitizer/tsan/tsan_md5.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_md5.cc -------------------------------------------------------===//
+//===-- tsan_md5.cpp ------------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -137,6 +138,14 @@ static const void *body(MD5_CTX *ctx, const void *data, ulong_t size) {
return ptr;
}
+#undef F
+#undef G
+#undef H
+#undef I
+#undef STEP
+#undef SET
+#undef GET
+
void MD5_Init(MD5_CTX *ctx) {
ctx->a = 0x67452301;
ctx->b = 0xefcdab89;
diff --git a/libsanitizer/tsan/tsan_mman.cc b/libsanitizer/tsan/tsan_mman.cpp
index 76d12a4..1b2c054 100644
--- a/libsanitizer/tsan/tsan_mman.cc
+++ b/libsanitizer/tsan/tsan_mman.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_mman.cc ------------------------------------------------------===//
+//===-- tsan_mman.cpp -----------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -200,6 +201,16 @@ void *user_calloc(ThreadState *thr, uptr pc, uptr size, uptr n) {
return SetErrnoOnNull(p);
}
+void *user_reallocarray(ThreadState *thr, uptr pc, void *p, uptr size, uptr n) {
+ if (UNLIKELY(CheckForCallocOverflow(size, n))) {
+ if (AllocatorMayReturnNull())
+ return SetErrnoOnNull(nullptr);
+ GET_STACK_TRACE_FATAL(thr, pc);
+ ReportReallocArrayOverflow(size, n, &stack);
+ }
+ return user_realloc(thr, pc, p, size * n);
+}
+
void OnUserAlloc(ThreadState *thr, uptr pc, uptr p, uptr sz, bool write) {
DPrintf("#%d: alloc(%zu) = %p\n", thr->tid, sz, p);
ctx->metamap.AllocBlock(thr, pc, p, sz);
diff --git a/libsanitizer/tsan/tsan_mman.h b/libsanitizer/tsan/tsan_mman.h
index 3443cb0..467aabd 100644
--- a/libsanitizer/tsan/tsan_mman.h
+++ b/libsanitizer/tsan/tsan_mman.h
@@ -1,7 +1,8 @@
//===-- tsan_mman.h ---------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -33,6 +34,7 @@ void user_free(ThreadState *thr, uptr pc, void *p, bool signal = true);
void *user_alloc(ThreadState *thr, uptr pc, uptr sz);
void *user_calloc(ThreadState *thr, uptr pc, uptr sz, uptr n);
void *user_realloc(ThreadState *thr, uptr pc, void *p, uptr sz);
+void *user_reallocarray(ThreadState *thr, uptr pc, void *p, uptr sz, uptr n);
void *user_memalign(ThreadState *thr, uptr pc, uptr align, uptr sz);
int user_posix_memalign(ThreadState *thr, uptr pc, void **memptr, uptr align,
uptr sz);
diff --git a/libsanitizer/tsan/tsan_mutex.cc b/libsanitizer/tsan/tsan_mutex.cpp
index 9b105cf..7a0918f 100644
--- a/libsanitizer/tsan/tsan_mutex.cc
+++ b/libsanitizer/tsan/tsan_mutex.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_mutex.cc -----------------------------------------------------===//
+//===-- tsan_mutex.cpp ----------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_mutex.h b/libsanitizer/tsan/tsan_mutex.h
index bd1000f..80fdc6e 100644
--- a/libsanitizer/tsan/tsan_mutex.h
+++ b/libsanitizer/tsan/tsan_mutex.h
@@ -1,7 +1,8 @@
//===-- tsan_mutex.h --------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_mutexset.cc b/libsanitizer/tsan/tsan_mutexset.cpp
index 3ebae3a..813fa3b 100644
--- a/libsanitizer/tsan/tsan_mutexset.cc
+++ b/libsanitizer/tsan/tsan_mutexset.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_mutexset.cc --------------------------------------------------===//
+//===-- tsan_mutexset.cpp -------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_mutexset.h b/libsanitizer/tsan/tsan_mutexset.h
index b2c60b9..d63881f 100644
--- a/libsanitizer/tsan/tsan_mutexset.h
+++ b/libsanitizer/tsan/tsan_mutexset.h
@@ -1,7 +1,8 @@
//===-- tsan_mutexset.h -----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_new_delete.cc b/libsanitizer/tsan/tsan_new_delete.cpp
index 1346aa7..3ed3c84 100644
--- a/libsanitizer/tsan/tsan_new_delete.cc
+++ b/libsanitizer/tsan/tsan_new_delete.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_new_delete.cc ----------------------------------------------===//
+//===-- tsan_new_delete.cpp ---------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -28,7 +29,7 @@ DECLARE_REAL(void, free, void *ptr)
// TODO(alekseys): throw std::bad_alloc instead of dying on OOM.
#define OPERATOR_NEW_BODY(mangled_name, nothrow) \
- if (cur_thread()->in_symbolizer) \
+ if (in_symbolizer()) \
return InternalAlloc(size); \
void *p = 0; \
{ \
@@ -43,7 +44,7 @@ DECLARE_REAL(void, free, void *ptr)
return p;
#define OPERATOR_NEW_BODY_ALIGN(mangled_name, nothrow) \
- if (cur_thread()->in_symbolizer) \
+ if (in_symbolizer()) \
return InternalAlloc(size, nullptr, (uptr)align); \
void *p = 0; \
{ \
@@ -113,7 +114,7 @@ void *operator new[](__sanitizer::uptr size, std::align_val_t align,
#define OPERATOR_DELETE_BODY(mangled_name) \
if (ptr == 0) return; \
- if (cur_thread()->in_symbolizer) \
+ if (in_symbolizer()) \
return InternalFree(ptr); \
invoke_free_hook(ptr); \
SCOPED_INTERCEPTOR_RAW(mangled_name, ptr); \
diff --git a/libsanitizer/tsan/tsan_platform.h b/libsanitizer/tsan/tsan_platform.h
index 871df46..0d106c4 100644
--- a/libsanitizer/tsan/tsan_platform.h
+++ b/libsanitizer/tsan/tsan_platform.h
@@ -1,7 +1,8 @@
//===-- tsan_platform.h -----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -1010,6 +1011,7 @@ void FlushShadowMemory();
void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive);
int ExtractResolvFDs(void *state, int *fds, int nfd);
int ExtractRecvmsgFDs(void *msg, int *fds, int nfd);
+uptr ExtractLongJmpSp(uptr *env);
void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size);
int call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,
diff --git a/libsanitizer/tsan/tsan_platform_linux.cc b/libsanitizer/tsan/tsan_platform_linux.cpp
index 9b4dea2..33fa586 100644
--- a/libsanitizer/tsan/tsan_platform_linux.cc
+++ b/libsanitizer/tsan/tsan_platform_linux.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_platform_linux.cc --------------------------------------------===//
+//===-- tsan_platform_linux.cpp -------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -66,12 +67,25 @@ extern "C" void *__libc_stack_end;
void *__libc_stack_end = 0;
#endif
-#if SANITIZER_LINUX && defined(__aarch64__)
-void InitializeGuardPtr() __attribute__((visibility("hidden")));
+#if SANITIZER_LINUX && defined(__aarch64__) && !SANITIZER_GO
+# define INIT_LONGJMP_XOR_KEY 1
+#else
+# define INIT_LONGJMP_XOR_KEY 0
+#endif
+
+#if INIT_LONGJMP_XOR_KEY
+#include "interception/interception.h"
+// Must be declared outside of other namespaces.
+DECLARE_REAL(int, _setjmp, void *env)
#endif
namespace __tsan {
+#if INIT_LONGJMP_XOR_KEY
+static void InitializeLongjmpXorKey();
+static uptr longjmp_xor_key;
+#endif
+
#ifdef TSAN_RUNTIME_VMA
// Runtime detected VMA size.
uptr vmaSize;
@@ -247,7 +261,8 @@ void InitializePlatform() {
// Go maps shadow memory lazily and works fine with limited address space.
// Unlimited stack is not a problem as well, because the executable
// is not compiled with -pie.
- if (!SANITIZER_GO) {
+#if !SANITIZER_GO
+ {
bool reexec = false;
// TSan doesn't play well with unlimited stack size (as stack
// overlaps with shadow memory). If we detect unlimited stack size,
@@ -282,17 +297,16 @@ void InitializePlatform() {
CHECK_NE(personality(old_personality | ADDR_NO_RANDOMIZE), -1);
reexec = true;
}
- // Initialize the guard pointer used in {sig}{set,long}jump.
- InitializeGuardPtr();
+ // Initialize the xor key used in {sig}{set,long}jump.
+ InitializeLongjmpXorKey();
#endif
if (reexec)
ReExec();
}
-#if !SANITIZER_GO
CheckAndProtect();
InitTlsSize();
-#endif
+#endif // !SANITIZER_GO
}
#if !SANITIZER_GO
@@ -333,6 +347,83 @@ int ExtractRecvmsgFDs(void *msgp, int *fds, int nfd) {
return res;
}
+// Reverse operation of libc stack pointer mangling
+static uptr UnmangleLongJmpSp(uptr mangled_sp) {
+#if defined(__x86_64__)
+# if SANITIZER_LINUX
+ // Reverse of:
+ // xor %fs:0x30, %rsi
+ // rol $0x11, %rsi
+ uptr sp;
+ asm("ror $0x11, %0 \n"
+ "xor %%fs:0x30, %0 \n"
+ : "=r" (sp)
+ : "0" (mangled_sp));
+ return sp;
+# else
+ return mangled_sp;
+# endif
+#elif defined(__aarch64__)
+# if SANITIZER_LINUX
+ return mangled_sp ^ longjmp_xor_key;
+# else
+ return mangled_sp;
+# endif
+#elif defined(__powerpc64__)
+ // Reverse of:
+ // ld r4, -28696(r13)
+ // xor r4, r3, r4
+ uptr xor_key;
+ asm("ld %0, -28696(%%r13)" : "=r" (xor_key));
+ return mangled_sp ^ xor_key;
+#elif defined(__mips__)
+ return mangled_sp;
+#else
+ #error "Unknown platform"
+#endif
+}
+
+#ifdef __powerpc__
+# define LONG_JMP_SP_ENV_SLOT 0
+#elif SANITIZER_FREEBSD
+# define LONG_JMP_SP_ENV_SLOT 2
+#elif SANITIZER_NETBSD
+# define LONG_JMP_SP_ENV_SLOT 6
+#elif SANITIZER_LINUX
+# ifdef __aarch64__
+# define LONG_JMP_SP_ENV_SLOT 13
+# elif defined(__mips64)
+# define LONG_JMP_SP_ENV_SLOT 1
+# else
+# define LONG_JMP_SP_ENV_SLOT 6
+# endif
+#endif
+
+uptr ExtractLongJmpSp(uptr *env) {
+ uptr mangled_sp = env[LONG_JMP_SP_ENV_SLOT];
+ return UnmangleLongJmpSp(mangled_sp);
+}
+
+#if INIT_LONGJMP_XOR_KEY
+// GLIBC mangles the function pointers in jmp_buf (used in {set,long}*jmp
+// functions) by XORing them with a random key. For AArch64 it is a global
+// variable rather than a TCB one (as for x86_64/powerpc). We obtain the key by
+// issuing a setjmp and XORing the SP pointer values to derive the key.
+static void InitializeLongjmpXorKey() {
+ // 1. Call REAL(setjmp), which stores the mangled SP in env.
+ jmp_buf env;
+ REAL(_setjmp)(env);
+
+ // 2. Retrieve vanilla/mangled SP.
+ uptr sp;
+ asm("mov %0, sp" : "=r" (sp));
+ uptr mangled_sp = ((uptr *)&env)[LONG_JMP_SP_ENV_SLOT];
+
+ // 3. xor SPs to obtain key.
+ longjmp_xor_key = mangled_sp ^ sp;
+}
+#endif
+
void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) {
// Check that the thr object is in tls;
const uptr thr_beg = (uptr)thr;
@@ -360,7 +451,7 @@ int call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,
pthread_cleanup_pop(0);
return res;
}
-#endif
+#endif // !SANITIZER_GO
#if !SANITIZER_GO
void ReplaceSystemMalloc() { }
@@ -400,6 +491,10 @@ ThreadState *cur_thread() {
return thr;
}
+void set_cur_thread(ThreadState *thr) {
+ *get_android_tls_ptr() = reinterpret_cast<uptr>(thr);
+}
+
void cur_thread_finalize() {
__sanitizer_sigset_t emptyset;
internal_sigfillset(&emptyset);
diff --git a/libsanitizer/tsan/tsan_platform_mac.cc b/libsanitizer/tsan/tsan_platform_mac.cpp
index 14395ba..326ca85 100644
--- a/libsanitizer/tsan/tsan_platform_mac.cc
+++ b/libsanitizer/tsan/tsan_platform_mac.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_platform_mac.cc ----------------------------------------------===//
+//===-- tsan_platform_mac.cpp ---------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -72,22 +73,22 @@ static void *SignalSafeGetOrAllocate(uptr *dst, uptr size) {
// shadow memory is set up.
static uptr main_thread_identity = 0;
ALIGNED(64) static char main_thread_state[sizeof(ThreadState)];
+static ThreadState *main_thread_state_loc = (ThreadState *)main_thread_state;
-ThreadState **cur_thread_location() {
- ThreadState **thread_identity = (ThreadState **)pthread_self();
- return ((uptr)thread_identity == main_thread_identity) ? nullptr
- : thread_identity;
+static ThreadState **cur_thread_location() {
+ uptr thread_identity = (uptr)pthread_self();
+ if (thread_identity == main_thread_identity || main_thread_identity == 0)
+ return &main_thread_state_loc;
+ return (ThreadState **)MemToShadow(thread_identity);
}
ThreadState *cur_thread() {
- ThreadState **thr_state_loc = cur_thread_location();
- if (thr_state_loc == nullptr || main_thread_identity == 0) {
- return (ThreadState *)&main_thread_state;
- }
- ThreadState **fake_tls = (ThreadState **)MemToShadow((uptr)thr_state_loc);
- ThreadState *thr = (ThreadState *)SignalSafeGetOrAllocate(
- (uptr *)fake_tls, sizeof(ThreadState));
- return thr;
+ return (ThreadState *)SignalSafeGetOrAllocate(
+ (uptr *)cur_thread_location(), sizeof(ThreadState));
+}
+
+void set_cur_thread(ThreadState *thr) {
+ *cur_thread_location() = thr;
}
// TODO(kuba.brecka): This is not async-signal-safe. In particular, we call
@@ -95,14 +96,13 @@ ThreadState *cur_thread() {
// handler will try to access the unmapped ThreadState.
void cur_thread_finalize() {
ThreadState **thr_state_loc = cur_thread_location();
- if (thr_state_loc == nullptr) {
+ if (thr_state_loc == &main_thread_state_loc) {
// Calling dispatch_main() or xpc_main() actually invokes pthread_exit to
// exit the main thread. Let's keep the main thread's ThreadState.
return;
}
- ThreadState **fake_tls = (ThreadState **)MemToShadow((uptr)thr_state_loc);
- internal_munmap(*fake_tls, sizeof(ThreadState));
- *fake_tls = nullptr;
+ internal_munmap(*thr_state_loc, sizeof(ThreadState));
+ *thr_state_loc = nullptr;
}
#endif
@@ -211,7 +211,7 @@ static void my_pthread_introspection_hook(unsigned int event, pthread_t thread,
ThreadState *parent_thread_state = nullptr; // No parent.
int tid = ThreadCreate(parent_thread_state, 0, (uptr)thread, true);
CHECK_NE(tid, 0);
- ThreadStart(thr, tid, GetTid(), /*workerthread*/ true);
+ ThreadStart(thr, tid, GetTid(), ThreadType::Worker);
}
} else if (event == PTHREAD_INTROSPECTION_THREAD_TERMINATE) {
if (thread == pthread_self()) {
@@ -238,8 +238,7 @@ void InitializePlatformEarly() {
#endif
}
-static const uptr kPthreadSetjmpXorKeySlot = 0x7;
-extern "C" uptr __tsan_darwin_setjmp_xor_key = 0;
+static uptr longjmp_xor_key = 0;
void InitializePlatform() {
DisableCoreDumperIfNecessary();
@@ -254,21 +253,35 @@ void InitializePlatform() {
#endif
if (GetMacosVersion() >= MACOS_VERSION_MOJAVE) {
- __tsan_darwin_setjmp_xor_key =
- (uptr)pthread_getspecific(kPthreadSetjmpXorKeySlot);
+ // Libsystem currently uses a process-global key; this might change.
+ const unsigned kTLSLongjmpXorKeySlot = 0x7;
+ longjmp_xor_key = (uptr)pthread_getspecific(kTLSLongjmpXorKeySlot);
}
}
+#ifdef __aarch64__
+# define LONG_JMP_SP_ENV_SLOT \
+ ((GetMacosVersion() >= MACOS_VERSION_MOJAVE) ? 12 : 13)
+#else
+# define LONG_JMP_SP_ENV_SLOT 2
+#endif
+
+uptr ExtractLongJmpSp(uptr *env) {
+ uptr mangled_sp = env[LONG_JMP_SP_ENV_SLOT];
+ uptr sp = mangled_sp ^ longjmp_xor_key;
+ return sp;
+}
+
#if !SANITIZER_GO
void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) {
// The pointer to the ThreadState object is stored in the shadow memory
// of the tls.
uptr tls_end = tls_addr + tls_size;
- ThreadState **thr_state_loc = cur_thread_location();
- if (thr_state_loc == nullptr) {
+ uptr thread_identity = (uptr)pthread_self();
+ if (thread_identity == main_thread_identity) {
MemoryRangeImitateWrite(thr, /*pc=*/2, tls_addr, tls_size);
} else {
- uptr thr_state_start = (uptr)thr_state_loc;
+ uptr thr_state_start = thread_identity;
uptr thr_state_end = thr_state_start + sizeof(uptr);
CHECK_GE(thr_state_start, tls_addr);
CHECK_LE(thr_state_start, tls_addr + tls_size);
diff --git a/libsanitizer/tsan/tsan_platform_posix.cc b/libsanitizer/tsan/tsan_platform_posix.cpp
index df9b6d4..1a0faee 100644
--- a/libsanitizer/tsan/tsan_platform_posix.cc
+++ b/libsanitizer/tsan/tsan_platform_posix.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_platform_posix.cc --------------------------------------------===//
+//===-- tsan_platform_posix.cpp -------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -29,14 +30,7 @@ static const char kShadowMemoryMappingHint[] =
"TSAN_OPTIONS=%s=0\n";
static void NoHugePagesInShadow(uptr addr, uptr size) {
- if (common_flags()->no_huge_pages_for_shadow)
- if (!NoHugePagesInRegion(addr, size)) {
- Printf(kShadowMemoryMappingWarning, SanitizerToolName, addr, addr + size,
- "MADV_NOHUGEPAGE", errno);
- Printf(kShadowMemoryMappingHint, "MADV_NOHUGEPAGE",
- "no_huge_pages_for_shadow");
- Die();
- }
+ SetShadowRegionHugePageMode(addr, size);
}
static void DontDumpShadow(uptr addr, uptr size) {
diff --git a/libsanitizer/tsan/tsan_platform_windows.cc b/libsanitizer/tsan/tsan_platform_windows.cpp
index 76883ca..1943787 100644
--- a/libsanitizer/tsan/tsan_platform_windows.cc
+++ b/libsanitizer/tsan/tsan_platform_windows.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_platform_windows.cc ------------------------------------------===//
+//===-- tsan_platform_windows.cpp -----------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_preinit.cc b/libsanitizer/tsan/tsan_preinit.cpp
index d5d1659..205bdbf 100644
--- a/libsanitizer/tsan/tsan_preinit.cc
+++ b/libsanitizer/tsan/tsan_preinit.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_preinit.cc ---------------------------------------------------===//
+//===-- tsan_preinit.cpp --------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_report.cc b/libsanitizer/tsan/tsan_report.cpp
index 4dffc34..655aa5f 100644
--- a/libsanitizer/tsan/tsan_report.cc
+++ b/libsanitizer/tsan/tsan_report.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_report.cc ----------------------------------------------------===//
+//===-- tsan_report.cpp ---------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -75,39 +76,42 @@ const char *thread_name(char *buf, int tid) {
}
static const char *ReportTypeString(ReportType typ, uptr tag) {
- if (typ == ReportTypeRace)
- return "data race";
- if (typ == ReportTypeVptrRace)
- return "data race on vptr (ctor/dtor vs virtual call)";
- if (typ == ReportTypeUseAfterFree)
- return "heap-use-after-free";
- if (typ == ReportTypeVptrUseAfterFree)
- return "heap-use-after-free (virtual call vs free)";
- if (typ == ReportTypeExternalRace) {
- const char *str = GetReportHeaderFromTag(tag);
- return str ? str : "race on external object";
+ switch (typ) {
+ case ReportTypeRace:
+ return "data race";
+ case ReportTypeVptrRace:
+ return "data race on vptr (ctor/dtor vs virtual call)";
+ case ReportTypeUseAfterFree:
+ return "heap-use-after-free";
+ case ReportTypeVptrUseAfterFree:
+ return "heap-use-after-free (virtual call vs free)";
+ case ReportTypeExternalRace: {
+ const char *str = GetReportHeaderFromTag(tag);
+ return str ? str : "race on external object";
+ }
+ case ReportTypeThreadLeak:
+ return "thread leak";
+ case ReportTypeMutexDestroyLocked:
+ return "destroy of a locked mutex";
+ case ReportTypeMutexDoubleLock:
+ return "double lock of a mutex";
+ case ReportTypeMutexInvalidAccess:
+ return "use of an invalid mutex (e.g. uninitialized or destroyed)";
+ case ReportTypeMutexBadUnlock:
+ return "unlock of an unlocked mutex (or by a wrong thread)";
+ case ReportTypeMutexBadReadLock:
+ return "read lock of a write locked mutex";
+ case ReportTypeMutexBadReadUnlock:
+ return "read unlock of a write locked mutex";
+ case ReportTypeSignalUnsafe:
+ return "signal-unsafe call inside of a signal";
+ case ReportTypeErrnoInSignal:
+ return "signal handler spoils errno";
+ case ReportTypeDeadlock:
+ return "lock-order-inversion (potential deadlock)";
+ // No default case so compiler warns us if we miss one
}
- if (typ == ReportTypeThreadLeak)
- return "thread leak";
- if (typ == ReportTypeMutexDestroyLocked)
- return "destroy of a locked mutex";
- if (typ == ReportTypeMutexDoubleLock)
- return "double lock of a mutex";
- if (typ == ReportTypeMutexInvalidAccess)
- return "use of an invalid mutex (e.g. uninitialized or destroyed)";
- if (typ == ReportTypeMutexBadUnlock)
- return "unlock of an unlocked mutex (or by a wrong thread)";
- if (typ == ReportTypeMutexBadReadLock)
- return "read lock of a write locked mutex";
- if (typ == ReportTypeMutexBadReadUnlock)
- return "read unlock of a write locked mutex";
- if (typ == ReportTypeSignalUnsafe)
- return "signal-unsafe call inside of a signal";
- if (typ == ReportTypeErrnoInSignal)
- return "signal handler spoils errno";
- if (typ == ReportTypeDeadlock)
- return "lock-order-inversion (potential deadlock)";
- return "";
+ UNREACHABLE("missing case");
}
#if SANITIZER_MAC
@@ -253,7 +257,7 @@ static void PrintThread(const ReportThread *rt) {
Printf(" '%s'", rt->name);
char thrbuf[kThreadBufSize];
const char *thread_status = rt->running ? "running" : "finished";
- if (rt->workerthread) {
+ if (rt->thread_type == ThreadType::Worker) {
Printf(" (tid=%zu, %s) is a GCD worker thread\n", rt->os_id, thread_status);
Printf("\n");
Printf("%s", d.Default());
@@ -294,7 +298,7 @@ static bool FrameIsInternal(const SymbolizedStack *frame) {
const char *file = frame->info.file;
const char *module = frame->info.module;
if (file != 0 &&
- (internal_strstr(file, "tsan_interceptors.cc") ||
+ (internal_strstr(file, "tsan_interceptors.cpp") ||
internal_strstr(file, "sanitizer_common_interceptors.inc") ||
internal_strstr(file, "tsan_interface_")))
return true;
diff --git a/libsanitizer/tsan/tsan_report.h b/libsanitizer/tsan/tsan_report.h
index 8e96e97..b4e4d89 100644
--- a/libsanitizer/tsan/tsan_report.h
+++ b/libsanitizer/tsan/tsan_report.h
@@ -1,7 +1,8 @@
//===-- tsan_report.h -------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -12,6 +13,7 @@
#define TSAN_REPORT_H
#include "sanitizer_common/sanitizer_symbolizer.h"
+#include "sanitizer_common/sanitizer_thread_registry.h"
#include "sanitizer_common/sanitizer_vector.h"
#include "tsan_defs.h"
@@ -90,7 +92,7 @@ struct ReportThread {
int id;
tid_t os_id;
bool running;
- bool workerthread;
+ ThreadType thread_type;
char *name;
u32 parent_tid;
ReportStack *stack;
diff --git a/libsanitizer/tsan/tsan_rtl.cc b/libsanitizer/tsan/tsan_rtl.cpp
index bd0892d..1ac3907 100644
--- a/libsanitizer/tsan/tsan_rtl.cc
+++ b/libsanitizer/tsan/tsan_rtl.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_rtl.cc -------------------------------------------------------===//
+//===-- tsan_rtl.cpp ------------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -148,6 +149,7 @@ static void BackgroundThread(void *arg) {
// We don't use ScopedIgnoreInterceptors, because we want ignores to be
// enabled even when the thread function exits (e.g. during pthread thread
// shutdown code).
+ cur_thread_init();
cur_thread()->ignore_interceptors++;
const u64 kMs2Ns = 1000 * 1000;
@@ -327,11 +329,8 @@ static void CheckShadowMapping() {
#if !SANITIZER_GO
static void OnStackUnwind(const SignalContext &sig, const void *,
BufferedStackTrace *stack) {
- uptr top = 0;
- uptr bottom = 0;
- bool fast = common_flags()->fast_unwind_on_fatal;
- if (fast) GetThreadStackTopAndBottom(false, &top, &bottom);
- stack->Unwind(kStackTraceMax, sig.pc, sig.bp, sig.context, top, bottom, fast);
+ stack->Unwind(sig.pc, sig.bp, sig.context,
+ common_flags()->fast_unwind_on_fatal);
}
static void TsanOnDeadlySignal(int signo, void *siginfo, void *context) {
@@ -352,12 +351,15 @@ void Initialize(ThreadState *thr) {
SetCheckFailedCallback(TsanCheckFailed);
ctx = new(ctx_placeholder) Context;
- const char *options = GetEnv(SANITIZER_GO ? "GORACE" : "TSAN_OPTIONS");
+ const char *env_name = SANITIZER_GO ? "GORACE" : "TSAN_OPTIONS";
+ const char *options = GetEnv(env_name);
CacheBinaryName();
CheckASLR();
- InitializeFlags(&ctx->flags, options);
+ InitializeFlags(&ctx->flags, options, env_name);
AvoidCVE_2016_2143();
- InitializePlatformEarly();
+ __sanitizer::InitializePlatformEarly();
+ __tsan::InitializePlatformEarly();
+
#if !SANITIZER_GO
// Re-exec ourselves if we need to set additional env or command line args.
MaybeReexec();
@@ -393,7 +395,7 @@ void Initialize(ThreadState *thr) {
// Initialize thread 0.
int tid = ThreadCreate(thr, 0, 0, true);
CHECK_EQ(tid, 0);
- ThreadStart(thr, tid, GetTid(), /*workerthread*/ false);
+ ThreadStart(thr, tid, GetTid(), ThreadType::Regular);
#if TSAN_CONTAINS_UBSAN
__ubsan::InitAsPlugin();
#endif
@@ -638,6 +640,7 @@ void MemoryAccessImpl1(ThreadState *thr, uptr addr,
// __m128i _mm_move_epi64(__m128i*);
// _mm_storel_epi64(u64*, __m128i);
u64 store_word = cur.raw();
+ bool stored = false;
// scan all the shadow values and dispatch to 4 categories:
// same, replace, candidate and race (see comments below).
@@ -662,16 +665,28 @@ void MemoryAccessImpl1(ThreadState *thr, uptr addr,
int idx = 0;
#include "tsan_update_shadow_word_inl.h"
idx = 1;
+ if (stored) {
+#include "tsan_update_shadow_word_inl.h"
+ } else {
#include "tsan_update_shadow_word_inl.h"
+ }
idx = 2;
+ if (stored) {
+#include "tsan_update_shadow_word_inl.h"
+ } else {
#include "tsan_update_shadow_word_inl.h"
+ }
idx = 3;
+ if (stored) {
#include "tsan_update_shadow_word_inl.h"
+ } else {
+#include "tsan_update_shadow_word_inl.h"
+ }
#endif
// we did not find any races and had already stored
// the current access info, so we are done
- if (LIKELY(store_word == 0))
+ if (LIKELY(stored))
return;
// choose a random candidate slot and replace it
StoreShadow(shadow_mem + (cur.epoch() % kShadowCnt), store_word);
@@ -811,7 +826,7 @@ void MemoryAccess(ThreadState *thr, uptr pc, uptr addr,
}
#endif
- if (!SANITIZER_GO && *shadow_mem == kShadowRodata) {
+ if (!SANITIZER_GO && !kAccessIsWrite && *shadow_mem == kShadowRodata) {
// Access to .rodata section, no races here.
// Measurements show that it can be 10-20% of all memory accesses.
StatInc(thr, StatMop);
@@ -822,7 +837,7 @@ void MemoryAccess(ThreadState *thr, uptr pc, uptr addr,
}
FastState fast_state = thr->fast_state;
- if (fast_state.GetIgnoreBit()) {
+ if (UNLIKELY(fast_state.GetIgnoreBit())) {
StatInc(thr, StatMop);
StatInc(thr, kAccessIsWrite ? StatMopWrite : StatMopRead);
StatInc(thr, (StatType)(StatMop1 + kAccessSizeLog));
@@ -855,7 +870,7 @@ void MemoryAccess(ThreadState *thr, uptr pc, uptr addr,
shadow_mem, cur);
}
-// Called by MemoryAccessRange in tsan_rtl_thread.cc
+// Called by MemoryAccessRange in tsan_rtl_thread.cpp
ALWAYS_INLINE USED
void MemoryAccessImpl(ThreadState *thr, uptr addr,
int kAccessSizeLog, bool kAccessIsWrite, bool kIsAtomic,
diff --git a/libsanitizer/tsan/tsan_rtl.h b/libsanitizer/tsan/tsan_rtl.h
index f97b583..3a8231b 100644
--- a/libsanitizer/tsan/tsan_rtl.h
+++ b/libsanitizer/tsan/tsan_rtl.h
@@ -1,7 +1,8 @@
//===-- tsan_rtl.h ----------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -54,18 +55,14 @@ namespace __tsan {
#if !SANITIZER_GO
struct MapUnmapCallback;
#if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__)
-static const uptr kAllocatorRegionSizeLog = 20;
-static const uptr kAllocatorNumRegions =
- SANITIZER_MMAP_RANGE_SIZE >> kAllocatorRegionSizeLog;
-typedef TwoLevelByteMap<(kAllocatorNumRegions >> 12), 1 << 12,
- MapUnmapCallback> ByteMap;
+
struct AP32 {
static const uptr kSpaceBeg = 0;
static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
static const uptr kMetadataSize = 0;
typedef __sanitizer::CompactSizeClassMap SizeClassMap;
- static const uptr kRegionSizeLog = kAllocatorRegionSizeLog;
- typedef __tsan::ByteMap ByteMap;
+ static const uptr kRegionSizeLog = 20;
+ using AddressSpaceView = LocalAddressSpaceView;
typedef __tsan::MapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
};
@@ -78,13 +75,12 @@ struct AP64 { // Allocator64 parameters. Deliberately using a short name.
typedef DefaultSizeClassMap SizeClassMap;
typedef __tsan::MapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
+ using AddressSpaceView = LocalAddressSpaceView;
};
typedef SizeClassAllocator64<AP64> PrimaryAllocator;
#endif
-typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
-typedef LargeMmapAllocator<MapUnmapCallback> SecondaryAllocator;
-typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
- SecondaryAllocator> Allocator;
+typedef CombinedAllocator<PrimaryAllocator> Allocator;
+typedef Allocator::AllocatorCache AllocatorCache;
Allocator *allocator();
#endif
@@ -329,7 +325,6 @@ struct ThreadSignalContext;
struct JmpBuf {
uptr sp;
- uptr mangled_sp;
int int_signal_send;
bool in_blocking_func;
uptr in_signal_handler;
@@ -381,6 +376,9 @@ struct ThreadState {
// taken by epoch between synchs.
// This way we can save one load from tls.
u64 fast_synch_epoch;
+ // Technically `current` should be a separate THREADLOCAL variable;
+ // but it is placed here in order to share cache line with previous fields.
+ ThreadState* current;
// This is a slow path flag. On fast path, fast_state.GetIgnoreBit() is read.
// We do not distinguish beteween ignoring reads and writes
// for better performance.
@@ -458,12 +456,22 @@ struct ThreadState {
#if !SANITIZER_GO
#if SANITIZER_MAC || SANITIZER_ANDROID
ThreadState *cur_thread();
+void set_cur_thread(ThreadState *thr);
void cur_thread_finalize();
+INLINE void cur_thread_init() { }
#else
__attribute__((tls_model("initial-exec")))
extern THREADLOCAL char cur_thread_placeholder[];
INLINE ThreadState *cur_thread() {
- return reinterpret_cast<ThreadState *>(&cur_thread_placeholder);
+ return reinterpret_cast<ThreadState *>(cur_thread_placeholder)->current;
+}
+INLINE void cur_thread_init() {
+ ThreadState *thr = reinterpret_cast<ThreadState *>(cur_thread_placeholder);
+ if (UNLIKELY(!thr->current))
+ thr->current = thr;
+}
+INLINE void set_cur_thread(ThreadState *thr) {
+ reinterpret_cast<ThreadState *>(cur_thread_placeholder)->current = thr;
}
INLINE void cur_thread_finalize() { }
#endif // SANITIZER_MAC || SANITIZER_ANDROID
@@ -761,7 +769,8 @@ void FuncEntry(ThreadState *thr, uptr pc);
void FuncExit(ThreadState *thr);
int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached);
-void ThreadStart(ThreadState *thr, int tid, tid_t os_id, bool workerthread);
+void ThreadStart(ThreadState *thr, int tid, tid_t os_id,
+ ThreadType thread_type);
void ThreadFinish(ThreadState *thr);
int ThreadTid(ThreadState *thr, uptr pc, uptr uid);
void ThreadJoin(ThreadState *thr, uptr pc, int tid);
@@ -770,6 +779,7 @@ void ThreadFinalize(ThreadState *thr);
void ThreadSetName(ThreadState *thr, const char *name);
int ThreadCount(ThreadState *thr);
void ProcessPendingSignals(ThreadState *thr);
+void ThreadNotJoined(ThreadState *thr, uptr pc, int tid, uptr uid);
Processor *ProcCreate();
void ProcDestroy(Processor *proc);
@@ -863,6 +873,16 @@ uptr ALWAYS_INLINE HeapEnd() {
}
#endif
+ThreadState *FiberCreate(ThreadState *thr, uptr pc, unsigned flags);
+void FiberDestroy(ThreadState *thr, uptr pc, ThreadState *fiber);
+void FiberSwitch(ThreadState *thr, uptr pc, ThreadState *fiber, unsigned flags);
+
+// These need to match __tsan_switch_to_fiber_* flags defined in
+// tsan_interface.h. See documentation there as well.
+enum FiberSwitchFlags {
+ FiberSwitchFlagNoSync = 1 << 0, // __tsan_switch_to_fiber_no_sync
+};
+
} // namespace __tsan
#endif // TSAN_RTL_H
diff --git a/libsanitizer/tsan/tsan_rtl_aarch64.S b/libsanitizer/tsan/tsan_rtl_aarch64.S
index 3d02bf2..e0b4c71 100644
--- a/libsanitizer/tsan/tsan_rtl_aarch64.S
+++ b/libsanitizer/tsan/tsan_rtl_aarch64.S
@@ -3,14 +3,6 @@
#include "sanitizer_common/sanitizer_asm.h"
-#if !defined(__APPLE__)
-.section .bss
-.type __tsan_pointer_chk_guard, %object
-ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__tsan_pointer_chk_guard))
-__tsan_pointer_chk_guard:
-.zero 8
-#endif
-
#if defined(__APPLE__)
.align 2
@@ -40,57 +32,6 @@ _sigsetjmp$non_lazy_ptr:
.align 3
#endif
-#if !defined(__APPLE__)
-// GLIBC mangles the function pointers in jmp_buf (used in {set,long}*jmp
-// functions) by XORing them with a random guard pointer. For AArch64 it is a
-// global variable rather than a TCB one (as for x86_64/powerpc) and althought
-// its value is exported by the loader, it lies within a private GLIBC
-// namespace (meaning it should be only used by GLIBC itself and the ABI is
-// not stable). So InitializeGuardPtr obtains the pointer guard value by
-// issuing a setjmp and checking the resulting pointers values against the
-// original ones.
-ASM_HIDDEN(_Z18InitializeGuardPtrv)
-.global _Z18InitializeGuardPtrv
-ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv))
-_Z18InitializeGuardPtrv:
- CFI_STARTPROC
- // Allocates a jmp_buf for the setjmp call.
- stp x29, x30, [sp, -336]!
- CFI_DEF_CFA_OFFSET (336)
- CFI_OFFSET (29, -336)
- CFI_OFFSET (30, -328)
- add x29, sp, 0
- CFI_DEF_CFA_REGISTER (29)
- add x0, x29, 24
-
- // Call libc setjmp that mangle the stack pointer value
- adrp x1, :got:_ZN14__interception12real__setjmpE
- ldr x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE]
- ldr x1, [x1]
- blr x1
-
- // glibc setjmp mangles both the frame pointer (FP, pc+4 on blr) and the
- // stack pointer (SP). FP will be placed on ((uintptr*)jmp_buf)[11] and
- // SP at ((uintptr*)jmp_buf)[13].
- // The mangle operation is just 'value' xor 'pointer guard value' and
- // if we know the original value (SP) and the expected one, we can derive
- // the guard pointer value.
- mov x0, sp
-
- // Loads the mangled SP pointer.
- ldr x1, [x29, 128]
- eor x0, x0, x1
- adrp x2, __tsan_pointer_chk_guard
- str x0, [x2, #:lo12:__tsan_pointer_chk_guard]
- ldp x29, x30, [sp], 336
- CFI_RESTORE (30)
- CFI_RESTORE (19)
- CFI_DEF_CFA (31, 0)
- ret
- CFI_ENDPROC
-ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv))
-#endif
-
ASM_HIDDEN(__tsan_setjmp)
.comm _ZN14__interception11real_setjmpE,8,8
.globl ASM_SYMBOL_INTERCEPTOR(setjmp)
@@ -98,7 +39,7 @@ ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(setjmp))
ASM_SYMBOL_INTERCEPTOR(setjmp):
CFI_STARTPROC
- // save env parameters for function call
+ // Save frame/link register
stp x29, x30, [sp, -32]!
CFI_DEF_CFA_OFFSET (32)
CFI_OFFSET (29, -32)
@@ -108,33 +49,24 @@ ASM_SYMBOL_INTERCEPTOR(setjmp):
add x29, sp, 0
CFI_DEF_CFA_REGISTER (29)
- // Save jmp_buf
- str x19, [sp, 16]
- CFI_OFFSET (19, -16)
- mov x19, x0
+ // Save env parameter
+ str x0, [sp, 16]
+ CFI_OFFSET (0, -16)
-#if !defined(__APPLE__)
- // SP pointer mangling (see glibc setjmp)
- adrp x2, __tsan_pointer_chk_guard
- ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard]
- add x0, x29, 32
- eor x1, x2, x0
-#else
- adrp x2, ___tsan_darwin_setjmp_xor_key@page
- ldr x2, [x2, ___tsan_darwin_setjmp_xor_key@pageoff]
+ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)`
add x0, x29, 32
- eor x1, x2, x0
-#endif
// call tsan interceptor
bl ASM_SYMBOL(__tsan_setjmp)
- // restore env parameter
- mov x0, x19
- ldr x19, [sp, 16]
+ // Restore env parameter
+ ldr x0, [sp, 16]
+ CFI_RESTORE (0)
+
+ // Restore frame/link register
ldp x29, x30, [sp], 32
+ CFI_RESTORE (29)
CFI_RESTORE (30)
- CFI_RESTORE (19)
CFI_DEF_CFA (31, 0)
// tail jump to libc setjmp
@@ -158,7 +90,7 @@ ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_setjmp))
ASM_SYMBOL_INTERCEPTOR(_setjmp):
CFI_STARTPROC
- // save env parameters for function call
+ // Save frame/link register
stp x29, x30, [sp, -32]!
CFI_DEF_CFA_OFFSET (32)
CFI_OFFSET (29, -32)
@@ -168,33 +100,24 @@ ASM_SYMBOL_INTERCEPTOR(_setjmp):
add x29, sp, 0
CFI_DEF_CFA_REGISTER (29)
- // Save jmp_buf
- str x19, [sp, 16]
- CFI_OFFSET (19, -16)
- mov x19, x0
+ // Save env parameter
+ str x0, [sp, 16]
+ CFI_OFFSET (0, -16)
-#if !defined(__APPLE__)
- // SP pointer mangling (see glibc setjmp)
- adrp x2, __tsan_pointer_chk_guard
- ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard]
+ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)`
add x0, x29, 32
- eor x1, x2, x0
-#else
- adrp x2, ___tsan_darwin_setjmp_xor_key@page
- ldr x2, [x2, ___tsan_darwin_setjmp_xor_key@pageoff]
- add x0, x29, 32
- eor x1, x2, x0
-#endif
// call tsan interceptor
bl ASM_SYMBOL(__tsan_setjmp)
- // Restore jmp_buf parameter
- mov x0, x19
- ldr x19, [sp, 16]
+ // Restore env parameter
+ ldr x0, [sp, 16]
+ CFI_RESTORE (0)
+
+ // Restore frame/link register
ldp x29, x30, [sp], 32
+ CFI_RESTORE (29)
CFI_RESTORE (30)
- CFI_RESTORE (19)
CFI_DEF_CFA (31, 0)
// tail jump to libc setjmp
@@ -218,7 +141,7 @@ ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(sigsetjmp))
ASM_SYMBOL_INTERCEPTOR(sigsetjmp):
CFI_STARTPROC
- // save env parameters for function call
+ // Save frame/link register
stp x29, x30, [sp, -32]!
CFI_DEF_CFA_OFFSET (32)
CFI_OFFSET (29, -32)
@@ -228,38 +151,26 @@ ASM_SYMBOL_INTERCEPTOR(sigsetjmp):
add x29, sp, 0
CFI_DEF_CFA_REGISTER (29)
- // Save jmp_buf and savesigs
- stp x19, x20, [sp, 16]
- CFI_OFFSET (19, -16)
- CFI_OFFSET (20, -8)
- mov w20, w1
- mov x19, x0
+ // Save env and savesigs parameter
+ stp x0, x1, [sp, 16]
+ CFI_OFFSET (0, -16)
+ CFI_OFFSET (1, -8)
-#if !defined(__APPLE__)
- // SP pointer mangling (see glibc setjmp)
- adrp x2, __tsan_pointer_chk_guard
- ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard]
- add x0, x29, 32
- eor x1, x2, x0
-#else
- adrp x2, ___tsan_darwin_setjmp_xor_key@page
- ldr x2, [x2, ___tsan_darwin_setjmp_xor_key@pageoff]
+ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)`
add x0, x29, 32
- eor x1, x2, x0
-#endif
// call tsan interceptor
bl ASM_SYMBOL(__tsan_setjmp)
- // restore env parameter
- mov w1, w20
- mov x0, x19
- ldp x19, x20, [sp, 16]
+ // Restore env and savesigs parameter
+ ldp x0, x1, [sp, 16]
+ CFI_RESTORE (0)
+ CFI_RESTORE (1)
+
+ // Restore frame/link register
ldp x29, x30, [sp], 32
- CFI_RESTORE (30)
CFI_RESTORE (29)
- CFI_RESTORE (19)
- CFI_RESTORE (20)
+ CFI_RESTORE (30)
CFI_DEF_CFA (31, 0)
// tail jump to libc sigsetjmp
@@ -283,7 +194,7 @@ ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp))
ASM_SYMBOL_INTERCEPTOR(__sigsetjmp):
CFI_STARTPROC
- // save env parameters for function call
+ // Save frame/link register
stp x29, x30, [sp, -32]!
CFI_DEF_CFA_OFFSET (32)
CFI_OFFSET (29, -32)
@@ -293,32 +204,26 @@ ASM_SYMBOL_INTERCEPTOR(__sigsetjmp):
add x29, sp, 0
CFI_DEF_CFA_REGISTER (29)
- // Save jmp_buf and savesigs
- stp x19, x20, [sp, 16]
- CFI_OFFSET (19, -16)
- CFI_OFFSET (20, -8)
- mov w20, w1
- mov x19, x0
+ // Save env and savesigs parameter
+ stp x0, x1, [sp, 16]
+ CFI_OFFSET (0, -16)
+ CFI_OFFSET (1, -8)
-#if !defined(__APPLE__)
- // SP pointer mangling (see glibc setjmp)
- adrp x2, __tsan_pointer_chk_guard
- ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard]
+ // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)`
add x0, x29, 32
- eor x1, x2, x0
-#endif
// call tsan interceptor
bl ASM_SYMBOL(__tsan_setjmp)
- mov w1, w20
- mov x0, x19
- ldp x19, x20, [sp, 16]
+ // Restore env and savesigs parameter
+ ldp x0, x1, [sp, 16]
+ CFI_RESTORE (0)
+ CFI_RESTORE (1)
+
+ // Restore frame/link register
ldp x29, x30, [sp], 32
- CFI_RESTORE (30)
CFI_RESTORE (29)
- CFI_RESTORE (19)
- CFI_RESTORE (20)
+ CFI_RESTORE (30)
CFI_DEF_CFA (31, 0)
// tail jump to libc __sigsetjmp
@@ -335,9 +240,6 @@ ASM_SYMBOL_INTERCEPTOR(__sigsetjmp):
ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp))
#endif
-#if defined(__linux__)
-/* We do not need executable stack. */
-.section .note.GNU-stack,"",@progbits
-#endif
+NO_EXEC_STACK_DIRECTIVE
#endif
diff --git a/libsanitizer/tsan/tsan_rtl_amd64.S b/libsanitizer/tsan/tsan_rtl_amd64.S
index 34ef51c..5913aa3 100644
--- a/libsanitizer/tsan/tsan_rtl_amd64.S
+++ b/libsanitizer/tsan/tsan_rtl_amd64.S
@@ -189,19 +189,11 @@ ASM_SYMBOL_INTERCEPTOR(setjmp):
push %rdi
CFI_ADJUST_CFA_OFFSET(8)
CFI_REL_OFFSET(%rdi, 0)
- // obtain %rsp
+ // obtain SP, store in %rdi, first argument to `void __tsan_setjmp(uptr sp)`
#if defined(__FreeBSD__) || defined(__NetBSD__)
lea 8(%rsp), %rdi
- mov %rdi, %rsi
-#elif defined(__APPLE__)
+#elif defined(__linux__) || defined(__APPLE__)
lea 16(%rsp), %rdi
- mov %rdi, %rsi
- xorq ___tsan_darwin_setjmp_xor_key(%rip), %rsi
-#elif defined(__linux__)
- lea 16(%rsp), %rdi
- mov %rdi, %rsi
- xor %fs:0x30, %rsi // magic mangling of rsp (see libc setjmp)
- rol $0x11, %rsi
#else
# error "Unknown platform"
#endif
@@ -238,19 +230,11 @@ ASM_SYMBOL_INTERCEPTOR(_setjmp):
push %rdi
CFI_ADJUST_CFA_OFFSET(8)
CFI_REL_OFFSET(%rdi, 0)
- // obtain %rsp
+ // obtain SP, store in %rdi, first argument to `void __tsan_setjmp(uptr sp)`
#if defined(__FreeBSD__) || defined(__NetBSD__)
lea 8(%rsp), %rdi
- mov %rdi, %rsi
-#elif defined(__APPLE__)
- lea 16(%rsp), %rdi
- mov %rdi, %rsi
- xorq ___tsan_darwin_setjmp_xor_key(%rip), %rsi
-#elif defined(__linux__)
+#elif defined(__linux__) || defined(__APPLE__)
lea 16(%rsp), %rdi
- mov %rdi, %rsi
- xor %fs:0x30, %rsi // magic mangling of rsp (see libc setjmp)
- rol $0x11, %rsi
#else
# error "Unknown platform"
#endif
@@ -294,19 +278,11 @@ ASM_SYMBOL_INTERCEPTOR(sigsetjmp):
// align stack frame
sub $8, %rsp
CFI_ADJUST_CFA_OFFSET(8)
- // obtain %rsp
+ // obtain SP, store in %rdi, first argument to `void __tsan_setjmp(uptr sp)`
#if defined(__FreeBSD__) || defined(__NetBSD__)
lea 24(%rsp), %rdi
- mov %rdi, %rsi
-#elif defined(__APPLE__)
+#elif defined(__linux__) || defined(__APPLE__)
lea 32(%rsp), %rdi
- mov %rdi, %rsi
- xorq ___tsan_darwin_setjmp_xor_key(%rip), %rsi
-#elif defined(__linux__)
- lea 32(%rsp), %rdi
- mov %rdi, %rsi
- xor %fs:0x30, %rsi // magic mangling of rsp (see libc setjmp)
- rol $0x11, %rsi
#else
# error "Unknown platform"
#endif
@@ -358,15 +334,11 @@ ASM_SYMBOL_INTERCEPTOR(__sigsetjmp):
// align stack frame
sub $8, %rsp
CFI_ADJUST_CFA_OFFSET(8)
- // obtain %rsp
+ // obtain SP, store in %rdi, first argument to `void __tsan_setjmp(uptr sp)`
#if defined(__FreeBSD__)
lea 24(%rsp), %rdi
- mov %rdi, %rsi
#else
lea 32(%rsp), %rdi
- mov %rdi, %rsi
- xor %fs:0x30, %rsi // magic mangling of rsp (see libc setjmp)
- rol $0x11, %rsi
#endif
// call tsan interceptor
call ASM_SYMBOL(__tsan_setjmp)
@@ -389,10 +361,6 @@ ASM_SYMBOL_INTERCEPTOR(__sigsetjmp):
ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp))
#endif // !defined(__APPLE__) && !defined(__NetBSD__)
-#if defined(__FreeBSD__) || defined(__linux__)
-/* We do not need executable stack. */
-/* This note is not needed on NetBSD. */
-.section .note.GNU-stack,"",@progbits
-#endif
+NO_EXEC_STACK_DIRECTIVE
#endif
diff --git a/libsanitizer/tsan/tsan_rtl_mutex.cc b/libsanitizer/tsan/tsan_rtl_mutex.cpp
index 6981f98..ce6e7cb 100644
--- a/libsanitizer/tsan/tsan_rtl_mutex.cc
+++ b/libsanitizer/tsan/tsan_rtl_mutex.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_rtl_mutex.cc -------------------------------------------------===//
+//===-- tsan_rtl_mutex.cpp ------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_rtl_proc.cc b/libsanitizer/tsan/tsan_rtl_proc.cpp
index 1b0a9b3..def61cc 100644
--- a/libsanitizer/tsan/tsan_rtl_proc.cc
+++ b/libsanitizer/tsan/tsan_rtl_proc.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_rtl_proc.cc ------------------------------------------------===//
+//===-- tsan_rtl_proc.cpp -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_rtl_report.cc b/libsanitizer/tsan/tsan_rtl_report.cpp
index 18b6cf7..47b8bf7 100644
--- a/libsanitizer/tsan/tsan_rtl_report.cc
+++ b/libsanitizer/tsan/tsan_rtl_report.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_rtl_report.cc ------------------------------------------------===//
+//===-- tsan_rtl_report.cpp -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -200,7 +201,7 @@ void ScopedReportBase::AddThread(const ThreadContext *tctx, bool suppressable) {
rt->running = (tctx->status == ThreadStatusRunning);
rt->name = internal_strdup(tctx->name);
rt->parent_tid = tctx->parent_tid;
- rt->workerthread = tctx->workerthread;
+ rt->thread_type = tctx->thread_type;
rt->stack = 0;
rt->stack = SymbolizeStackId(tctx->creation_stack_id);
if (rt->stack)
@@ -649,7 +650,7 @@ void ReportRace(ThreadState *thr) {
// and the resulting PC has kExternalPCBit set, so we pass it to
// __tsan_symbolize_external_ex. __tsan_symbolize_external_ex is within its
// rights to crash since the PC is completely bogus.
- // test/tsan/double_race.cc contains a test case for this.
+ // test/tsan/double_race.cpp contains a test case for this.
toppc = 0;
}
ObtainCurrentStack(thr, toppc, &traces[0], &tags[0]);
@@ -728,10 +729,12 @@ void PrintCurrentStack(ThreadState *thr, uptr pc) {
ALWAYS_INLINE
void PrintCurrentStackSlow(uptr pc) {
#if !SANITIZER_GO
+ uptr bp = GET_CURRENT_FRAME();
BufferedStackTrace *ptrace =
new(internal_alloc(MBlockStackTrace, sizeof(BufferedStackTrace)))
BufferedStackTrace();
- ptrace->Unwind(kStackTraceMax, pc, 0, 0, 0, 0, false);
+ ptrace->Unwind(pc, bp, nullptr, false);
+
for (uptr i = 0; i < ptrace->size / 2; i++) {
uptr tmp = ptrace->trace_buffer[i];
ptrace->trace_buffer[i] = ptrace->trace_buffer[ptrace->size - i - 1];
diff --git a/libsanitizer/tsan/tsan_rtl_thread.cc b/libsanitizer/tsan/tsan_rtl_thread.cpp
index 7a731c4..0ac1ee9 100644
--- a/libsanitizer/tsan/tsan_rtl_thread.cc
+++ b/libsanitizer/tsan/tsan_rtl_thread.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_rtl_thread.cc ------------------------------------------------===//
+//===-- tsan_rtl_thread.cpp -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -238,13 +239,15 @@ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached) {
return tid;
}
-void ThreadStart(ThreadState *thr, int tid, tid_t os_id, bool workerthread) {
+void ThreadStart(ThreadState *thr, int tid, tid_t os_id,
+ ThreadType thread_type) {
uptr stk_addr = 0;
uptr stk_size = 0;
uptr tls_addr = 0;
uptr tls_size = 0;
#if !SANITIZER_GO
- GetThreadStackAndTls(tid == 0, &stk_addr, &stk_size, &tls_addr, &tls_size);
+ if (thread_type != ThreadType::Fiber)
+ GetThreadStackAndTls(tid == 0, &stk_addr, &stk_size, &tls_addr, &tls_size);
if (tid) {
if (stk_addr && stk_size)
@@ -256,7 +259,7 @@ void ThreadStart(ThreadState *thr, int tid, tid_t os_id, bool workerthread) {
ThreadRegistry *tr = ctx->thread_registry;
OnStartedArgs args = { thr, stk_addr, stk_size, tls_addr, tls_size };
- tr->StartThread(tid, os_id, workerthread, &args);
+ tr->StartThread(tid, os_id, thread_type, &args);
tr->Lock();
thr->tctx = (ThreadContext*)tr->GetThreadLocked(tid);
@@ -310,6 +313,12 @@ void ThreadDetach(ThreadState *thr, uptr pc, int tid) {
ctx->thread_registry->DetachThread(tid, thr);
}
+void ThreadNotJoined(ThreadState *thr, uptr pc, int tid, uptr uid) {
+ CHECK_GT(tid, 0);
+ CHECK_LT(tid, kMaxTid);
+ ctx->thread_registry->SetThreadUserId(tid, uid);
+}
+
void ThreadSetName(ThreadState *thr, const char *name) {
ctx->thread_registry->SetThreadName(thr->tid, name);
}
@@ -396,4 +405,40 @@ void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr,
}
}
+#if !SANITIZER_GO
+void FiberSwitchImpl(ThreadState *from, ThreadState *to) {
+ Processor *proc = from->proc();
+ ProcUnwire(proc, from);
+ ProcWire(proc, to);
+ set_cur_thread(to);
+}
+
+ThreadState *FiberCreate(ThreadState *thr, uptr pc, unsigned flags) {
+ void *mem = internal_alloc(MBlockThreadContex, sizeof(ThreadState));
+ ThreadState *fiber = static_cast<ThreadState *>(mem);
+ internal_memset(fiber, 0, sizeof(*fiber));
+ int tid = ThreadCreate(thr, pc, 0, true);
+ FiberSwitchImpl(thr, fiber);
+ ThreadStart(fiber, tid, 0, ThreadType::Fiber);
+ FiberSwitchImpl(fiber, thr);
+ return fiber;
+}
+
+void FiberDestroy(ThreadState *thr, uptr pc, ThreadState *fiber) {
+ FiberSwitchImpl(thr, fiber);
+ ThreadFinish(fiber);
+ FiberSwitchImpl(fiber, thr);
+ internal_free(fiber);
+}
+
+void FiberSwitch(ThreadState *thr, uptr pc,
+ ThreadState *fiber, unsigned flags) {
+ if (!(flags & FiberSwitchFlagNoSync))
+ Release(thr, pc, (uptr)fiber);
+ FiberSwitchImpl(thr, fiber);
+ if (!(flags & FiberSwitchFlagNoSync))
+ Acquire(fiber, pc, (uptr)fiber);
+}
+#endif
+
} // namespace __tsan
diff --git a/libsanitizer/tsan/tsan_stack_trace.cc b/libsanitizer/tsan/tsan_stack_trace.cpp
index 4ddec96..403a21a 100644
--- a/libsanitizer/tsan/tsan_stack_trace.cc
+++ b/libsanitizer/tsan/tsan_stack_trace.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_stack_trace.cc -----------------------------------------------===//
+//===-- tsan_stack_trace.cpp ----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -47,3 +48,16 @@ void VarSizeStackTrace::ReverseOrder() {
}
} // namespace __tsan
+
+#if !SANITIZER_GO
+void __sanitizer::BufferedStackTrace::UnwindImpl(
+ uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
+ uptr top = 0;
+ uptr bottom = 0;
+ if (StackTrace::WillUseFastUnwind(request_fast)) {
+ GetThreadStackTopAndBottom(false, &top, &bottom);
+ Unwind(max_depth, pc, bp, nullptr, top, bottom, true);
+ } else
+ Unwind(max_depth, pc, 0, context, 0, 0, false);
+}
+#endif // SANITIZER_GO
diff --git a/libsanitizer/tsan/tsan_stack_trace.h b/libsanitizer/tsan/tsan_stack_trace.h
index bc4468f..3eb8ce1 100644
--- a/libsanitizer/tsan/tsan_stack_trace.h
+++ b/libsanitizer/tsan/tsan_stack_trace.h
@@ -1,7 +1,8 @@
//===-- tsan_stack_trace.h --------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_stat.cc b/libsanitizer/tsan/tsan_stat.cpp
index decb7a2..78f3cce 100644
--- a/libsanitizer/tsan/tsan_stat.cc
+++ b/libsanitizer/tsan/tsan_stat.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_stat.cc ------------------------------------------------------===//
+//===-- tsan_stat.cpp -----------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_stat.h b/libsanitizer/tsan/tsan_stat.h
index c4859df..94e18bc 100644
--- a/libsanitizer/tsan/tsan_stat.h
+++ b/libsanitizer/tsan/tsan_stat.h
@@ -1,7 +1,8 @@
//===-- tsan_stat.h ---------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_suppressions.cc b/libsanitizer/tsan/tsan_suppressions.cpp
index d48148f..6bf6720 100644
--- a/libsanitizer/tsan/tsan_suppressions.cc
+++ b/libsanitizer/tsan/tsan_suppressions.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_suppressions.cc ----------------------------------------------===//
+//===-- tsan_suppressions.cpp ---------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -64,38 +65,30 @@ SuppressionContext *Suppressions() {
}
static const char *conv(ReportType typ) {
- if (typ == ReportTypeRace)
- return kSuppressionRace;
- else if (typ == ReportTypeVptrRace)
- return kSuppressionRace;
- else if (typ == ReportTypeUseAfterFree)
- return kSuppressionRace;
- else if (typ == ReportTypeVptrUseAfterFree)
- return kSuppressionRace;
- else if (typ == ReportTypeExternalRace)
- return kSuppressionRace;
- else if (typ == ReportTypeThreadLeak)
- return kSuppressionThread;
- else if (typ == ReportTypeMutexDestroyLocked)
- return kSuppressionMutex;
- else if (typ == ReportTypeMutexDoubleLock)
- return kSuppressionMutex;
- else if (typ == ReportTypeMutexInvalidAccess)
- return kSuppressionMutex;
- else if (typ == ReportTypeMutexBadUnlock)
- return kSuppressionMutex;
- else if (typ == ReportTypeMutexBadReadLock)
- return kSuppressionMutex;
- else if (typ == ReportTypeMutexBadReadUnlock)
- return kSuppressionMutex;
- else if (typ == ReportTypeSignalUnsafe)
- return kSuppressionSignal;
- else if (typ == ReportTypeErrnoInSignal)
- return kSuppressionNone;
- else if (typ == ReportTypeDeadlock)
- return kSuppressionDeadlock;
- Printf("ThreadSanitizer: unknown report type %d\n", typ);
- Die();
+ switch (typ) {
+ case ReportTypeRace:
+ case ReportTypeVptrRace:
+ case ReportTypeUseAfterFree:
+ case ReportTypeVptrUseAfterFree:
+ case ReportTypeExternalRace:
+ return kSuppressionRace;
+ case ReportTypeThreadLeak:
+ return kSuppressionThread;
+ case ReportTypeMutexDestroyLocked:
+ case ReportTypeMutexDoubleLock:
+ case ReportTypeMutexInvalidAccess:
+ case ReportTypeMutexBadUnlock:
+ case ReportTypeMutexBadReadLock:
+ case ReportTypeMutexBadReadUnlock:
+ return kSuppressionMutex;
+ case ReportTypeSignalUnsafe:
+ case ReportTypeErrnoInSignal:
+ return kSuppressionSignal;
+ case ReportTypeDeadlock:
+ return kSuppressionDeadlock;
+ // No default case so compiler warns us if we miss one
+ }
+ UNREACHABLE("missing case");
}
static uptr IsSuppressed(const char *stype, const AddressInfo &info,
diff --git a/libsanitizer/tsan/tsan_suppressions.h b/libsanitizer/tsan/tsan_suppressions.h
index 5895197..f430aeb6 100644
--- a/libsanitizer/tsan/tsan_suppressions.h
+++ b/libsanitizer/tsan/tsan_suppressions.h
@@ -1,7 +1,8 @@
//===-- tsan_suppressions.h -------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_symbolize.cc b/libsanitizer/tsan/tsan_symbolize.cpp
index 074006b..6478f3a 100644
--- a/libsanitizer/tsan/tsan_symbolize.cc
+++ b/libsanitizer/tsan/tsan_symbolize.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_symbolize.cc -------------------------------------------------===//
+//===-- tsan_symbolize.cpp ------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_symbolize.h b/libsanitizer/tsan/tsan_symbolize.h
index a859f63..7adaa04 100644
--- a/libsanitizer/tsan/tsan_symbolize.h
+++ b/libsanitizer/tsan/tsan_symbolize.h
@@ -1,7 +1,8 @@
//===-- tsan_symbolize.h ----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_sync.cc b/libsanitizer/tsan/tsan_sync.cpp
index 10ae446..7f686dc 100644
--- a/libsanitizer/tsan/tsan_sync.cc
+++ b/libsanitizer/tsan/tsan_sync.cpp
@@ -1,7 +1,8 @@
-//===-- tsan_sync.cc ------------------------------------------------------===//
+//===-- tsan_sync.cpp -----------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_sync.h b/libsanitizer/tsan/tsan_sync.h
index a4409fe..47f2739 100644
--- a/libsanitizer/tsan/tsan_sync.h
+++ b/libsanitizer/tsan/tsan_sync.h
@@ -1,7 +1,8 @@
//===-- tsan_sync.h ---------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_trace.h b/libsanitizer/tsan/tsan_trace.h
index 5cc3f8f..fbd0f72 100644
--- a/libsanitizer/tsan/tsan_trace.h
+++ b/libsanitizer/tsan/tsan_trace.h
@@ -1,7 +1,8 @@
//===-- tsan_trace.h --------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/tsan/tsan_update_shadow_word_inl.h b/libsanitizer/tsan/tsan_update_shadow_word_inl.h
index 2ea7428..056c3aa 100644
--- a/libsanitizer/tsan/tsan_update_shadow_word_inl.h
+++ b/libsanitizer/tsan/tsan_update_shadow_word_inl.h
@@ -1,7 +1,8 @@
//===-- tsan_update_shadow_word_inl.h ---------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -16,31 +17,35 @@ do {
const unsigned kAccessSize = 1 << kAccessSizeLog;
u64 *sp = &shadow_mem[idx];
old = LoadShadow(sp);
- if (old.IsZero()) {
+ if (LIKELY(old.IsZero())) {
StatInc(thr, StatShadowZero);
- if (store_word)
+ if (!stored) {
StoreIfNotYetStored(sp, &store_word);
- // The above StoreIfNotYetStored could be done unconditionally
- // and it even shows 4% gain on synthetic benchmarks (r4307).
+ stored = true;
+ }
break;
}
// is the memory access equal to the previous?
- if (Shadow::Addr0AndSizeAreEqual(cur, old)) {
+ if (LIKELY(Shadow::Addr0AndSizeAreEqual(cur, old))) {
StatInc(thr, StatShadowSameSize);
// same thread?
- if (Shadow::TidsAreEqual(old, cur)) {
+ if (LIKELY(Shadow::TidsAreEqual(old, cur))) {
StatInc(thr, StatShadowSameThread);
- if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic))
+ if (LIKELY(old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic))) {
StoreIfNotYetStored(sp, &store_word);
+ stored = true;
+ }
break;
}
StatInc(thr, StatShadowAnotherThread);
if (HappensBefore(old, thr)) {
- if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic))
+ if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic)) {
StoreIfNotYetStored(sp, &store_word);
+ stored = true;
+ }
break;
}
- if (old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic))
+ if (LIKELY(old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic)))
break;
goto RACE;
}
@@ -54,7 +59,7 @@ do {
StatInc(thr, StatShadowAnotherThread);
if (old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic))
break;
- if (HappensBefore(old, thr))
+ if (LIKELY(HappensBefore(old, thr)))
break;
goto RACE;
}
diff --git a/libsanitizer/ubsan/Makefile.am b/libsanitizer/ubsan/Makefile.am
index 1f924f8..46021d6 100644
--- a/libsanitizer/ubsan/Makefile.am
+++ b/libsanitizer/ubsan/Makefile.am
@@ -13,16 +13,16 @@ ACLOCAL_AMFLAGS = -I m4
toolexeclib_LTLIBRARIES = libubsan.la
ubsan_plugin_files = \
- ubsan_diag.cc \
- ubsan_flags.cc \
- ubsan_handlers.cc \
- ubsan_handlers_cxx.cc \
- ubsan_init.cc \
- ubsan_monitor.cc \
- ubsan_type_hash.cc \
- ubsan_type_hash_itanium.cc \
- ubsan_type_hash_win.cc \
- ubsan_value.cc
+ ubsan_diag.cpp \
+ ubsan_flags.cpp \
+ ubsan_handlers.cpp \
+ ubsan_handlers_cxx.cpp \
+ ubsan_init.cpp \
+ ubsan_monitor.cpp \
+ ubsan_type_hash.cpp \
+ ubsan_type_hash_itanium.cpp \
+ ubsan_type_hash_win.cpp \
+ ubsan_value.cpp
ubsan_files = $(ubsan_plugin_files)
diff --git a/libsanitizer/ubsan/Makefile.in b/libsanitizer/ubsan/Makefile.in
index b1ba31a..71d2626 100644
--- a/libsanitizer/ubsan/Makefile.in
+++ b/libsanitizer/ubsan/Makefile.in
@@ -379,16 +379,16 @@ AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic \
ACLOCAL_AMFLAGS = -I m4
toolexeclib_LTLIBRARIES = libubsan.la
ubsan_plugin_files = \
- ubsan_diag.cc \
- ubsan_flags.cc \
- ubsan_handlers.cc \
- ubsan_handlers_cxx.cc \
- ubsan_init.cc \
- ubsan_monitor.cc \
- ubsan_type_hash.cc \
- ubsan_type_hash_itanium.cc \
- ubsan_type_hash_win.cc \
- ubsan_value.cc
+ ubsan_diag.cpp \
+ ubsan_flags.cpp \
+ ubsan_handlers.cpp \
+ ubsan_handlers_cxx.cpp \
+ ubsan_init.cpp \
+ ubsan_monitor.cpp \
+ ubsan_type_hash.cpp \
+ ubsan_type_hash_itanium.cpp \
+ ubsan_type_hash_win.cpp \
+ ubsan_value.cpp
ubsan_files = $(ubsan_plugin_files)
libubsan_la_SOURCES = $(ubsan_files)
@@ -439,7 +439,7 @@ MAKEOVERRIDES =
all: all-am
.SUFFIXES:
-.SUFFIXES: .cc .lo .o .obj
+.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
@@ -525,21 +525,21 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_type_hash_win.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_value.Plo@am__quote@
-.cc.o:
+.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
-.cc.obj:
+.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-.cc.lo:
+.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
diff --git a/libsanitizer/ubsan/ubsan_checks.inc b/libsanitizer/ubsan/ubsan_checks.inc
index dbe5550..7e7216c 100644
--- a/libsanitizer/ubsan/ubsan_checks.inc
+++ b/libsanitizer/ubsan/ubsan_checks.inc
@@ -1,7 +1,8 @@
//===-- ubsan_checks.inc ----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -19,6 +20,7 @@ UBSAN_CHECK(GenericUB, "undefined-behavior", "undefined")
UBSAN_CHECK(NullPointerUse, "null-pointer-use", "null")
UBSAN_CHECK(PointerOverflow, "pointer-overflow", "pointer-overflow")
UBSAN_CHECK(MisalignedPointerUse, "misaligned-pointer-use", "alignment")
+UBSAN_CHECK(AlignmentAssumption, "alignment-assumption", "alignment")
UBSAN_CHECK(InsufficientObjectSize, "insufficient-object-size", "object-size")
UBSAN_CHECK(SignedIntegerOverflow, "signed-integer-overflow",
"signed-integer-overflow")
@@ -34,6 +36,12 @@ UBSAN_CHECK(ImplicitUnsignedIntegerTruncation,
UBSAN_CHECK(ImplicitSignedIntegerTruncation,
"implicit-signed-integer-truncation",
"implicit-signed-integer-truncation")
+UBSAN_CHECK(ImplicitIntegerSignChange,
+ "implicit-integer-sign-change",
+ "implicit-integer-sign-change")
+UBSAN_CHECK(ImplicitSignedIntegerTruncationOrSignChange,
+ "implicit-signed-integer-truncation-or-sign-change",
+ "implicit-signed-integer-truncation,implicit-integer-sign-change")
UBSAN_CHECK(InvalidShiftBase, "invalid-shift-base", "shift-base")
UBSAN_CHECK(InvalidShiftExponent, "invalid-shift-exponent", "shift-exponent")
UBSAN_CHECK(OutOfBoundsIndex, "out-of-bounds-index", "bounds")
diff --git a/libsanitizer/ubsan/ubsan_diag.cc b/libsanitizer/ubsan/ubsan_diag.cpp
index cdf15b7..c8f7960 100644
--- a/libsanitizer/ubsan/ubsan_diag.cc
+++ b/libsanitizer/ubsan/ubsan_diag.cpp
@@ -1,7 +1,8 @@
-//===-- ubsan_diag.cc -----------------------------------------------------===//
+//===-- ubsan_diag.cpp ----------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -25,13 +26,21 @@
using namespace __ubsan;
-void __ubsan::GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc,
- uptr bp, void *context, bool fast) {
+// UBSan is combined with runtimes that already provide this functionality
+// (e.g., ASan) as well as runtimes that lack it (e.g., scudo). Tried to use
+// weak linkage to resolve this issue which is not portable and breaks on
+// Windows.
+// TODO(yln): This is a temporary workaround. GetStackTrace functions will be
+// removed in the future.
+void ubsan_GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
+ uptr pc, uptr bp, void *context, bool fast) {
uptr top = 0;
uptr bottom = 0;
- if (fast)
+ if (StackTrace::WillUseFastUnwind(fast)) {
GetThreadStackTopAndBottom(false, &top, &bottom);
- stack->Unwind(max_depth, pc, bp, context, top, bottom, fast);
+ stack->Unwind(max_depth, pc, bp, nullptr, top, bottom, true);
+ } else
+ stack->Unwind(max_depth, pc, bp, context, 0, 0, false);
}
static void MaybePrintStackTrace(uptr pc, uptr bp) {
@@ -41,7 +50,7 @@ static void MaybePrintStackTrace(uptr pc, uptr bp) {
return;
BufferedStackTrace stack;
- GetStackTrace(&stack, kStackTraceMax, pc, bp, nullptr,
+ ubsan_GetStackTrace(&stack, kStackTraceMax, pc, bp, nullptr,
common_flags()->fast_unwind_on_fatal);
stack.Print();
}
diff --git a/libsanitizer/ubsan/ubsan_diag.h b/libsanitizer/ubsan/ubsan_diag.h
index 429a9ec..b444e97 100644
--- a/libsanitizer/ubsan/ubsan_diag.h
+++ b/libsanitizer/ubsan/ubsan_diag.h
@@ -1,7 +1,8 @@
//===-- ubsan_diag.h --------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -233,9 +234,6 @@ bool ignoreReport(SourceLocation SLoc, ReportOptions Opts, ErrorType ET);
GET_CALLER_PC_BP; \
ReportOptions Opts = {unrecoverable_handler, pc, bp}
-void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp,
- void *context, bool fast);
-
/// \brief Instantiate this class before printing diagnostics in the error
/// report. This class ensures that reports from different threads and from
/// different sanitizers won't be mixed.
diff --git a/libsanitizer/ubsan/ubsan_diag_standalone.cc b/libsanitizer/ubsan/ubsan_diag_standalone.cc
deleted file mode 100644
index ddc1be7..0000000
--- a/libsanitizer/ubsan/ubsan_diag_standalone.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-//===-- ubsan_diag_standalone.cc ------------------------------------------===//
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Diagnostic reporting for the standalone UBSan runtime.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ubsan_platform.h"
-#if CAN_SANITIZE_UB
-#include "ubsan_diag.h"
-
-using namespace __ubsan;
-
-extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_print_stack_trace() {
- uptr top = 0;
- uptr bottom = 0;
- bool request_fast_unwind = common_flags()->fast_unwind_on_fatal;
- if (request_fast_unwind)
- __sanitizer::GetThreadStackTopAndBottom(false, &top, &bottom);
-
- GET_CURRENT_PC_BP_SP;
- (void)sp;
- BufferedStackTrace stack;
- stack.Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom,
- request_fast_unwind);
- stack.Print();
-}
-} // extern "C"
-
-#endif // CAN_SANITIZE_UB
diff --git a/libsanitizer/ubsan/ubsan_diag_standalone.cpp b/libsanitizer/ubsan/ubsan_diag_standalone.cpp
new file mode 100644
index 0000000..300179a
--- /dev/null
+++ b/libsanitizer/ubsan/ubsan_diag_standalone.cpp
@@ -0,0 +1,40 @@
+//===-- ubsan_diag_standalone.cpp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Diagnostic reporting for the standalone UBSan runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ubsan_platform.h"
+#if CAN_SANITIZE_UB
+#include "ubsan_diag.h"
+
+using namespace __ubsan;
+
+void __sanitizer::BufferedStackTrace::UnwindImpl(
+ uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) {
+ uptr top = 0;
+ uptr bottom = 0;
+ if (StackTrace::WillUseFastUnwind(request_fast)) {
+ GetThreadStackTopAndBottom(false, &top, &bottom);
+ Unwind(max_depth, pc, bp, nullptr, top, bottom, true);
+ } else
+ Unwind(max_depth, pc, bp, context, 0, 0, false);
+}
+
+extern "C" {
+SANITIZER_INTERFACE_ATTRIBUTE
+void __sanitizer_print_stack_trace() {
+ GET_CURRENT_PC_BP;
+ BufferedStackTrace stack;
+ stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal);
+ stack.Print();
+}
+} // extern "C"
+
+#endif // CAN_SANITIZE_UB
diff --git a/libsanitizer/ubsan/ubsan_flags.cc b/libsanitizer/ubsan/ubsan_flags.cpp
index a7ecc75..80de2a6 100644
--- a/libsanitizer/ubsan/ubsan_flags.cc
+++ b/libsanitizer/ubsan/ubsan_flags.cpp
@@ -1,7 +1,8 @@
-//===-- ubsan_flags.cc ----------------------------------------------------===//
+//===-- ubsan_flags.cpp ---------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -68,7 +69,7 @@ void InitializeFlags() {
// Override from user-specified string.
parser.ParseString(MaybeCallUbsanDefaultOptions());
// Override from environment variable.
- parser.ParseString(GetFlag("UBSAN_OPTIONS"));
+ parser.ParseStringFromEnv("UBSAN_OPTIONS");
InitializeCommonFlags();
if (Verbosity()) ReportUnrecognizedFlags();
diff --git a/libsanitizer/ubsan/ubsan_flags.h b/libsanitizer/ubsan/ubsan_flags.h
index 2604b6b..daa0d7c 100644
--- a/libsanitizer/ubsan/ubsan_flags.h
+++ b/libsanitizer/ubsan/ubsan_flags.h
@@ -1,7 +1,8 @@
//===-- ubsan_flags.h -------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/ubsan/ubsan_flags.inc b/libsanitizer/ubsan/ubsan_flags.inc
index 438ea0b..a4d0e61 100644
--- a/libsanitizer/ubsan/ubsan_flags.inc
+++ b/libsanitizer/ubsan/ubsan_flags.inc
@@ -1,7 +1,8 @@
//===-- ubsan_flags.inc -----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -23,5 +24,5 @@ UBSAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
UBSAN_FLAG(bool, report_error_type, false,
"Print specific error type instead of 'undefined-behavior' in summary.")
UBSAN_FLAG(bool, silence_unsigned_overflow, false,
- "Do not print error reports for unsigned integer overflow. "
- "Used to provide fuzzing signal without blowing up logs.")
+ "Do not print non-fatal error reports for unsigned integer overflow. "
+ "Used to provide fuzzing signal without blowing up logs.")
diff --git a/libsanitizer/ubsan/ubsan_handlers.cc b/libsanitizer/ubsan/ubsan_handlers.cpp
index f67b9e3..6099e36 100644
--- a/libsanitizer/ubsan/ubsan_handlers.cc
+++ b/libsanitizer/ubsan/ubsan_handlers.cpp
@@ -1,7 +1,8 @@
-//===-- ubsan_handlers.cc -------------------------------------------------===//
+//===-- ubsan_handlers.cpp ------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -104,6 +105,62 @@ void __ubsan::__ubsan_handle_type_mismatch_v1_abort(TypeMismatchData *Data,
Die();
}
+static void handleAlignmentAssumptionImpl(AlignmentAssumptionData *Data,
+ ValueHandle Pointer,
+ ValueHandle Alignment,
+ ValueHandle Offset,
+ ReportOptions Opts) {
+ Location Loc = Data->Loc.acquire();
+ SourceLocation AssumptionLoc = Data->AssumptionLoc.acquire();
+
+ ErrorType ET = ErrorType::AlignmentAssumption;
+
+ if (ignoreReport(Loc.getSourceLocation(), Opts, ET))
+ return;
+
+ ScopedReport R(Opts, Loc, ET);
+
+ uptr RealPointer = Pointer - Offset;
+ uptr LSB = LeastSignificantSetBitIndex(RealPointer);
+ uptr ActualAlignment = uptr(1) << LSB;
+
+ uptr Mask = Alignment - 1;
+ uptr MisAlignmentOffset = RealPointer & Mask;
+
+ if (!Offset) {
+ Diag(Loc, DL_Error, ET,
+ "assumption of %0 byte alignment for pointer of type %1 failed")
+ << Alignment << Data->Type;
+ } else {
+ Diag(Loc, DL_Error, ET,
+ "assumption of %0 byte alignment (with offset of %1 byte) for pointer "
+ "of type %2 failed")
+ << Alignment << Offset << Data->Type;
+ }
+
+ if (!AssumptionLoc.isInvalid())
+ Diag(AssumptionLoc, DL_Note, ET, "alignment assumption was specified here");
+
+ Diag(RealPointer, DL_Note, ET,
+ "%0address is %1 aligned, misalignment offset is %2 bytes")
+ << (Offset ? "offset " : "") << ActualAlignment << MisAlignmentOffset;
+}
+
+void __ubsan::__ubsan_handle_alignment_assumption(AlignmentAssumptionData *Data,
+ ValueHandle Pointer,
+ ValueHandle Alignment,
+ ValueHandle Offset) {
+ GET_REPORT_OPTIONS(false);
+ handleAlignmentAssumptionImpl(Data, Pointer, Alignment, Offset, Opts);
+}
+void __ubsan::__ubsan_handle_alignment_assumption_abort(
+ AlignmentAssumptionData *Data, ValueHandle Pointer, ValueHandle Alignment,
+ ValueHandle Offset) {
+ GET_REPORT_OPTIONS(true);
+ handleAlignmentAssumptionImpl(Data, Pointer, Alignment, Offset, Opts);
+ Die();
+}
+
/// \brief Common diagnostic emission for various forms of integer overflow.
template <typename T>
static void handleIntegerOverflowImpl(OverflowData *Data, ValueHandle LHS,
@@ -117,7 +174,9 @@ static void handleIntegerOverflowImpl(OverflowData *Data, ValueHandle LHS,
if (ignoreReport(Loc, Opts, ET))
return;
- if (!IsSigned && flags()->silence_unsigned_overflow)
+ // If this is an unsigned overflow in non-fatal mode, potentially ignore it.
+ if (!IsSigned && !Opts.FromUnrecoverableHandler &&
+ flags()->silence_unsigned_overflow)
return;
ScopedReport R(Opts, Loc, ET);
@@ -479,6 +538,12 @@ static void handleImplicitConversion(ImplicitConversionData *Data,
case ICCK_SignedIntegerTruncation:
ET = ErrorType::ImplicitSignedIntegerTruncation;
break;
+ case ICCK_IntegerSignChange:
+ ET = ErrorType::ImplicitIntegerSignChange;
+ break;
+ case ICCK_SignedIntegerTruncationOrSignChange:
+ ET = ErrorType::ImplicitSignedIntegerTruncationOrSignChange;
+ break;
}
if (ignoreReport(Loc, Opts, ET))
@@ -533,42 +598,6 @@ void __ubsan::__ubsan_handle_invalid_builtin_abort(InvalidBuiltinData *Data) {
Die();
}
-static void handleFunctionTypeMismatch(FunctionTypeMismatchData *Data,
- ValueHandle Function,
- ReportOptions Opts) {
- SourceLocation CallLoc = Data->Loc.acquire();
- ErrorType ET = ErrorType::FunctionTypeMismatch;
-
- if (ignoreReport(CallLoc, Opts, ET))
- return;
-
- ScopedReport R(Opts, CallLoc, ET);
-
- SymbolizedStackHolder FLoc(getSymbolizedLocation(Function));
- const char *FName = FLoc.get()->info.function;
- if (!FName)
- FName = "(unknown)";
-
- Diag(CallLoc, DL_Error, ET,
- "call to function %0 through pointer to incorrect function type %1")
- << FName << Data->Type;
- Diag(FLoc, DL_Note, ET, "%0 defined here") << FName;
-}
-
-void
-__ubsan::__ubsan_handle_function_type_mismatch(FunctionTypeMismatchData *Data,
- ValueHandle Function) {
- GET_REPORT_OPTIONS(false);
- handleFunctionTypeMismatch(Data, Function, Opts);
-}
-
-void __ubsan::__ubsan_handle_function_type_mismatch_abort(
- FunctionTypeMismatchData *Data, ValueHandle Function) {
- GET_REPORT_OPTIONS(true);
- handleFunctionTypeMismatch(Data, Function, Opts);
- Die();
-}
-
static void handleNonNullReturn(NonNullReturnData *Data, SourceLocation *LocPtr,
ReportOptions Opts, bool IsAttr) {
if (!LocPtr)
diff --git a/libsanitizer/ubsan/ubsan_handlers.h b/libsanitizer/ubsan/ubsan_handlers.h
index 87e3c34..eba1cf9 100644
--- a/libsanitizer/ubsan/ubsan_handlers.h
+++ b/libsanitizer/ubsan/ubsan_handlers.h
@@ -1,7 +1,8 @@
//===-- ubsan_handlers.h ----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -37,6 +38,17 @@ struct TypeMismatchData {
/// type.
RECOVERABLE(type_mismatch_v1, TypeMismatchData *Data, ValueHandle Pointer)
+struct AlignmentAssumptionData {
+ SourceLocation Loc;
+ SourceLocation AssumptionLoc;
+ const TypeDescriptor &Type;
+};
+
+/// \brief Handle a runtime alignment assumption check failure,
+/// caused by a misaligned pointer.
+RECOVERABLE(alignment_assumption, AlignmentAssumptionData *Data,
+ ValueHandle Pointer, ValueHandle Alignment, ValueHandle Offset)
+
struct OverflowData {
SourceLocation Loc;
const TypeDescriptor &Type;
@@ -126,6 +138,8 @@ enum ImplicitConversionCheckKind : unsigned char {
ICCK_IntegerTruncation = 0, // Legacy, was only used by clang 7.
ICCK_UnsignedIntegerTruncation = 1,
ICCK_SignedIntegerTruncation = 2,
+ ICCK_IntegerSignChange = 3,
+ ICCK_SignedIntegerTruncationOrSignChange = 4,
};
struct ImplicitConversionData {
@@ -154,15 +168,6 @@ struct InvalidBuiltinData {
/// Handle a builtin called in an invalid way.
RECOVERABLE(invalid_builtin, InvalidBuiltinData *Data)
-struct FunctionTypeMismatchData {
- SourceLocation Loc;
- const TypeDescriptor &Type;
-};
-
-RECOVERABLE(function_type_mismatch,
- FunctionTypeMismatchData *Data,
- ValueHandle Val)
-
struct NonNullReturnData {
SourceLocation AttrLoc;
};
diff --git a/libsanitizer/ubsan/ubsan_handlers_cxx.cc b/libsanitizer/ubsan/ubsan_handlers_cxx.cpp
index 9126170..2a6d558 100644
--- a/libsanitizer/ubsan/ubsan_handlers_cxx.cc
+++ b/libsanitizer/ubsan/ubsan_handlers_cxx.cpp
@@ -1,7 +1,8 @@
-//===-- ubsan_handlers_cxx.cc ---------------------------------------------===//
+//===-- ubsan_handlers_cxx.cpp --------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -155,6 +156,50 @@ void __ubsan_handle_cfi_bad_type(CFICheckFailData *Data, ValueHandle Vtable,
Diag(Loc, DL_Note, ET, "check failed in %0, vtable located in %1")
<< SrcModule << DstModule;
}
+
+static bool handleFunctionTypeMismatch(FunctionTypeMismatchData *Data,
+ ValueHandle Function,
+ ValueHandle calleeRTTI,
+ ValueHandle fnRTTI, ReportOptions Opts) {
+ if (checkTypeInfoEquality(reinterpret_cast<void *>(calleeRTTI),
+ reinterpret_cast<void *>(fnRTTI)))
+ return false;
+
+ SourceLocation CallLoc = Data->Loc.acquire();
+ ErrorType ET = ErrorType::FunctionTypeMismatch;
+
+ if (ignoreReport(CallLoc, Opts, ET))
+ return true;
+
+ ScopedReport R(Opts, CallLoc, ET);
+
+ SymbolizedStackHolder FLoc(getSymbolizedLocation(Function));
+ const char *FName = FLoc.get()->info.function;
+ if (!FName)
+ FName = "(unknown)";
+
+ Diag(CallLoc, DL_Error, ET,
+ "call to function %0 through pointer to incorrect function type %1")
+ << FName << Data->Type;
+ Diag(FLoc, DL_Note, ET, "%0 defined here") << FName;
+ return true;
+}
+
+void __ubsan_handle_function_type_mismatch_v1(FunctionTypeMismatchData *Data,
+ ValueHandle Function,
+ ValueHandle calleeRTTI,
+ ValueHandle fnRTTI) {
+ GET_REPORT_OPTIONS(false);
+ handleFunctionTypeMismatch(Data, Function, calleeRTTI, fnRTTI, Opts);
+}
+
+void __ubsan_handle_function_type_mismatch_v1_abort(
+ FunctionTypeMismatchData *Data, ValueHandle Function,
+ ValueHandle calleeRTTI, ValueHandle fnRTTI) {
+ GET_REPORT_OPTIONS(true);
+ if (handleFunctionTypeMismatch(Data, Function, calleeRTTI, fnRTTI, Opts))
+ Die();
+}
} // namespace __ubsan
#endif // CAN_SANITIZE_UB
diff --git a/libsanitizer/ubsan/ubsan_handlers_cxx.h b/libsanitizer/ubsan/ubsan_handlers_cxx.h
index 3738235..f7b9fc5 100644
--- a/libsanitizer/ubsan/ubsan_handlers_cxx.h
+++ b/libsanitizer/ubsan/ubsan_handlers_cxx.h
@@ -1,7 +1,8 @@
//===-- ubsan_handlers_cxx.h ------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -32,6 +33,22 @@ void __ubsan_handle_dynamic_type_cache_miss(
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
void __ubsan_handle_dynamic_type_cache_miss_abort(
DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash);
+
+struct FunctionTypeMismatchData {
+ SourceLocation Loc;
+ const TypeDescriptor &Type;
+};
+
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE void
+__ubsan_handle_function_type_mismatch_v1(FunctionTypeMismatchData *Data,
+ ValueHandle Val,
+ ValueHandle calleeRTTI,
+ ValueHandle fnRTTI);
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE void
+__ubsan_handle_function_type_mismatch_v1_abort(FunctionTypeMismatchData *Data,
+ ValueHandle Val,
+ ValueHandle calleeRTTI,
+ ValueHandle fnRTTI);
}
#endif // UBSAN_HANDLERS_H
diff --git a/libsanitizer/ubsan/ubsan_init.cc b/libsanitizer/ubsan/ubsan_init.cpp
index 9ae17f5..1a3b7d3 100644
--- a/libsanitizer/ubsan/ubsan_init.cc
+++ b/libsanitizer/ubsan/ubsan_init.cpp
@@ -1,7 +1,8 @@
-//===-- ubsan_init.cc -----------------------------------------------------===//
+//===-- ubsan_init.cpp ----------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/ubsan/ubsan_init.h b/libsanitizer/ubsan/ubsan_init.h
index 73bd3f3..0510385 100644
--- a/libsanitizer/ubsan/ubsan_init.h
+++ b/libsanitizer/ubsan/ubsan_init.h
@@ -1,7 +1,8 @@
//===-- ubsan_init.h --------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/ubsan/ubsan_init_standalone.cc b/libsanitizer/ubsan/ubsan_init_standalone.cpp
index 67223be..91c3f57 100644
--- a/libsanitizer/ubsan/ubsan_init_standalone.cc
+++ b/libsanitizer/ubsan/ubsan_init_standalone.cpp
@@ -1,7 +1,8 @@
-//===-- ubsan_init_standalone.cc ------------------------------------------===//
+//===-- ubsan_init_standalone.cpp -----------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/ubsan/ubsan_init_standalone_preinit.cc b/libsanitizer/ubsan/ubsan_init_standalone_preinit.cpp
index fd26b49..fabbf91 100644
--- a/libsanitizer/ubsan/ubsan_init_standalone_preinit.cc
+++ b/libsanitizer/ubsan/ubsan_init_standalone_preinit.cpp
@@ -1,7 +1,8 @@
-//===-- ubsan_init_standalone_preinit.cc ---------------------------------===//
+//===-- ubsan_init_standalone_preinit.cpp --------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/ubsan/ubsan_interface.inc b/libsanitizer/ubsan/ubsan_interface.inc
index ef0842d..1e44bc2 100644
--- a/libsanitizer/ubsan/ubsan_interface.inc
+++ b/libsanitizer/ubsan/ubsan_interface.inc
@@ -1,13 +1,16 @@
//===-- ubsan_interface.inc -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// Ubsan interface list.
//===----------------------------------------------------------------------===//
INTERFACE_FUNCTION(__ubsan_handle_add_overflow)
INTERFACE_FUNCTION(__ubsan_handle_add_overflow_abort)
+INTERFACE_FUNCTION(__ubsan_handle_alignment_assumption)
+INTERFACE_FUNCTION(__ubsan_handle_alignment_assumption_abort)
INTERFACE_FUNCTION(__ubsan_handle_builtin_unreachable)
INTERFACE_FUNCTION(__ubsan_handle_cfi_bad_type)
INTERFACE_FUNCTION(__ubsan_handle_cfi_check_fail)
@@ -18,8 +21,8 @@ INTERFACE_FUNCTION(__ubsan_handle_dynamic_type_cache_miss)
INTERFACE_FUNCTION(__ubsan_handle_dynamic_type_cache_miss_abort)
INTERFACE_FUNCTION(__ubsan_handle_float_cast_overflow)
INTERFACE_FUNCTION(__ubsan_handle_float_cast_overflow_abort)
-INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch)
-INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_abort)
+INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_v1)
+INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_v1_abort)
INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion)
INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion_abort)
INTERFACE_FUNCTION(__ubsan_handle_invalid_builtin)
diff --git a/libsanitizer/ubsan/ubsan_monitor.cc b/libsanitizer/ubsan/ubsan_monitor.cpp
index 81180a6..d064e95 100644
--- a/libsanitizer/ubsan/ubsan_monitor.cc
+++ b/libsanitizer/ubsan/ubsan_monitor.cpp
@@ -1,7 +1,8 @@
-//===-- ubsan_monitor.cc ----------------------------------------*- C++ -*-===//
+//===-- ubsan_monitor.cpp ---------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/ubsan/ubsan_monitor.h b/libsanitizer/ubsan/ubsan_monitor.h
index 632bd25..3bfd7be 100644
--- a/libsanitizer/ubsan/ubsan_monitor.h
+++ b/libsanitizer/ubsan/ubsan_monitor.h
@@ -1,7 +1,8 @@
//===-- ubsan_monitor.h -----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/ubsan/ubsan_platform.h b/libsanitizer/ubsan/ubsan_platform.h
index 67c4e07..58aabbe 100644
--- a/libsanitizer/ubsan/ubsan_platform.h
+++ b/libsanitizer/ubsan/ubsan_platform.h
@@ -1,7 +1,8 @@
//===-- ubsan_platform.h ----------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/ubsan/ubsan_signals_standalone.cc b/libsanitizer/ubsan/ubsan_signals_standalone.cpp
index 5e77c60..627b3c4 100644
--- a/libsanitizer/ubsan/ubsan_signals_standalone.cc
+++ b/libsanitizer/ubsan/ubsan_signals_standalone.cpp
@@ -1,10 +1,8 @@
-//=-- ubsan_signals_standalone.cc
-//------------------------------------------------===//
+//=-- ubsan_signals_standalone.cpp ----------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -39,11 +37,15 @@ void InitializeDeadlySignals() {}
#define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name)
#include "sanitizer_common/sanitizer_signal_interceptors.inc"
+// TODO(yln): Temporary workaround. Will be removed.
+void ubsan_GetStackTrace(BufferedStackTrace *stack, uptr max_depth,
+ uptr pc, uptr bp, void *context, bool fast);
+
namespace __ubsan {
static void OnStackUnwind(const SignalContext &sig, const void *,
BufferedStackTrace *stack) {
- GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context,
+ ubsan_GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context,
common_flags()->fast_unwind_on_fatal);
}
diff --git a/libsanitizer/ubsan/ubsan_signals_standalone.h b/libsanitizer/ubsan/ubsan_signals_standalone.h
index b29c294..128eff2 100644
--- a/libsanitizer/ubsan/ubsan_signals_standalone.h
+++ b/libsanitizer/ubsan/ubsan_signals_standalone.h
@@ -1,10 +1,9 @@
//=-- ubsan_signals_standalone.h
//------------------------------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/ubsan/ubsan_type_hash.cc b/libsanitizer/ubsan/ubsan_type_hash.cpp
index 65160aa..8f4b9ae 100644
--- a/libsanitizer/ubsan/ubsan_type_hash.cc
+++ b/libsanitizer/ubsan/ubsan_type_hash.cpp
@@ -1,7 +1,8 @@
-//===-- ubsan_type_hash.cc ------------------------------------------------===//
+//===-- ubsan_type_hash.cpp -----------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -10,7 +11,7 @@
// permitted to use language features which require a C++ ABI library.
//
// Most of the implementation lives in an ABI-specific source file
-// (ubsan_type_hash_{itanium,win}.cc).
+// (ubsan_type_hash_{itanium,win}.cpp).
//
//===----------------------------------------------------------------------===//
diff --git a/libsanitizer/ubsan/ubsan_type_hash.h b/libsanitizer/ubsan/ubsan_type_hash.h
index 610fcb4..e42884b 100644
--- a/libsanitizer/ubsan/ubsan_type_hash.h
+++ b/libsanitizer/ubsan/ubsan_type_hash.h
@@ -1,7 +1,8 @@
//===-- ubsan_type_hash.h ---------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -63,6 +64,10 @@ const int VptrMaxOffsetToTop = 1<<20;
extern "C" SANITIZER_INTERFACE_ATTRIBUTE
HashValue __ubsan_vptr_type_cache[VptrTypeCacheSize];
+/// \brief Do whatever is required by the ABI to check for std::type_info
+/// equivalence beyond simple pointer comparison.
+bool checkTypeInfoEquality(const void *TypeInfo1, const void *TypeInfo2);
+
} // namespace __ubsan
#endif // UBSAN_TYPE_HASH_H
diff --git a/libsanitizer/ubsan/ubsan_type_hash_itanium.cc b/libsanitizer/ubsan/ubsan_type_hash_itanium.cpp
index bff7888..97846d4 100644
--- a/libsanitizer/ubsan/ubsan_type_hash_itanium.cc
+++ b/libsanitizer/ubsan/ubsan_type_hash_itanium.cpp
@@ -1,7 +1,8 @@
-//===-- ubsan_type_hash_itanium.cc ----------------------------------------===//
+//===-- ubsan_type_hash_itanium.cpp ---------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -116,9 +117,7 @@ static bool isDerivedFromAtOffset(const abi::__class_type_info *Derived,
const abi::__class_type_info *Base,
sptr Offset) {
if (Derived->__type_name == Base->__type_name ||
- (SANITIZER_NON_UNIQUE_TYPEINFO &&
- Derived->__type_name[0] != '*' &&
- !internal_strcmp(Derived->__type_name, Base->__type_name)))
+ __ubsan::checkTypeInfoEquality(Derived, Base))
return Offset == 0;
if (const abi::__si_class_type_info *SI =
@@ -257,4 +256,13 @@ __ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) {
ObjectType ? ObjectType->__type_name : "<unknown>");
}
+bool __ubsan::checkTypeInfoEquality(const void *TypeInfo1,
+ const void *TypeInfo2) {
+ auto TI1 = static_cast<const std::type_info *>(TypeInfo1);
+ auto TI2 = static_cast<const std::type_info *>(TypeInfo2);
+ return SANITIZER_NON_UNIQUE_TYPEINFO && TI1->__type_name[0] != '*' &&
+ TI2->__type_name[0] != '*' &&
+ !internal_strcmp(TI1->__type_name, TI2->__type_name);
+}
+
#endif // CAN_SANITIZE_UB && !SANITIZER_WINDOWS
diff --git a/libsanitizer/ubsan/ubsan_type_hash_win.cc b/libsanitizer/ubsan/ubsan_type_hash_win.cpp
index a2eb1a7..45dcb75 100644
--- a/libsanitizer/ubsan/ubsan_type_hash_win.cc
+++ b/libsanitizer/ubsan/ubsan_type_hash_win.cpp
@@ -1,7 +1,8 @@
-//===-- ubsan_type_hash_win.cc --------------------------------------------===//
+//===-- ubsan_type_hash_win.cpp -------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
@@ -76,4 +77,8 @@ __ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) {
"<unknown>");
}
+bool __ubsan::checkTypeInfoEquality(const void *, const void *) {
+ return false;
+}
+
#endif // CAN_SANITIZE_UB && SANITIZER_WINDOWS
diff --git a/libsanitizer/ubsan/ubsan_value.cc b/libsanitizer/ubsan/ubsan_value.cpp
index 3e158f9..60f0b5c 100644
--- a/libsanitizer/ubsan/ubsan_value.cc
+++ b/libsanitizer/ubsan/ubsan_value.cpp
@@ -1,7 +1,8 @@
-//===-- ubsan_value.cc ----------------------------------------------------===//
+//===-- ubsan_value.cpp ---------------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/ubsan/ubsan_value.h b/libsanitizer/ubsan/ubsan_value.h
index cca1ac8..a216e3a 100644
--- a/libsanitizer/ubsan/ubsan_value.h
+++ b/libsanitizer/ubsan/ubsan_value.h
@@ -1,7 +1,8 @@
//===-- ubsan_value.h -------------------------------------------*- C++ -*-===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/ubsan/ubsan_win_dll_thunk.cc b/libsanitizer/ubsan/ubsan_win_dll_thunk.cpp
index 1091ac0..5ac7fc3 100644
--- a/libsanitizer/ubsan/ubsan_win_dll_thunk.cc
+++ b/libsanitizer/ubsan/ubsan_win_dll_thunk.cpp
@@ -1,7 +1,8 @@
-//===-- ubsan_win_dll_thunk.cc --------------------------------------------===//
+//===-- ubsan_win_dll_thunk.cpp -------------------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/ubsan/ubsan_win_dynamic_runtime_thunk.cc b/libsanitizer/ubsan/ubsan_win_dynamic_runtime_thunk.cpp
index 6ab5ae3..00722b4 100644
--- a/libsanitizer/ubsan/ubsan_win_dynamic_runtime_thunk.cc
+++ b/libsanitizer/ubsan/ubsan_win_dynamic_runtime_thunk.cpp
@@ -1,7 +1,8 @@
-//===-- ubsan_win_dynamic_runtime_thunk.cc --------------------------------===//
+//===-- ubsan_win_dynamic_runtime_thunk.cpp -------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
diff --git a/libsanitizer/ubsan/ubsan_win_weak_interception.cc b/libsanitizer/ubsan/ubsan_win_weak_interception.cpp
index 9f0a8f1..01db0c0 100644
--- a/libsanitizer/ubsan/ubsan_win_weak_interception.cc
+++ b/libsanitizer/ubsan/ubsan_win_weak_interception.cpp
@@ -1,7 +1,8 @@
-//===-- ubsan_win_weak_interception.cc ------------------------------------===//
+//===-- ubsan_win_weak_interception.cpp -----------------------------------===//
//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// This module should be included in Ubsan when it is implemented as a shared
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 099314d..086966a 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,323 @@
+2019-08-16 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/abi/post/alpha-linux-gnu/baseline_symbols.txt: Update.
+
+2019-08-15 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/91456
+ * include/bits/std_function.h (__check_func_return_type): Remove.
+ (function::_Callable): Use std::__is_invocable_impl instead of
+ __check_func_return_type.
+ * include/std/type_traits (__is_invocable_impl): Add another defaulted
+ template parameter. Define a separate partial specialization for
+ INVOKE and INVOKE<void>. For INVOKE<R> replace is_convertible check
+ with a check that models delayed temporary materialization.
+ * testsuite/20_util/function/91456.cc: New test.
+ * testsuite/20_util/is_invocable/91456.cc: New test.
+
+2019-08-14 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/type_traits (__is_nullptr_t): Add deprecated attribute.
+
+2019-08-14 Edward Smith-Rowland <3dw4rd@verizon.net>
+
+ Implement C++20 p0879 - Constexpr for swap and swap related functions.
+ * include/std/version (__cpp_lib_constexpr_swap_algorithms): New macro.
+ * include/bits/algorithmfwd.h (__cpp_lib_constexpr_swap_algorithms):
+ New macro.
+ (iter_swap, make_heap, next_permutation, partial_sort_copy, pop_heap)
+ (prev_permutation, push_heap, reverse, rotate, sort_heap, swap)
+ (swap_ranges, nth_element, partial_sort, sort): Add constexpr.
+ * include/bits/move.h (swap): Add constexpr.
+ * include/bits/stl_algo.h (__move_median_to_first, __reverse, reverse)
+ (__gcd, __rotate, rotate, __partition, __heap_select)
+ (__partial_sort_copy, partial_sort_copy, __unguarded_partition)
+ (__unguarded_partition_pivot, __partial_sort, __introsort_loop, __sort)
+ (__introselect, __chunk_insertion_sort, next_permutation)
+ (prev_permutation, partition, partial_sort, nth_element, sort)
+ (__iter_swap::iter_swap, iter_swap, swap_ranges): Add constexpr.
+ * include/bits/stl_algobase.h (__iter_swap::iter_swap, iter_swap)
+ (swap_ranges): Add constexpr.
+ * include/bits/stl_heap.h (__push_heap, push_heap, __adjust_heap,
+ __pop_heap, pop_heap, __make_heap, make_heap, __sort_heap, sort_heap):
+ Add constexpr.
+ * include/std/type_traits (swap): Add constexpr.
+ * testsuite/25_algorithms/headers/algorithm/synopsis.cc: Add constexpr.
+ * testsuite/25_algorithms/iter_swap/constexpr.cc: New test.
+ * testsuite/25_algorithms/make_heap/constexpr.cc: New test.
+ * testsuite/25_algorithms/next_permutation/constexpr.cc: New test.
+ * testsuite/25_algorithms/nth_element/constexpr.cc: New test.
+ * testsuite/25_algorithms/partial_sort/constexpr.cc: New test.
+ * testsuite/25_algorithms/partial_sort_copy/constexpr.cc: New test.
+ * testsuite/25_algorithms/partition/constexpr.cc: New test.
+ * testsuite/25_algorithms/pop_heap/constexpr.cc: New test.
+ * testsuite/25_algorithms/prev_permutation/constexpr.cc: New test.
+ * testsuite/25_algorithms/push_heap/constexpr.cc: New test.
+ * testsuite/25_algorithms/reverse/constexpr.cc: New test.
+ * testsuite/25_algorithms/rotate/constexpr.cc: New test.
+ * testsuite/25_algorithms/sort/constexpr.cc: New test.
+ * testsuite/25_algorithms/sort_heap/constexpr.cc: New test.
+ * testsuite/25_algorithms/swap/constexpr.cc: New test.
+ * testsuite/25_algorithms/swap_ranges/constexpr.cc: New test.
+
+2019-08-12 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/90361
+ * src/c++17/string-inst.cc: Use _GLIBCXX_USE_CXX11_ABI=1 by default.
+
+ * include/std/tuple (__unpack_std_tuple): New variable template and
+ partial specializations.
+ (apply, make_from_tuple): Add noexcept-specifier.
+ * testsuite/20_util/tuple/apply/2.cc: New test.
+ * testsuite/20_util/tuple/make_from_tuple/2.cc: New test.
+
+2019-08-09 Corentin Gay <gay@adacore.com>
+
+ * testsuite/ext/random/beta_distribution/operators/serialize.cc,
+ testsuite/ext/random/hypergeometric_distribution/operators/serialize.cc,
+ testsuite/ext/random/normal_mv_distribution/operators/serialize.cc,
+ testsuite/ext/random/triangular_distribution/operators/serialize.cc,
+ testsuite/ext/random/von_mises_distribution/operators/serialize.cc:
+ Add call to `VERIFY`.
+
+2019-08-09 Alexandre Oliva <oliva@adacore.com>
+
+ * include/ext/random
+ (normal_mv_distribution::param_type::param_type): New private
+ ctor taking a decomposed varcov matrix, for use by...
+ (operator>>): ... this, befriended.
+ * include/ext/random.tcc (operator>>): Use it.
+ (normal_mv_distribution::param_type::_M_init_lower): Adjust
+ member function name in exception message.
+
+2019-08-08 Jonathan Wakely <jwakely@redhat.com>
+
+ P0325R4 to_array from LFTS with updates
+ * include/experimental/array (to_array): Qualify call to __to_array.
+ * include/std/array (__cpp_lib_to_array, to_array): Define for C++20.
+ * include/std/version (__cpp_lib_to_array): Likewise.
+ * testsuite/23_containers/array/creation/1.cc: New test.
+ * testsuite/23_containers/array/creation/2.cc: New test.
+ * testsuite/23_containers/array/creation/3_neg.cc: New test.
+ * testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc:
+ Use zero for dg-error line number.
+
+2019-08-06 Jonathan Wakely <jwakely@redhat.com>
+
+ P1651R0 bind_front should not unwrap reference_wrapper
+ * include/std/functional (bind_front): Don't unwrap reference_wrapper.
+ * include/std/version (__cpp_lib_bind_front): Update value.
+ * testsuite/20_util/function_objects/bind_front/1.cc: Fix test for
+ feature test macro.
+ * testsuite/20_util/function_objects/bind_front/2.cc: New test.
+
+ * include/std/numbers [!__STRICT_ANSI__ && _GLIBCXX_USE_FLOAT128]
+ (e_v, log2e_v, log10e_v, pi_v, inv_pi_v, inv_sqrtpi_v, ln2_v, ln10_v)
+ (sqrt2_v, sqrt3_v, inv_sqrt3, egamma_v, phi_v): Add explicit
+ specializations for __float128.
+ * testsuite/26_numerics/numbers/float128.cc: New test.
+
+2019-08-04 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/xml/manual/documentation_hacking.xml: doxygen.org is now
+ doxygen.nl.
+
+2019-08-01 Edward Smith-Rowland <3dw4rd@verizon.net>
+
+ Implement C++20 p0202 - Add Constexpr Modifiers to Functions
+ in <algorithm> and <utility> Headers.
+ Implement C++20 p1023 - constexpr comparison operators for std::array.
+ * include/bits/algorithmfwd.h (all_of, any_of, binary_search, copy,
+ copy_backward, copy_if, copy_n, equal_range, fill, find_end,
+ find_if_not, includes, is_heap, is_heap_until, is_partitioned,
+ is_permutation, is_sorted, is_sorted_until, iter_swap, lower_bound,
+ none_of, partition_copy, partition_point, remove, remove_if,
+ remove_copy, remove_copy_if, replace_copy, replace_copy_if,
+ reverse_copy, rotate_copy, uunique, upper_bound, adjacent_find, count,
+ count_if, equal, find, find_first_of, find_if, for_each, generate,
+ generate_n, lexicographical_compare, merge, mismatch, replace,
+ replace_if, search, search_n, set_difference, set_intersection,
+ set_symmetric_difference, set_union, transform, unique_copy):
+ Mark constexpr.
+ * include/bits/cpp_type_traits.h (__miter_base): Mark constexpr.
+ * include/bits/predefined_ops.h (_Iter_less_val::operator(),
+ _Val_less_iter::operator(), _Iter_equal_to_iter::operator(),
+ _Iter_equal_to_val::operator(), _Iter_equals_val::operator()):
+ Use const ref instead of ref arg;
+ (_Iter_less_val, __iter_less_val, _Val_less_iter, __val_less_iter,
+ __iter_equal_to_iter, __iter_equal_to_val, __iter_comp_val,
+ _Iter_comp_val, _Val_comp_iter, __val_comp_iter, __iter_equals_val,
+ _Iter_equals_iter, __iter_comp_iter, _Iter_pred, __pred_iter,
+ _Iter_comp_to_val, __iter_comp_val, _Iter_comp_to_iter,
+ __iter_comp_iter): Mark constexpr.
+ * include/bits/stl_algo.h (__find_if, __find_if_not, __find_if_not_n,
+ __search, __search_n_aux, __search_n, __find_end, find_end, all_of,
+ none_of, any_of, find_if_not, is_partitioned, partition_point,
+ __remove_copy_if, remove_copy, remove_copy_if, copy_if, __copy_n,
+ copy_n, partition_copy, __remove_if, remove, remove_if, __adjacent_find,
+ __unique, unique, __unique_copy, reverse_copy, rotate_copy,
+ __unguarded_linear_insert, __insertion_sort, __unguarded_insertion_sort,
+ __final_insertion_sort, lower_bound, __upper_bound, upper_bound,
+ __equal_range, equal_range, binary_search, __includes, includes,
+ __next_permutation, __prev_permutation, __replace_copy_if, replace_copy,
+ replace_copy_if, __count_if, is_sorted, __is_sorted_until,
+ is_sorted_until, __is_permutation, is_permutation, for_each, find,
+ find_if, find_first_of, adjacent_find, count, count_if, search,
+ search_n, transform, replace, replace_if, generate, generate_n,
+ unique_copy, __merge, merge, __set_union, set_union, __set_intersection,
+ set_intersection, __set_difference, set_difference,
+ __set_symmetric_difference, set_symmetric_difference): Mark constexpr.
+ * include/bits/stl_algobase.h (__memmove, __memcmp): New maybe constexpr
+ wrappers around __builtin_memmove and __builtin_memcmp
+ respectively;
+ (__niter_base, __niter_wrap, __copy_m, __copy_move_a, __copy_move_a2,
+ copy, move, __copy_move_b, __copy_move_backward_a,
+ __copy_move_backward_a2, copy_backward, move_backward, __fill_a, fill,
+ __fill_n_a, fill_n, equal, __lc_rai::__newlast1, __lc_rai::__cnd2,
+ __lexicographical_compare_impl, __lexicographical_compare,
+ __lexicographical_compare<true>::__lc, __lexicographical_compare_aux,
+ __lower_bound, lower_bound, equal, __equal4, lexicographical_compare,
+ __mismatch, mismatch, __is_heap_until, __is_heap, is_heap_until,
+ is_heap): Mark constexpr.
+ * include/bits/stl_heap.h (__is_heap_until, __is_heap, is_heap_until,
+ is_heap): Mark constexpr.
+ * include/bits/stl_iterator.h (__niter_base, __miter_base): Mark constexpr.
+ * include/std/array: Make comparison ops constexpr.
+ * include/std/utility: Make exchange constexpr.
+ * include/std/version (__cpp_lib_constexpr_algorithms): New macro.
+ * testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust.
+ * testsuite/23_containers/array/tuple_interface/
+ tuple_element_neg.cc: Adjust.
+ * testsuite/20_util/exchange/constexpr.cc: New.
+ * testsuite/23_containers/array/comparison_operators/constexpr.cc: New.
+ * testsuite/25_algorithms/constexpr_macro.cc: New.
+ * testsuite/25_algorithms/adjacent_find/constexpr.cc: New.
+ * testsuite/25_algorithms/all_of/constexpr.cc: New.
+ * testsuite/25_algorithms/any_of/constexpr.cc: New.
+ * testsuite/25_algorithms/binary_search/constexpr.cc: New.
+ * testsuite/25_algorithms/copy/constexpr.cc: New.
+ * testsuite/25_algorithms/copy_backward/constexpr.cc: New.
+ * testsuite/25_algorithms/copy_if/constexpr.cc: New.
+ * testsuite/25_algorithms/copy_n/constexpr.cc: New.
+ * testsuite/25_algorithms/count/constexpr.cc: New.
+ * testsuite/25_algorithms/count_if/constexpr.cc: New.
+ * testsuite/25_algorithms/equal/constexpr.cc: New.
+ * testsuite/25_algorithms/equal_range/constexpr.cc: New.
+ * testsuite/25_algorithms/fill/constexpr.cc: New.
+ * testsuite/25_algorithms/fill_n/constexpr.cc: New.
+ * testsuite/25_algorithms/find/constexpr.cc: New.
+ * testsuite/25_algorithms/find_end/constexpr.cc: New.
+ * testsuite/25_algorithms/find_first_of/constexpr.cc: New.
+ * testsuite/25_algorithms/find_if/constexpr.cc: New.
+ * testsuite/25_algorithms/find_if_not/constexpr.cc: New.
+ * testsuite/25_algorithms/for_each/constexpr.cc: New.
+ * testsuite/25_algorithms/generate/constexpr.cc: New.
+ * testsuite/25_algorithms/generate_n/constexpr.cc: New.
+ * testsuite/25_algorithms/is_heap/constexpr.cc: New.
+ * testsuite/25_algorithms/is_heap_until/constexpr.cc: New.
+ * testsuite/25_algorithms/is_partitioned/constexpr.cc: New.
+ * testsuite/25_algorithms/is_permutation/constexpr.cc: New.
+ * testsuite/25_algorithms/is_sorted/constexpr.cc: New.
+ * testsuite/25_algorithms/is_sorted_until/constexpr.cc: New.
+ * testsuite/25_algorithms/lexicographical_compare/constexpr.cc: New.
+ * testsuite/25_algorithms/lower_bound/constexpr.cc: New.
+ * testsuite/25_algorithms/merge/constexpr.cc: New.
+ * testsuite/25_algorithms/mismatch/constexpr.cc: New.
+ * testsuite/25_algorithms/none_of/constexpr.cc: New.
+ * testsuite/25_algorithms/partition_copy/constexpr.cc: New.
+ * testsuite/25_algorithms/partition_point/constexpr.cc: New.
+ * testsuite/25_algorithms/remove/constexpr.cc: New.
+ * testsuite/25_algorithms/remove_copy/constexpr.cc: New.
+ * testsuite/25_algorithms/remove_copy_if/constexpr.cc: New.
+ * testsuite/25_algorithms/remove_if/constexpr.cc: New.
+ * testsuite/25_algorithms/replace_copy/constexpr.cc: New.
+ * testsuite/25_algorithms/replace_copy_if/constexpr.cc: New.
+ * testsuite/25_algorithms/replace_if/constexpr.cc: New.
+ * testsuite/25_algorithms/reverse_copy/constexpr.cc: New.
+ * testsuite/25_algorithms/rotate_copy/constexpr.cc: New.
+ * testsuite/25_algorithms/search/constexpr.cc: New.
+ * testsuite/25_algorithms/search_n/constexpr.cc: New.
+ * testsuite/25_algorithms/set_difference/constexpr.cc: New.
+ * testsuite/25_algorithms/set_intersection/constexpr.cc: New.
+ * testsuite/25_algorithms/set_symmetric_difference/constexpr.cc: New.
+ * testsuite/25_algorithms/set_union/constexpr.cc: New.
+ * testsuite/25_algorithms/transform/constexpr.cc: New.
+ * testsuite/25_algorithms/unique/constexpr.cc: New.
+ * testsuite/25_algorithms/unique_copy/constexpr.cc: New.
+ * testsuite/25_algorithms/upper_bound/constexpr.cc: New.
+
+2019-07-31 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/memory (make_obj_using_allocator): Qualify call to
+ uses_allocator_construction_args.
+
+ P0631R4 Math Constants
+ * include/Makefile.am: Add new header.
+ * include/Makefile.in: Regenerate.
+ * include/precompiled/stdc++.h: Include new header.
+ * include/std/numbers: New header.
+ * include/std/version (__cpp_lib_math_constants): Define.
+ * testsuite/26_numerics/numbers/1.cc: New test.
+ * testsuite/26_numerics/numbers/2.cc: New test.
+ * testsuite/26_numerics/numbers/3.cc: New test.
+ * testsuite/26_numerics/numbers/nonfloat_neg.cc: New test.
+
+ * include/std/bit: Add Doxygen comments.
+
+ PR libstdc++/91308
+ * include/bits/unique_ptr.h (unique_ptr::__safe_conversion_up): Remove
+ constraints on deleter that should only apply to the constructor.
+ (unique_ptr<T[], D>::__safe_conversion_up): Likewise.
+ (unique_ptr<T[], D>::unique_ptr(unique_ptr<U, D>&&)): Restore
+ constraints on deleter here.
+ * testsuite/20_util/unique_ptr/assign/91308.cc: New test.
+
+2019-07-29 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/51333
+ * libsupc++/cxxabi.h (__gnu_cxx::recursive_init_error): Do not define
+ constructor inline.
+ * libsupc++/guard_error.cc (__gnu_cxx::recursive_init_error): Define
+ constructor.
+ * testsuite/18_support/51333.cc: New test.
+
+2019-07-28 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * doc/xml/manual/documentation_hacking.xml: Fix broken reference
+ to the Doxygen manual. Avoid a "here" link on the way.
+ Fix another broken link to Doxygen docblocks.
+
+2019-07-26 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/bit (__cpp_lib_endian): Define.
+ * include/std/version (__cpp_lib_endian): Define.
+ * testsuite/26_numerics/endian/2.cc: New.
+ * testsuite/26_numerics/endian/3.cc: New.
+ * testsuite/26_numerics/endian/4.cc: New.
+
+2019-07-26 François Dumont <fdumont@gcc.gnu.org>
+
+ * testsuite/util/testsuite_iterators.h
+ (bidirectional_iterator_wrapper): Fix type comment.
+ (random_access_iterator_wrapper): Likewise.
+
+2019-07-25 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/std/bit (endian): Move definition here as per P1612R1.
+ * include/std/type_traits (endian): Remove definition from here.
+ * testsuite/20_util/endian/1.cc: Rename to ...
+ * testsuite/26_numerics/endian/1.cc: ... here. Adjust header.
+
+2019-07-25 Martin Liska <mliska@suse.cz>
+ Dominik Infuhr <dominik.infuehr@theobroma-systems.com>
+
+ PR c++/23383
+ * testsuite/ext/bitmap_allocator/check_delete.cc: Add
+ -fno-allocation-dce.
+ * testsuite/ext/bitmap_allocator/check_new.cc: Likewise.
+ * testsuite/ext/new_allocator/check_delete.cc: Likewise.
+ * testsuite/ext/new_allocator/check_new.cc: Likewise.
+
2019-07-22 Jonathan Wakely <jwakely@redhat.com>
* testsuite/26_numerics/bit/bitops.count/*: Rename to ...
diff --git a/libstdc++-v3/config/abi/post/alpha-linux-gnu/baseline_symbols.txt b/libstdc++-v3/config/abi/post/alpha-linux-gnu/baseline_symbols.txt
index 9d07051..65ee06d 100644
--- a/libstdc++-v3/config/abi/post/alpha-linux-gnu/baseline_symbols.txt
+++ b/libstdc++-v3/config/abi/post/alpha-linux-gnu/baseline_symbols.txt
@@ -112,6 +112,7 @@ FUNC:_ZN11__gnu_debug19_Safe_sequence_base13_M_detach_allEv@@GLIBCXX_3.4
FUNC:_ZN11__gnu_debug19_Safe_sequence_base18_M_detach_singularEv@@GLIBCXX_3.4
FUNC:_ZN11__gnu_debug19_Safe_sequence_base22_M_revalidate_singularEv@@GLIBCXX_3.4
FUNC:_ZN11__gnu_debug19_Safe_sequence_base7_M_swapERS0_@@GLIBCXX_3.4
+FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base16_M_attach_singleEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4.26
FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base9_M_attachEPNS_19_Safe_sequence_baseEb@@GLIBCXX_3.4.17
FUNC:_ZN11__gnu_debug25_Safe_local_iterator_base9_M_detachEv@@GLIBCXX_3.4.17
FUNC:_ZN11__gnu_debug30_Safe_unordered_container_base13_M_detach_allEv@@GLIBCXX_3.4.17
@@ -261,6 +262,7 @@ FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8_M_limitEmm@@GLIBCXX_3.4
FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8capacityEv@@GLIBCXX_3.4
FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE8max_sizeEv@@GLIBCXX_3.4
FUNC:_ZNKSbIwSt11char_traitsIwESaIwEE9_M_ibeginEv@@GLIBCXX_3.4
+FUNC:_ZNKSbIwSt11char_traitsIwESaIwEEcvSt17basic_string_viewIwS0_EEv@@GLIBCXX_3.4.26
FUNC:_ZNKSbIwSt11char_traitsIwESaIwEEixEm@@GLIBCXX_3.4
FUNC:_ZNKSi6gcountEv@@GLIBCXX_3.4
FUNC:_ZNKSi6sentrycvbEv@@GLIBCXX_3.4
@@ -328,9 +330,66 @@ FUNC:_ZNKSs8_M_limitEmm@@GLIBCXX_3.4
FUNC:_ZNKSs8capacityEv@@GLIBCXX_3.4
FUNC:_ZNKSs8max_sizeEv@@GLIBCXX_3.4
FUNC:_ZNKSs9_M_ibeginEv@@GLIBCXX_3.4
+FUNC:_ZNKSscvSt17basic_string_viewIcSt11char_traitsIcEEEv@@GLIBCXX_3.4.26
FUNC:_ZNKSsixEm@@GLIBCXX_3.4
FUNC:_ZNKSt10bad_typeid4whatEv@@GLIBCXX_3.4.9
FUNC:_ZNKSt10error_code23default_error_conditionEv@@GLIBCXX_3.4.11
+FUNC:_ZNKSt10filesystem16filesystem_error4whatEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem16filesystem_error5path1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem16filesystem_error5path2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem18directory_iteratordeEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem28recursive_directory_iterator17recursion_pendingEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem28recursive_directory_iterator5depthEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem28recursive_directory_iterator7optionsEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem28recursive_directory_iteratordeEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path11parent_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path12has_filenameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path13has_root_nameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path13has_root_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path13relative_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path14root_directoryEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path15has_parent_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path16lexically_normalEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path17_M_find_extensionEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path17has_relative_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path18has_root_directoryEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path18lexically_relativeERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path19lexically_proximateERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path5_List13_Impl_deleterclEPNS1_5_ImplE@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path5_List3endEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path5_List5beginEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path7compareERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path7compareESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path9root_nameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem4path9root_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error4whatEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error5path1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1116filesystem_error5path2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1118directory_iteratordeEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator17recursion_pendingEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator5depthEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iterator7optionsEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx1128recursive_directory_iteratordeEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path11parent_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path12has_filenameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path13has_root_nameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path13has_root_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path13relative_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path14root_directoryEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path15has_parent_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path16lexically_normalEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path17_M_find_extensionEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path17has_relative_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path18has_root_directoryEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path18lexically_relativeERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path19lexically_proximateERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path5_List13_Impl_deleterclEPNS2_5_ImplE@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path5_List3endEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path5_List5beginEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path7compareERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path7compareESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path9root_nameEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt10filesystem7__cxx114path9root_pathEv@@GLIBCXX_3.4.26
FUNC:_ZNKSt10istrstream5rdbufEv@@GLIBCXX_3.4
FUNC:_ZNKSt10lock_error4whatEv@@GLIBCXX_3.4.11
FUNC:_ZNKSt10moneypunctIcLb0EE10neg_formatEv@@GLIBCXX_3.4
@@ -876,6 +935,7 @@ FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_checkEmPKc@@GLIBC
FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8_M_limitEmm@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8capacityEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE8max_sizeEv@@GLIBCXX_3.4.21
+FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEcvSt17basic_string_viewIcS2_EEv@@GLIBCXX_3.4.26
FUNC:_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEixEm@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_M_disjunctEPKw@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE11_M_is_localEv@@GLIBCXX_3.4.21
@@ -936,6 +996,7 @@ FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8_M_checkEmPKc@@GLIBC
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8_M_limitEmm@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8capacityEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE8max_sizeEv@@GLIBCXX_3.4.21
+FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEcvSt17basic_string_viewIwS2_EEv@@GLIBCXX_3.4.26
FUNC:_ZNKSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEixEm@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEE3strEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEE3strEv@@GLIBCXX_3.4.21
@@ -1067,6 +1128,13 @@ FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_
FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE6do_putES4_bRSt8ios_basewg@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb0EEES4_S4_RSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21
FUNC:_ZNKSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE9_M_insertILb1EEES4_S4_RSt8ios_basewRKNS_12basic_stringIwS3_SaIwEEE@@GLIBCXX_3.4.21
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE10do_unshiftERS0_PDuS3_RS3_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE5do_inERS0_PKDuS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE6do_outERS0_PKDiS4_RS4_PDuS6_RS6_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDiDu11__mbstate_tE9do_lengthERS0_PKDuS4_m@@GLIBCXX_3.4.26
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE10do_unshiftERS0_PcS3_RS3_@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.21
@@ -1074,6 +1142,13 @@ FUNC:_ZNKSt7codecvtIDic11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE5do_inERS0_PKcS4_RS4_PDiS6_RS6_@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE6do_outERS0_PKDiS4_RS4_PcS6_RS6_@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDic11__mbstate_tE9do_lengthERS0_PKcS4_m@@GLIBCXX_3.4.21
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE10do_unshiftERS0_PDuS3_RS3_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE16do_always_noconvEv@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE5do_inERS0_PKDuS4_RS4_PDsS6_RS6_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE6do_outERS0_PKDsS4_RS4_PDuS6_RS6_@@GLIBCXX_3.4.26
+FUNC:_ZNKSt7codecvtIDsDu11__mbstate_tE9do_lengthERS0_PKDuS4_m@@GLIBCXX_3.4.26
FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE10do_unshiftERS0_PcS3_RS3_@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE11do_encodingEv@@GLIBCXX_3.4.21
FUNC:_ZNKSt7codecvtIDsc11__mbstate_tE13do_max_lengthEv@@GLIBCXX_3.4.21
@@ -1276,6 +1351,7 @@ FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE16do_get_mont
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKc@@GLIBCXX_3.4
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE24_M_extract_wday_or_monthES3_S3_RiPPKcmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.14
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKcSC_@@GLIBCXX_3.4.21
+FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.26
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4
FUNC:_ZNKSt8time_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE8get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4
@@ -1294,6 +1370,7 @@ FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE16do_get_mont
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE21_M_extract_via_formatES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKw@@GLIBCXX_3.4
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE24_M_extract_wday_or_monthES3_S3_RiPPKwmRSt8ios_baseRSt12_Ios_Iostate@@GLIBCXX_3.4.14
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPKwSC_@@GLIBCXX_3.4.21
+FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.26
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc@@GLIBCXX_3.4.21
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_dateES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4
FUNC:_ZNKSt8time_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE8get_timeES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tm@@GLIBCXX_3.4
@@ -1386,6 +1463,8 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIN9__gnu_cxx17__normal_iterato
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIPKwEEPwT_S7_RKS1_St20forward_iterator_tag@@GLIBCXX_3.4.14
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_constructIPwEES4_T_S5_RKS1_St20forward_iterator_tag@@GLIBCXX_3.4.14
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12_S_empty_repEv@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12__sv_wrapperC1ESt17basic_string_viewIwS0_E@@GLIBCXX_3.4.26
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEE12__sv_wrapperC2ESt17basic_string_viewIwS0_E@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS2_EES8_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIS3_S2_EES6_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwPKwS5_@@GLIBCXX_3.4
@@ -1393,6 +1472,7 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS3_S3_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE13shrink_to_fitEv@@GLIBCXX_3.4.14
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE14_M_replace_auxEmmmw@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE15_M_replace_safeEmmPKwm@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEE17_S_to_string_viewESt17basic_string_viewIwS0_E@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE18_S_construct_aux_2EmwRKS1_@@GLIBCXX_3.4.14
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE2atEm@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4
@@ -1409,6 +1489,7 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep7_M_grabERKS1_S5_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep8_M_cloneERKS1_m@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep9_S_createEmmRKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.15
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4dataEv@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE4swapERS2_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4
@@ -1467,11 +1548,14 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwmw@@GLIBCXX_3.4.5
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_assignEPwmw@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9_M_mutateEmmm@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEE9push_backEw@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ENS2_12__sv_wrapperERKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EOS2_@@GLIBCXX_3.4.14
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EOS2_RKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EPKwRKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1EPKwmRKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_RKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_mRKS1_@@GLIBCXX_3.4.23
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_mm@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1ERKS2_mmRKS1_@@GLIBCXX_3.4
@@ -1481,11 +1565,14 @@ FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IN9__gnu_cxx17__normal_iteratorIPwS2_EEEET_S8_RKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IPKwEET_S6_RKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC1IPwEET_S5_RKS1_@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ENS2_12__sv_wrapperERKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EOS2_@@GLIBCXX_3.4.15
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EOS2_RKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EPKwRKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2EPKwmRKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS1_@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_@@GLIBCXX_3.4
+FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_RKS1_@@GLIBCXX_3.4.26
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_mRKS1_@@GLIBCXX_3.4.23
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_mm@@GLIBCXX_3.4
FUNC:_ZNSbIwSt11char_traitsIwESaIwEEC2ERKS2_mmRKS1_@@GLIBCXX_3.4
@@ -1616,6 +1703,7 @@ FUNC:_ZNSoD0Ev@@GLIBCXX_3.4
FUNC:_ZNSoD1Ev@@GLIBCXX_3.4
FUNC:_ZNSoD2Ev@@GLIBCXX_3.4
FUNC:_ZNSoaSEOSo@@GLIBCXX_3.4.21
+FUNC:_ZNSolsEDn@@GLIBCXX_3.4.26
FUNC:_ZNSolsEPFRSoS_E@@GLIBCXX_3.4
FUNC:_ZNSolsEPFRSt8ios_baseS0_E@@GLIBCXX_3.4
FUNC:_ZNSolsEPFRSt9basic_iosIcSt11char_traitsIcEES3_E@@GLIBCXX_3.4
@@ -1643,6 +1731,8 @@ FUNC:_ZNSs12_S_constructIN9__gnu_cxx17__normal_iteratorIPcSsEEEES2_T_S4_RKSaIcES
FUNC:_ZNSs12_S_constructIPKcEEPcT_S3_RKSaIcESt20forward_iterator_tag@@GLIBCXX_3.4.14
FUNC:_ZNSs12_S_constructIPcEES0_T_S1_RKSaIcESt20forward_iterator_tag@@GLIBCXX_3.4.14
FUNC:_ZNSs12_S_empty_repEv@@GLIBCXX_3.4
+FUNC:_ZNSs12__sv_wrapperC1ESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNSs12__sv_wrapperC2ESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
FUNC:_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcSsEES4_@@GLIBCXX_3.4
FUNC:_ZNSs13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIS_SsEES2_@@GLIBCXX_3.4
FUNC:_ZNSs13_S_copy_charsEPcPKcS1_@@GLIBCXX_3.4
@@ -1650,6 +1740,7 @@ FUNC:_ZNSs13_S_copy_charsEPcS_S_@@GLIBCXX_3.4
FUNC:_ZNSs13shrink_to_fitEv@@GLIBCXX_3.4.14
FUNC:_ZNSs14_M_replace_auxEmmmc@@GLIBCXX_3.4
FUNC:_ZNSs15_M_replace_safeEmmPKcm@@GLIBCXX_3.4
+FUNC:_ZNSs17_S_to_string_viewESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
FUNC:_ZNSs18_S_construct_aux_2EmcRKSaIcE@@GLIBCXX_3.4.14
FUNC:_ZNSs2atEm@@GLIBCXX_3.4
FUNC:_ZNSs3endEv@@GLIBCXX_3.4
@@ -1666,6 +1757,7 @@ FUNC:_ZNSs4_Rep7_M_grabERKSaIcES2_@@GLIBCXX_3.4
FUNC:_ZNSs4_Rep8_M_cloneERKSaIcEm@@GLIBCXX_3.4
FUNC:_ZNSs4_Rep9_S_createEmmRKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSs4backEv@@GLIBCXX_3.4.15
+FUNC:_ZNSs4dataEv@@GLIBCXX_3.4.26
FUNC:_ZNSs4rendEv@@GLIBCXX_3.4
FUNC:_ZNSs4swapERSs@@GLIBCXX_3.4
FUNC:_ZNSs5beginEv@@GLIBCXX_3.4
@@ -1724,11 +1816,14 @@ FUNC:_ZNSs9_M_assignEPcmc@@GLIBCXX_3.4.5
FUNC:_ZNSs9_M_assignEPcmc@GLIBCXX_3.4
FUNC:_ZNSs9_M_mutateEmmm@@GLIBCXX_3.4
FUNC:_ZNSs9push_backEc@@GLIBCXX_3.4
+FUNC:_ZNSsC1ENSs12__sv_wrapperERKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC1EOSs@@GLIBCXX_3.4.14
+FUNC:_ZNSsC1EOSsRKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC1EPKcRKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC1EPKcmRKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC1ERKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC1ERKSs@@GLIBCXX_3.4
+FUNC:_ZNSsC1ERKSsRKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC1ERKSsmRKSaIcE@@GLIBCXX_3.4.23
FUNC:_ZNSsC1ERKSsmm@@GLIBCXX_3.4
FUNC:_ZNSsC1ERKSsmmRKSaIcE@@GLIBCXX_3.4
@@ -1738,11 +1833,14 @@ FUNC:_ZNSsC1Ev@@GLIBCXX_3.4
FUNC:_ZNSsC1IN9__gnu_cxx17__normal_iteratorIPcSsEEEET_S4_RKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC1IPKcEET_S2_RKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC1IPcEET_S1_RKSaIcE@@GLIBCXX_3.4
+FUNC:_ZNSsC2ENSs12__sv_wrapperERKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC2EOSs@@GLIBCXX_3.4.15
+FUNC:_ZNSsC2EOSsRKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC2EPKcRKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC2EPKcmRKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC2ERKSaIcE@@GLIBCXX_3.4
FUNC:_ZNSsC2ERKSs@@GLIBCXX_3.4
+FUNC:_ZNSsC2ERKSsRKSaIcE@@GLIBCXX_3.4.26
FUNC:_ZNSsC2ERKSsmRKSaIcE@@GLIBCXX_3.4.23
FUNC:_ZNSsC2ERKSsmm@@GLIBCXX_3.4
FUNC:_ZNSsC2ERKSsmmRKSaIcE@@GLIBCXX_3.4
@@ -1774,6 +1872,208 @@ FUNC:_ZNSt10__num_base15_S_format_floatERKSt8ios_basePcc@@GLIBCXX_3.4
FUNC:_ZNSt10bad_typeidD0Ev@@GLIBCXX_3.4
FUNC:_ZNSt10bad_typeidD1Ev@@GLIBCXX_3.4
FUNC:_ZNSt10bad_typeidD2Ev@@GLIBCXX_3.4
+FUNC:_ZNSt10filesystem10equivalentERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10equivalentERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10equivalentERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10equivalentERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10hash_valueERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10remove_allERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10remove_allERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10remove_allERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem10remove_allERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11permissionsERKNS_4pathENS_5permsENS_12perm_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11permissionsERKNS_4pathENS_5permsENS_12perm_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11permissionsERKNS_7__cxx114pathENS_5permsENS_12perm_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11permissionsERKNS_7__cxx114pathENS_5permsENS_12perm_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11resize_fileERKNS_4pathEm@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11resize_fileERKNS_4pathEmRSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11resize_fileERKNS_7__cxx114pathEm@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem11resize_fileERKNS_7__cxx114pathEmRSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12copy_symlinkERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12copy_symlinkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12copy_symlinkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12copy_symlinkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathB5cxx11ERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathB5cxx11Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12current_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12read_symlinkERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12read_symlinkERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12read_symlinkERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem12read_symlinkERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14create_symlinkERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14create_symlinkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14create_symlinkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14create_symlinkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14symlink_statusERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14symlink_statusERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14symlink_statusERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem14symlink_statusERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15hard_link_countERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15hard_link_countERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15hard_link_countERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15hard_link_countERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathENSt6chrono10time_pointINS_12__file_clockENS3_8durationIlSt5ratioILl1ELl1000000000EEEEEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathENSt6chrono10time_pointINS_12__file_clockENS3_8durationIlSt5ratioILl1ELl1000000000EEEEEERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathENSt6chrono10time_pointINS_12__file_clockENS4_8durationIlSt5ratioILl1ELl1000000000EEEEEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathENSt6chrono10time_pointINS_12__file_clockENS4_8durationIlSt5ratioILl1ELl1000000000EEEEEERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem15last_write_timeERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_directoryERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_hard_linkERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_hard_linkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_hard_linkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16create_hard_linkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsRKNS_4pathES5_St10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsRKNS_4pathESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC1ERKSsSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsRKNS_4pathES5_St10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsRKNS_4pathESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorC2ERKSsSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorD0Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16filesystem_errorD2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem16weakly_canonicalERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18create_directoriesERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18create_directoriesERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18create_directoriesERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18create_directoriesERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18directory_iteratorC1ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18directory_iteratorC2ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem18directory_iteratorppEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem19temp_directory_pathB5cxx11ERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem19temp_directory_pathB5cxx11Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem19temp_directory_pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem19temp_directory_pathEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem24create_directory_symlinkERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iterator25disable_recursion_pendingEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iterator3popERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iterator3popEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratorC1ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratorC2ERKNS_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratorD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratorD2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratoraSEOS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem28recursive_directory_iteratoraSERKS0_@@GLIBCXX_3.4.27
+FUNC:_ZNSt10filesystem28recursive_directory_iteratorppEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4copyERKNS_4pathES2_NS_12copy_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4copyERKNS_4pathES2_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4copyERKNS_7__cxx114pathES3_NS_12copy_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4copyERKNS_7__cxx114pathES3_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path14_M_split_cmptsEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path14_S_convert_locEPKcS2_RKSt6locale@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path15remove_filenameEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path16replace_filenameERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path17replace_extensionERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path5_ListC1ERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path5_ListC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path9_M_appendESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4path9_M_concatESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4pathaSERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4pathdVERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem4pathpLERKS0_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem5spaceERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem5spaceERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem5spaceERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem5spaceERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6removeERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6removeERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6removeERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6removeERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6renameERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6renameERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6renameERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6renameERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6statusERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6statusERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6statusERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem6statusERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1110hash_valueERKNS0_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESC_St10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESC_St10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_4pathESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD0Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1116filesystem_errorD2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1118directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorC1ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorC2ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1118directory_iteratorppEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator25disable_recursion_pendingEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator3popERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator3popEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iterator9incrementERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorC1ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorC2ERKNS0_4pathENS_17directory_optionsEPSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorD2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratoraSEOS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratoraSERKS1_@@GLIBCXX_3.4.27
+FUNC:_ZNSt10filesystem7__cxx1128recursive_directory_iteratorppEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path14_M_split_cmptsEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path14_S_convert_locEPKcS3_RKSt6locale@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path15remove_filenameEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path16replace_filenameERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path17replace_extensionERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path5_ListC1ERKS2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path5_ListC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path9_M_appendESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114path9_M_concatESt17basic_string_viewIcSt11char_traitsIcEE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114pathaSERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114pathdVERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem7__cxx114pathpLERKS1_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8absoluteERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8absoluteERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8absoluteERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8absoluteERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8is_emptyERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8is_emptyERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8is_emptyERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8is_emptyERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8relativeERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8relativeERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8relativeERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem8relativeERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9canonicalERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9canonicalERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9canonicalERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9canonicalERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9copy_fileERKNS_4pathES2_NS_12copy_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9copy_fileERKNS_4pathES2_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9copy_fileERKNS_7__cxx114pathES3_NS_12copy_optionsE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9copy_fileERKNS_7__cxx114pathES3_NS_12copy_optionsERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9file_sizeERKNS_4pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9file_sizeERKNS_4pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9file_sizeERKNS_7__cxx114pathE@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9file_sizeERKNS_7__cxx114pathERSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9proximateERKNS_4pathES2_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9proximateERKNS_4pathES2_RSt10error_code@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9proximateERKNS_7__cxx114pathES3_@@GLIBCXX_3.4.26
+FUNC:_ZNSt10filesystem9proximateERKNS_7__cxx114pathES3_RSt10error_code@@GLIBCXX_3.4.26
FUNC:_ZNSt10istrstream3strEv@@GLIBCXX_3.4
FUNC:_ZNSt10istrstreamC1EPKc@@GLIBCXX_3.4
FUNC:_ZNSt10istrstreamC1EPKcl@@GLIBCXX_3.4
@@ -1860,10 +2160,12 @@ FUNC:_ZNSt11char_traitsIcE2eqERKcS2_@@GLIBCXX_3.4.5
FUNC:_ZNSt11char_traitsIcE2eqERKcS2_@GLIBCXX_3.4
FUNC:_ZNSt11char_traitsIwE2eqERKwS2_@@GLIBCXX_3.4.5
FUNC:_ZNSt11char_traitsIwE2eqERKwS2_@GLIBCXX_3.4
+FUNC:_ZNSt11logic_errorC1EOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt11logic_errorC1EPKc@@GLIBCXX_3.4.21
FUNC:_ZNSt11logic_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
FUNC:_ZNSt11logic_errorC1ERKS_@@GLIBCXX_3.4.21
FUNC:_ZNSt11logic_errorC1ERKSs@@GLIBCXX_3.4
+FUNC:_ZNSt11logic_errorC2EOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt11logic_errorC2EPKc@@GLIBCXX_3.4.21
FUNC:_ZNSt11logic_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
FUNC:_ZNSt11logic_errorC2ERKS_@@GLIBCXX_3.4.21
@@ -1871,6 +2173,7 @@ FUNC:_ZNSt11logic_errorC2ERKSs@@GLIBCXX_3.4
FUNC:_ZNSt11logic_errorD0Ev@@GLIBCXX_3.4
FUNC:_ZNSt11logic_errorD1Ev@@GLIBCXX_3.4
FUNC:_ZNSt11logic_errorD2Ev@@GLIBCXX_3.4
+FUNC:_ZNSt11logic_erroraSEOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt11logic_erroraSERKS_@@GLIBCXX_3.4.21
FUNC:_ZNSt11range_errorC1EPKc@@GLIBCXX_3.4.21
FUNC:_ZNSt11range_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
@@ -1903,6 +2206,20 @@ FUNC:_ZNSt12__basic_fileIcEC1EP15pthread_mutex_t@@GLIBCXX_3.4
FUNC:_ZNSt12__basic_fileIcEC2EP15pthread_mutex_t@@GLIBCXX_3.4
FUNC:_ZNSt12__basic_fileIcED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt12__basic_fileIcED2Ev@@GLIBCXX_3.4
+FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1EOS5_@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem28recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27
+FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC1EOS4_@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27
+FUNC:_ZNSt12__shared_ptrINSt10filesystem4_DirELN9__gnu_cxx12_Lock_policyE2EEaSEOS4_@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1EOS6_@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx1128recursive_directory_iterator10_Dir_stackELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC1EOS5_@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEC2Ev@@GLIBCXX_3.4.27
+FUNC:_ZNSt12__shared_ptrINSt10filesystem7__cxx114_DirELN9__gnu_cxx12_Lock_policyE2EEaSEOS5_@@GLIBCXX_3.4.26
FUNC:_ZNSt12bad_weak_ptrD0Ev@@GLIBCXX_3.4.15
FUNC:_ZNSt12bad_weak_ptrD1Ev@@GLIBCXX_3.4.15
FUNC:_ZNSt12bad_weak_ptrD2Ev@@GLIBCXX_3.4.15
@@ -2206,6 +2523,7 @@ FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEED2Ev@@GLIBCXX_3.4
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEEaSEOS2_@@GLIBCXX_3.4.21
+FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEDn@@GLIBCXX_3.4.26
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRS2_S3_E@@GLIBCXX_3.4
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRSt8ios_baseS4_E@@GLIBCXX_3.4
FUNC:_ZNSt13basic_ostreamIwSt11char_traitsIwEElsEPFRSt9basic_iosIwS1_ES5_E@@GLIBCXX_3.4
@@ -2231,10 +2549,12 @@ FUNC:_ZNSt13random_device7_M_finiEv@@GLIBCXX_3.4.18
FUNC:_ZNSt13random_device7_M_initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
FUNC:_ZNSt13random_device7_M_initERKSs@@GLIBCXX_3.4.18
FUNC:_ZNSt13random_device9_M_getvalEv@@GLIBCXX_3.4.18
+FUNC:_ZNSt13runtime_errorC1EOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt13runtime_errorC1EPKc@@GLIBCXX_3.4.21
FUNC:_ZNSt13runtime_errorC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
FUNC:_ZNSt13runtime_errorC1ERKS_@@GLIBCXX_3.4.21
FUNC:_ZNSt13runtime_errorC1ERKSs@@GLIBCXX_3.4
+FUNC:_ZNSt13runtime_errorC2EOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt13runtime_errorC2EPKc@@GLIBCXX_3.4.21
FUNC:_ZNSt13runtime_errorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
FUNC:_ZNSt13runtime_errorC2ERKS_@@GLIBCXX_3.4.21
@@ -2242,6 +2562,7 @@ FUNC:_ZNSt13runtime_errorC2ERKSs@@GLIBCXX_3.4
FUNC:_ZNSt13runtime_errorD0Ev@@GLIBCXX_3.4
FUNC:_ZNSt13runtime_errorD1Ev@@GLIBCXX_3.4
FUNC:_ZNSt13runtime_errorD2Ev@@GLIBCXX_3.4
+FUNC:_ZNSt13runtime_erroraSEOS_@@GLIBCXX_3.4.26
FUNC:_ZNSt13runtime_erroraSERKS_@@GLIBCXX_3.4.21
FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openEPKcSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt14basic_ifstreamIcSt11char_traitsIcEE4openERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode@@GLIBCXX_3.4.21
@@ -2353,12 +2674,16 @@ FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt14codecvt_bynameIwc11__mbstate_tED2Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIcEC1EPKcm@@GLIBCXX_3.4
+FUNC:_ZNSt14collate_bynameIcEC1ERKSsm@@GLIBCXX_3.4.26
FUNC:_ZNSt14collate_bynameIcEC2EPKcm@@GLIBCXX_3.4
+FUNC:_ZNSt14collate_bynameIcEC2ERKSsm@@GLIBCXX_3.4.26
FUNC:_ZNSt14collate_bynameIcED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIcED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIcED2Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIwEC1EPKcm@@GLIBCXX_3.4
+FUNC:_ZNSt14collate_bynameIwEC1ERKSsm@@GLIBCXX_3.4.26
FUNC:_ZNSt14collate_bynameIwEC2EPKcm@@GLIBCXX_3.4
+FUNC:_ZNSt14collate_bynameIwEC2ERKSsm@@GLIBCXX_3.4.26
FUNC:_ZNSt14collate_bynameIwED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIwED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt14collate_bynameIwED2Ev@@GLIBCXX_3.4
@@ -2498,9 +2823,11 @@ FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEE9underflowEv@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIcSt11char_traitsIcESaIcEEaSEOS3_@@GLIBCXX_3.4.21
@@ -2520,9 +2847,11 @@ FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEE9underflowEv@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt15basic_stringbufIwSt11char_traitsIwESaIwEEaSEOS3_@@GLIBCXX_3.4.21
@@ -2730,9 +3059,11 @@ FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4.
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4
@@ -2742,9 +3073,11 @@ FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4.
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt18basic_stringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4
@@ -2756,6 +3089,7 @@ FUNC:_ZNSt18condition_variableC1Ev@@GLIBCXX_3.4.11
FUNC:_ZNSt18condition_variableC2Ev@@GLIBCXX_3.4.11
FUNC:_ZNSt18condition_variableD1Ev@@GLIBCXX_3.4.11
FUNC:_ZNSt18condition_variableD2Ev@@GLIBCXX_3.4.11
+FUNC:_ZNSt19_Sp_make_shared_tag5_S_eqERKSt9type_info@@GLIBCXX_3.4.26
FUNC:_ZNSt19__codecvt_utf8_baseIDiED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt19__codecvt_utf8_baseIDiED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt19__codecvt_utf8_baseIDiED2Ev@@GLIBCXX_3.4.21
@@ -2770,9 +3104,11 @@ FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4
@@ -2782,9 +3118,11 @@ FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_istringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4
@@ -2794,9 +3132,11 @@ FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEE4swapERS3_@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ERKSsSt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4
@@ -2806,9 +3146,11 @@ FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEE4swapERS3_@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2EOS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ERKSbIwS1_S2_ESt13_Ios_Openmode@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4
+FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4
FUNC:_ZNSt19basic_ostringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4
@@ -2849,6 +3191,26 @@ FUNC:_ZNSt3_V214error_categoryD1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt3_V214error_categoryD2Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt3_V215system_categoryEv@@GLIBCXX_3.4.21
FUNC:_ZNSt3_V216generic_categoryEv@@GLIBCXX_3.4.21
+FUNC:_ZNSt3pmr19new_delete_resourceEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr20get_default_resourceEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr20null_memory_resourceEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr20set_default_resourceEPNS_15memory_resourceE@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr25monotonic_buffer_resource13_M_new_bufferEmm@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr25monotonic_buffer_resource18_M_release_buffersEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resource11do_allocateEmm@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resource13do_deallocateEPvmm@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resource7releaseEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resourceC1ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resourceC2ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resourceD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr26synchronized_pool_resourceD2Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resource11do_allocateEmm@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resource13do_deallocateEPvmm@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resource7releaseEv@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resourceC1ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resourceC2ERKNS_12pool_optionsEPNS_15memory_resourceE@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resourceD1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt3pmr28unsynchronized_pool_resourceD2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt5ctypeIcE13classic_tableEv@@GLIBCXX_3.4
FUNC:_ZNSt5ctypeIcEC1EP15__locale_structPKtbm@@GLIBCXX_3.4
FUNC:_ZNSt5ctypeIcEC1EPKtbm@@GLIBCXX_3.4
@@ -2982,6 +3344,8 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPcS4_EEEEvT_SA_St20forward_iterator_tag@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPcEEvT_S7_St20forward_iterator_tag@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12__sv_wrapperC1ESt17basic_string_viewIcS2_E@@GLIBCXX_3.4.26
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12__sv_wrapperC2ESt17basic_string_viewIcS2_E@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_M_local_dataEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_M_set_lengthEm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcN9__gnu_cxx17__normal_iteratorIPKcS4_EESA_@@GLIBCXX_3.4.21
@@ -2991,10 +3355,12 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13_S_copy_charsEPcS5_S
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE13shrink_to_fitEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE14_M_replace_auxEmmmc@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16_M_get_allocatorEv@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE17_S_to_string_viewESt17basic_string_viewIcS2_E@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE18_M_construct_aux_2Emc@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE2atEm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE3endEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4backEv@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4dataEv@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4rendEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE5beginEv@@GLIBCXX_3.4.21
@@ -3018,6 +3384,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignERKS4_@@GLIBCXX
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignERKS4_mm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignESt16initializer_listIcE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6assignEmc@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EESt16initializer_listIcE@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EEc@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPKcS4_EEmc@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE6insertEN9__gnu_cxx17__normal_iteratorIPcS4_EESt16initializer_listIcE@@GLIBCXX_3.4.21
@@ -3067,6 +3434,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_lengthEm@@GLIBCXX_
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEmmPKcm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_S_assignEPcmc@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9push_backEc@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EOS4_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1EPKcRKS3_@@GLIBCXX_3.4.21
@@ -3083,6 +3451,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IN9__gnu_cxx17__normal_iteratorIPcS4_EEvEET_SA_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IPKcvEET_S8_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC1IPcvEET_S7_RKS3_@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EOS4_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEC2EPKcRKS3_@@GLIBCXX_3.4.21
@@ -3125,6 +3494,8 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIN9__gnu_cxx17__normal_iteratorIPwS4_EEEEvT_SA_St20forward_iterator_tag@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIPKwEEvT_S8_St20forward_iterator_tag@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12_M_constructIPwEEvT_S7_St20forward_iterator_tag@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12__sv_wrapperC1ESt17basic_string_viewIwS2_E@@GLIBCXX_3.4.26
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE12__sv_wrapperC2ESt17basic_string_viewIwS2_E@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_M_local_dataEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_M_set_lengthEm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwN9__gnu_cxx17__normal_iteratorIPKwS4_EESA_@@GLIBCXX_3.4.21
@@ -3134,10 +3505,12 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13_S_copy_charsEPwS5_S
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE13shrink_to_fitEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE14_M_replace_auxEmmmw@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE16_M_get_allocatorEv@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE17_S_to_string_viewESt17basic_string_viewIwS2_E@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE18_M_construct_aux_2Emw@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE2atEm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE3endEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4backEv@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4dataEv@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4rendEv@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE5beginEv@@GLIBCXX_3.4.21
@@ -3161,6 +3534,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignERKS4_@@GLIBCXX
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignERKS4_mm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignESt16initializer_listIwE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6assignEmw@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EESt16initializer_listIwE@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EEmw@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPKwS4_EEw@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE6insertEN9__gnu_cxx17__normal_iteratorIPwS4_EESt16initializer_listIwE@@GLIBCXX_3.4.21
@@ -3210,6 +3584,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_lengthEm@@GLIBCXX_
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_M_mutateEmmPKwm@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9_S_assignEPwmw@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEE9push_backEw@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EOS4_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1EPKwRKS3_@@GLIBCXX_3.4.21
@@ -3226,6 +3601,7 @@ FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IN9__gnu_cxx17__normal_iteratorIPwS4_EEvEET_SA_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IPKwvEET_S8_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC1IPwvEET_S7_RKS3_@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2ENS4_12__sv_wrapperERKS3_@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EOS4_RKS3_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1112basic_stringIwSt11char_traitsIwESaIwEEC2EPKwRKS3_@@GLIBCXX_3.4.21
@@ -3289,10 +3665,12 @@ FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21
@@ -3318,10 +3696,12 @@ FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2EOS4_ONS4_14__xfer_bufptrsE@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1115basic_stringbufIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21
@@ -3401,9 +3781,11 @@ FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEE4swapERS4_@@GLIB
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21
@@ -3413,9 +3795,11 @@ FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEE4swapERS4_@@GLIB
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1118basic_stringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21
@@ -3425,9 +3809,11 @@ FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEE4swapERS4_@@GLI
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21
@@ -3437,9 +3823,11 @@ FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEE4swapERS4_@@GLI
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_istringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21
@@ -3449,9 +3837,11 @@ FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEE4swapERS4_@@GLI
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ERKNS_12basic_stringIcS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEED2Ev@@GLIBCXX_3.4.21
@@ -3461,9 +3851,11 @@ FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEE4swapERS4_@@GLI
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC1Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2EOS4_@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ERKNS_12basic_stringIwS2_S3_EESt13_Ios_Openmode@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2ESt13_Ios_Openmode@@GLIBCXX_3.4.21
+FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEEC2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx1119basic_ostringstreamIwSt11char_traitsIwESaIwEED2Ev@@GLIBCXX_3.4.21
@@ -3546,9 +3938,15 @@ FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEC2Em@
FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEED2Ev@@GLIBCXX_3.4.21
+FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED0Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt7codecvtIDiDu11__mbstate_tED2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7codecvtIDic11__mbstate_tED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7codecvtIDic11__mbstate_tED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7codecvtIDic11__mbstate_tED2Ev@@GLIBCXX_3.4.21
+FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED0Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED1Ev@@GLIBCXX_3.4.26
+FUNC:_ZNSt7codecvtIDsDu11__mbstate_tED2Ev@@GLIBCXX_3.4.26
FUNC:_ZNSt7codecvtIDsc11__mbstate_tED0Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7codecvtIDsc11__mbstate_tED1Ev@@GLIBCXX_3.4.21
FUNC:_ZNSt7codecvtIDsc11__mbstate_tED2Ev@@GLIBCXX_3.4.21
@@ -3831,6 +4229,7 @@ FUNC:_ZSt18_Rb_tree_incrementPSt18_Rb_tree_node_base@@GLIBCXX_3.4
FUNC:_ZSt18__throw_bad_typeidv@@GLIBCXX_3.4
FUNC:_ZSt18uncaught_exceptionv@@GLIBCXX_3.4
FUNC:_ZSt19__throw_ios_failurePKc@@GLIBCXX_3.4
+FUNC:_ZSt19__throw_ios_failurePKci@@GLIBCXX_3.4.26
FUNC:_ZSt19__throw_logic_errorPKc@@GLIBCXX_3.4
FUNC:_ZSt19__throw_range_errorPKc@@GLIBCXX_3.4
FUNC:_ZSt19__throw_regex_errorNSt15regex_constants10error_typeE@@GLIBCXX_3.4.15
@@ -4211,6 +4610,7 @@ OBJECT:0:CXXABI_1.3
OBJECT:0:CXXABI_1.3.1
OBJECT:0:CXXABI_1.3.10
OBJECT:0:CXXABI_1.3.11
+OBJECT:0:CXXABI_1.3.12
OBJECT:0:CXXABI_1.3.2
OBJECT:0:CXXABI_1.3.3
OBJECT:0:CXXABI_1.3.4
@@ -4240,6 +4640,8 @@ OBJECT:0:GLIBCXX_3.4.22
OBJECT:0:GLIBCXX_3.4.23
OBJECT:0:GLIBCXX_3.4.24
OBJECT:0:GLIBCXX_3.4.25
+OBJECT:0:GLIBCXX_3.4.26
+OBJECT:0:GLIBCXX_3.4.27
OBJECT:0:GLIBCXX_3.4.3
OBJECT:0:GLIBCXX_3.4.4
OBJECT:0:GLIBCXX_3.4.5
@@ -4326,6 +4728,7 @@ OBJECT:16:_ZTIDf@@CXXABI_1.3.4
OBJECT:16:_ZTIDi@@CXXABI_1.3.3
OBJECT:16:_ZTIDn@@CXXABI_1.3.5
OBJECT:16:_ZTIDs@@CXXABI_1.3.3
+OBJECT:16:_ZTIDu@@CXXABI_1.3.12
OBJECT:16:_ZTIN10__cxxabiv115__forced_unwindE@@CXXABI_1.3.2
OBJECT:16:_ZTIN10__cxxabiv119__foreign_exceptionE@@CXXABI_1.3.2
OBJECT:16:_ZTINSt13__future_base11_State_baseE@@GLIBCXX_3.4.15
@@ -4447,6 +4850,19 @@ OBJECT:1:_ZNSt14numeric_limitsIDsE8is_exactE@@GLIBCXX_3.4.11
OBJECT:1:_ZNSt14numeric_limitsIDsE9is_iec559E@@GLIBCXX_3.4.11
OBJECT:1:_ZNSt14numeric_limitsIDsE9is_moduloE@@GLIBCXX_3.4.11
OBJECT:1:_ZNSt14numeric_limitsIDsE9is_signedE@@GLIBCXX_3.4.11
+OBJECT:1:_ZNSt14numeric_limitsIDuE10is_boundedE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE10is_integerE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE12has_infinityE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE13has_quiet_NaNE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE14is_specializedE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE15has_denorm_lossE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE15tinyness_beforeE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE17has_signaling_NaNE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE5trapsE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE8is_exactE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE9is_iec559E@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE9is_moduloE@@GLIBCXX_3.4.26
+OBJECT:1:_ZNSt14numeric_limitsIDuE9is_signedE@@GLIBCXX_3.4.26
OBJECT:1:_ZNSt14numeric_limitsIaE10is_boundedE@@GLIBCXX_3.4
OBJECT:1:_ZNSt14numeric_limitsIaE10is_integerE@@GLIBCXX_3.4
OBJECT:1:_ZNSt14numeric_limitsIaE12has_infinityE@@GLIBCXX_3.4
@@ -4758,6 +5174,8 @@ OBJECT:24:_ZTIN9__gnu_cxx13stdio_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4
OBJECT:24:_ZTIN9__gnu_cxx13stdio_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4
OBJECT:24:_ZTIN9__gnu_cxx18stdio_sync_filebufIcSt11char_traitsIcEEE@@GLIBCXX_3.4
OBJECT:24:_ZTIN9__gnu_cxx18stdio_sync_filebufIwSt11char_traitsIwEEE@@GLIBCXX_3.4
+OBJECT:24:_ZTINSt10filesystem16filesystem_errorE@@GLIBCXX_3.4.26
+OBJECT:24:_ZTINSt10filesystem7__cxx1116filesystem_errorE@@GLIBCXX_3.4.26
OBJECT:24:_ZTINSt13__future_base19_Async_state_commonE@@GLIBCXX_3.4.17
OBJECT:24:_ZTINSt17__gnu_cxx_ldbl1287num_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4
OBJECT:24:_ZTINSt17__gnu_cxx_ldbl1287num_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4
@@ -4767,6 +5185,8 @@ OBJECT:24:_ZTINSt17__gnu_cxx_ldbl1289money_getIcSt19istreambuf_iteratorIcSt11cha
OBJECT:24:_ZTINSt17__gnu_cxx_ldbl1289money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4
OBJECT:24:_ZTINSt17__gnu_cxx_ldbl1289money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEEE@@GLIBCXX_LDBL_3.4
OBJECT:24:_ZTINSt17__gnu_cxx_ldbl1289money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEEE@@GLIBCXX_LDBL_3.4
+OBJECT:24:_ZTINSt3pmr26synchronized_pool_resourceE@@GLIBCXX_3.4.26
+OBJECT:24:_ZTINSt3pmr28unsynchronized_pool_resourceE@@GLIBCXX_3.4.26
OBJECT:24:_ZTINSt7__cxx1114collate_bynameIcEE@@GLIBCXX_3.4.21
OBJECT:24:_ZTINSt7__cxx1114collate_bynameIwEE@@GLIBCXX_3.4.21
OBJECT:24:_ZTINSt7__cxx1115basic_stringbufIcSt11char_traitsIcESaIcEEE@@GLIBCXX_3.4.21
@@ -4865,7 +5285,9 @@ OBJECT:24:_ZTISt25__codecvt_utf8_utf16_baseIDiE@@GLIBCXX_3.4.21
OBJECT:24:_ZTISt25__codecvt_utf8_utf16_baseIDsE@@GLIBCXX_3.4.21
OBJECT:24:_ZTISt25__codecvt_utf8_utf16_baseIwE@@GLIBCXX_3.4.21
OBJECT:24:_ZTISt5ctypeIwE@@GLIBCXX_3.4
+OBJECT:24:_ZTISt7codecvtIDiDu11__mbstate_tE@@GLIBCXX_3.4.26
OBJECT:24:_ZTISt7codecvtIDic11__mbstate_tE@@GLIBCXX_3.4.21
+OBJECT:24:_ZTISt7codecvtIDsDu11__mbstate_tE@@GLIBCXX_3.4.26
OBJECT:24:_ZTISt7codecvtIDsc11__mbstate_tE@@GLIBCXX_3.4.21
OBJECT:24:_ZTISt7codecvtIcc11__mbstate_tE@@GLIBCXX_3.4
OBJECT:24:_ZTISt7codecvtIwc11__mbstate_tE@@GLIBCXX_3.4
@@ -4952,6 +5374,8 @@ OBJECT:2:_ZTSv@@CXXABI_1.3
OBJECT:2:_ZTSw@@CXXABI_1.3
OBJECT:2:_ZTSx@@CXXABI_1.3
OBJECT:2:_ZTSy@@CXXABI_1.3
+OBJECT:30:_ZTSSt7codecvtIDiDu11__mbstate_tE@@GLIBCXX_3.4.26
+OBJECT:30:_ZTSSt7codecvtIDsDu11__mbstate_tE@@GLIBCXX_3.4.26
OBJECT:32:_ZNSbIwSt11char_traitsIwESaIwEE4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4
OBJECT:32:_ZNSs4_Rep20_S_empty_rep_storageE@@GLIBCXX_3.4
OBJECT:32:_ZTIPDd@@CXXABI_1.3.4
@@ -4960,12 +5384,14 @@ OBJECT:32:_ZTIPDf@@CXXABI_1.3.4
OBJECT:32:_ZTIPDi@@CXXABI_1.3.3
OBJECT:32:_ZTIPDn@@CXXABI_1.3.5
OBJECT:32:_ZTIPDs@@CXXABI_1.3.3
+OBJECT:32:_ZTIPDu@@CXXABI_1.3.12
OBJECT:32:_ZTIPKDd@@CXXABI_1.3.4
OBJECT:32:_ZTIPKDe@@CXXABI_1.3.4
OBJECT:32:_ZTIPKDf@@CXXABI_1.3.4
OBJECT:32:_ZTIPKDi@@CXXABI_1.3.3
OBJECT:32:_ZTIPKDn@@CXXABI_1.3.5
OBJECT:32:_ZTIPKDs@@CXXABI_1.3.3
+OBJECT:32:_ZTIPKDu@@CXXABI_1.3.12
OBJECT:32:_ZTIPKa@@CXXABI_1.3
OBJECT:32:_ZTIPKb@@CXXABI_1.3
OBJECT:32:_ZTIPKc@@CXXABI_1.3
@@ -5095,6 +5521,8 @@ OBJECT:40:_ZTSSt14basic_ifstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4
OBJECT:40:_ZTSSt14basic_iostreamIwSt11char_traitsIwEE@@GLIBCXX_3.4
OBJECT:40:_ZTSSt14basic_ofstreamIcSt11char_traitsIcEE@@GLIBCXX_3.4
OBJECT:40:_ZTSSt14basic_ofstreamIwSt11char_traitsIwEE@@GLIBCXX_3.4
+OBJECT:40:_ZTVNSt10filesystem16filesystem_errorE@@GLIBCXX_3.4.26
+OBJECT:40:_ZTVNSt10filesystem7__cxx1116filesystem_errorE@@GLIBCXX_3.4.26
OBJECT:40:_ZTVNSt13__future_base11_State_baseE@@GLIBCXX_3.4.15
OBJECT:40:_ZTVNSt13__future_base12_Result_baseE@@GLIBCXX_3.4.15
OBJECT:40:_ZTVNSt13__future_base19_Async_state_commonE@@GLIBCXX_3.4.17
@@ -5169,6 +5597,15 @@ OBJECT:4:_ZNSt14numeric_limitsIDsE14min_exponent10E@@GLIBCXX_3.4.11
OBJECT:4:_ZNSt14numeric_limitsIDsE5radixE@@GLIBCXX_3.4.11
OBJECT:4:_ZNSt14numeric_limitsIDsE6digitsE@@GLIBCXX_3.4.11
OBJECT:4:_ZNSt14numeric_limitsIDsE8digits10E@@GLIBCXX_3.4.11
+OBJECT:4:_ZNSt14numeric_limitsIDuE10has_denormE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE11round_styleE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE12max_exponentE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE12min_exponentE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE14max_exponent10E@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE14min_exponent10E@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE5radixE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE6digitsE@@GLIBCXX_3.4.26
+OBJECT:4:_ZNSt14numeric_limitsIDuE8digits10E@@GLIBCXX_3.4.26
OBJECT:4:_ZNSt14numeric_limitsIaE10has_denormE@@GLIBCXX_3.4
OBJECT:4:_ZNSt14numeric_limitsIaE11round_styleE@@GLIBCXX_3.4
OBJECT:4:_ZNSt14numeric_limitsIaE12max_digits10E@@GLIBCXX_3.4.14
@@ -5585,7 +6022,9 @@ OBJECT:88:_ZTVSt23__codecvt_abstract_baseIwc11__mbstate_tE@@GLIBCXX_3.4
OBJECT:88:_ZTVSt25__codecvt_utf8_utf16_baseIDiE@@GLIBCXX_3.4.21
OBJECT:88:_ZTVSt25__codecvt_utf8_utf16_baseIDsE@@GLIBCXX_3.4.21
OBJECT:88:_ZTVSt25__codecvt_utf8_utf16_baseIwE@@GLIBCXX_3.4.21
+OBJECT:88:_ZTVSt7codecvtIDiDu11__mbstate_tE@@GLIBCXX_3.4.26
OBJECT:88:_ZTVSt7codecvtIDic11__mbstate_tE@@GLIBCXX_3.4.21
+OBJECT:88:_ZTVSt7codecvtIDsDu11__mbstate_tE@@GLIBCXX_3.4.26
OBJECT:88:_ZTVSt7codecvtIDsc11__mbstate_tE@@GLIBCXX_3.4.21
OBJECT:88:_ZTVSt7codecvtIcc11__mbstate_tE@@GLIBCXX_3.4
OBJECT:88:_ZTVSt7codecvtIwc11__mbstate_tE@@GLIBCXX_3.4
@@ -5679,7 +6118,9 @@ OBJECT:8:_ZNSt7__cxx119money_getIcSt19istreambuf_iteratorIcSt11char_traitsIcEEE2
OBJECT:8:_ZNSt7__cxx119money_getIwSt19istreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21
OBJECT:8:_ZNSt7__cxx119money_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE2idE@@GLIBCXX_3.4.21
OBJECT:8:_ZNSt7__cxx119money_putIwSt19ostreambuf_iteratorIwSt11char_traitsIwEEE2idE@@GLIBCXX_3.4.21
+OBJECT:8:_ZNSt7codecvtIDiDu11__mbstate_tE2idE@@GLIBCXX_3.4.26
OBJECT:8:_ZNSt7codecvtIDic11__mbstate_tE2idE@@GLIBCXX_3.4.21
+OBJECT:8:_ZNSt7codecvtIDsDu11__mbstate_tE2idE@@GLIBCXX_3.4.26
OBJECT:8:_ZNSt7codecvtIDsc11__mbstate_tE2idE@@GLIBCXX_3.4.21
OBJECT:8:_ZNSt7codecvtIcc11__mbstate_tE2idE@@GLIBCXX_3.4
OBJECT:8:_ZNSt7codecvtIwc11__mbstate_tE2idE@@GLIBCXX_3.4
diff --git a/libstdc++-v3/doc/xml/manual/documentation_hacking.xml b/libstdc++-v3/doc/xml/manual/documentation_hacking.xml
index fffa1fc..e0990a2 100644
--- a/libstdc++-v3/doc/xml/manual/documentation_hacking.xml
+++ b/libstdc++-v3/doc/xml/manual/documentation_hacking.xml
@@ -261,7 +261,7 @@
<para>
Prerequisite tools are Bash 2.0 or later,
- <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.doxygen.org">Doxygen</link>, and
+ <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.doxygen.nl">Doxygen</link>, and
the <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.gnu.org/software/coreutils/">GNU
coreutils</link>. (GNU versions of find, xargs, and possibly
sed and grep are used, just because the GNU versions make
@@ -445,9 +445,10 @@
<para>
Adding Doxygen markup to a file (informally called
- <quote>doxygenating</quote>) is very simple. The Doxygen manual can be
- found
- <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.stack.nl/~dimitri/doxygen/download.html#latestman">here</link>.
+ <quote>doxygenating</quote>) is very simple. See the
+ <link xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:href="http://www.doxygen.nl/download.html#latestman">Doxygen
+ manual</link> for details.
We try to use a very-recent version of Doxygen.
</para>
@@ -463,7 +464,8 @@
<para>
Some commentary to accompany
- the first list in the <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.stack.nl/~dimitri/doxygen/manual/docblocks.html">Special
+ the first list in the <link xmlns:xlink="http://www.w3.org/1999/xlink"
+ xlink:href="http://www.doxygen.nl/manual/docblocks.html">Special
Documentation Blocks</link> section of the Doxygen manual:
</para>
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 742f2c3..3fe80f3 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -57,6 +57,7 @@ std_headers = \
${std_srcdir}/memory \
${std_srcdir}/memory_resource \
${std_srcdir}/mutex \
+ ${std_srcdir}/numbers \
${std_srcdir}/numeric \
${std_srcdir}/optional \
${std_srcdir}/ostream \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index fd4dbf7..b675d35 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -401,6 +401,7 @@ std_headers = \
${std_srcdir}/memory \
${std_srcdir}/memory_resource \
${std_srcdir}/mutex \
+ ${std_srcdir}/numbers \
${std_srcdir}/numeric \
${std_srcdir}/optional \
${std_srcdir}/ostream \
diff --git a/libstdc++-v3/include/bits/algorithmfwd.h b/libstdc++-v3/include/bits/algorithmfwd.h
index 5e47fff..9c511f0 100644
--- a/libstdc++-v3/include/bits/algorithmfwd.h
+++ b/libstdc++-v3/include/bits/algorithmfwd.h
@@ -191,21 +191,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// adjacent_find
+#if __cplusplus > 201703L
+# define __cpp_lib_constexpr_algorithms 201711L
+# define __cpp_lib_constexpr_swap_algorithms 201806L
+#endif
+
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
bool
all_of(_IIter, _IIter, _Predicate);
template<typename _IIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
bool
any_of(_IIter, _IIter, _Predicate);
#endif
template<typename _FIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
bool
binary_search(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
binary_search(_FIter, _FIter, const _Tp&, _Compare);
@@ -222,19 +231,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
template<typename _IIter, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
copy(_IIter, _IIter, _OIter);
template<typename _BIter1, typename _BIter2>
+ _GLIBCXX20_CONSTEXPR
_BIter2
copy_backward(_BIter1, _BIter1, _BIter2);
#if __cplusplus >= 201103L
template<typename _IIter, typename _OIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_OIter
copy_if(_IIter, _IIter, _OIter, _Predicate);
template<typename _IIter, typename _Size, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
copy_n(_IIter, _Size, _OIter);
#endif
@@ -243,28 +256,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// count_if
template<typename _FIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
pair<_FIter, _FIter>
equal_range(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
pair<_FIter, _FIter>
equal_range(_FIter, _FIter, const _Tp&, _Compare);
template<typename _FIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
void
fill(_FIter, _FIter, const _Tp&);
template<typename _OIter, typename _Size, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_OIter
fill_n(_OIter, _Size, const _Tp&);
// find
template<typename _FIter1, typename _FIter2>
+ _GLIBCXX20_CONSTEXPR
_FIter1
find_end(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_FIter1
find_end(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
@@ -273,6 +292,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_IIter
find_if_not(_IIter, _IIter, _Predicate);
#endif
@@ -282,10 +302,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// generate_n
template<typename _IIter1, typename _IIter2>
+ _GLIBCXX20_CONSTEXPR
bool
includes(_IIter1, _IIter1, _IIter2, _IIter2);
template<typename _IIter1, typename _IIter2, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
includes(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
@@ -299,68 +321,84 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
bool
is_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
is_heap(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
_RAIter
is_heap_until(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_RAIter
is_heap_until(_RAIter, _RAIter, _Compare);
template<typename _IIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
bool
is_partitioned(_IIter, _IIter, _Predicate);
template<typename _FIter1, typename _FIter2>
+ _GLIBCXX20_CONSTEXPR
bool
is_permutation(_FIter1, _FIter1, _FIter2);
template<typename _FIter1, typename _FIter2,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
bool
is_permutation(_FIter1, _FIter1, _FIter2, _BinaryPredicate);
template<typename _FIter>
+ _GLIBCXX20_CONSTEXPR
bool
is_sorted(_FIter, _FIter);
template<typename _FIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
is_sorted(_FIter, _FIter, _Compare);
template<typename _FIter>
+ _GLIBCXX20_CONSTEXPR
_FIter
is_sorted_until(_FIter, _FIter);
template<typename _FIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_FIter
is_sorted_until(_FIter, _FIter, _Compare);
#endif
template<typename _FIter1, typename _FIter2>
+ _GLIBCXX20_CONSTEXPR
void
iter_swap(_FIter1, _FIter2);
template<typename _FIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_FIter
lower_bound(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_FIter
lower_bound(_FIter, _FIter, const _Tp&, _Compare);
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
void
make_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
make_heap(_RAIter, _RAIter, _Compare);
@@ -444,15 +482,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// mismatch
template<typename _BIter>
+ _GLIBCXX20_CONSTEXPR
bool
next_permutation(_BIter, _BIter);
template<typename _BIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
next_permutation(_BIter, _BIter, _Compare);
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
bool
none_of(_IIter, _IIter, _Predicate);
#endif
@@ -461,10 +502,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// partial_sort
template<typename _IIter, typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
_RAIter
partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter);
template<typename _IIter, typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_RAIter
partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter, _Compare);
@@ -473,84 +516,102 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
template<typename _IIter, typename _OIter1,
typename _OIter2, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
pair<_OIter1, _OIter2>
partition_copy(_IIter, _IIter, _OIter1, _OIter2, _Predicate);
template<typename _FIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_FIter
partition_point(_FIter, _FIter, _Predicate);
#endif
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
void
pop_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
pop_heap(_RAIter, _RAIter, _Compare);
template<typename _BIter>
+ _GLIBCXX20_CONSTEXPR
bool
prev_permutation(_BIter, _BIter);
template<typename _BIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
prev_permutation(_BIter, _BIter, _Compare);
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
void
push_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
push_heap(_RAIter, _RAIter, _Compare);
// random_shuffle
template<typename _FIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_FIter
remove(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_FIter
remove_if(_FIter, _FIter, _Predicate);
template<typename _IIter, typename _OIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_OIter
remove_copy(_IIter, _IIter, _OIter, const _Tp&);
template<typename _IIter, typename _OIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_OIter
remove_copy_if(_IIter, _IIter, _OIter, _Predicate);
// replace
template<typename _IIter, typename _OIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_OIter
replace_copy(_IIter, _IIter, _OIter, const _Tp&, const _Tp&);
template<typename _Iter, typename _OIter, typename _Predicate, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_OIter
replace_copy_if(_Iter, _Iter, _OIter, _Predicate, const _Tp&);
// replace_if
template<typename _BIter>
+ _GLIBCXX20_CONSTEXPR
void
reverse(_BIter, _BIter);
template<typename _BIter, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
reverse_copy(_BIter, _BIter, _OIter);
inline namespace _V2
{
template<typename _FIter>
+ _GLIBCXX20_CONSTEXPR
_FIter
rotate(_FIter, _FIter, _FIter);
}
template<typename _FIter, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
rotate_copy(_FIter, _FIter, _FIter, _OIter);
@@ -568,10 +629,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
void
sort_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
sort_heap(_RAIter, _RAIter, _Compare);
@@ -583,97 +646,119 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// For C++11 swap() is declared in <type_traits>.
template<typename _Tp, size_t _Nm>
+ _GLIBCXX20_CONSTEXPR
inline void
swap(_Tp& __a, _Tp& __b);
template<typename _Tp, size_t _Nm>
+ _GLIBCXX20_CONSTEXPR
inline void
swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]);
#endif
template<typename _FIter1, typename _FIter2>
+ _GLIBCXX20_CONSTEXPR
_FIter2
swap_ranges(_FIter1, _FIter1, _FIter2);
// transform
template<typename _FIter>
+ _GLIBCXX20_CONSTEXPR
_FIter
unique(_FIter, _FIter);
template<typename _FIter, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_FIter
unique(_FIter, _FIter, _BinaryPredicate);
// unique_copy
template<typename _FIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_FIter
upper_bound(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_FIter
upper_bound(_FIter, _FIter, const _Tp&, _Compare);
_GLIBCXX_BEGIN_NAMESPACE_ALGO
template<typename _FIter>
+ _GLIBCXX20_CONSTEXPR
_FIter
adjacent_find(_FIter, _FIter);
template<typename _FIter, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_FIter
adjacent_find(_FIter, _FIter, _BinaryPredicate);
template<typename _IIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
typename iterator_traits<_IIter>::difference_type
count(_IIter, _IIter, const _Tp&);
template<typename _IIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
typename iterator_traits<_IIter>::difference_type
count_if(_IIter, _IIter, _Predicate);
template<typename _IIter1, typename _IIter2>
+ _GLIBCXX20_CONSTEXPR
bool
equal(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
bool
equal(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
template<typename _IIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_IIter
find(_IIter, _IIter, const _Tp&);
template<typename _FIter1, typename _FIter2>
+ _GLIBCXX20_CONSTEXPR
_FIter1
find_first_of(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_FIter1
find_first_of(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
template<typename _IIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_IIter
find_if(_IIter, _IIter, _Predicate);
template<typename _IIter, typename _Funct>
+ _GLIBCXX20_CONSTEXPR
_Funct
for_each(_IIter, _IIter, _Funct);
template<typename _FIter, typename _Generator>
+ _GLIBCXX20_CONSTEXPR
void
generate(_FIter, _FIter, _Generator);
template<typename _OIter, typename _Size, typename _Generator>
+ _GLIBCXX20_CONSTEXPR
_OIter
generate_n(_OIter, _Size, _Generator);
template<typename _IIter1, typename _IIter2>
+ _GLIBCXX20_CONSTEXPR
bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2);
template<typename _IIter1, typename _IIter2, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
@@ -688,11 +773,13 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
max_element(_FIter, _FIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
@@ -707,30 +794,37 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
min_element(_FIter, _FIter, _Compare);
template<typename _IIter1, typename _IIter2>
+ _GLIBCXX20_CONSTEXPR
pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
void
nth_element(_RAIter, _RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
nth_element(_RAIter, _RAIter, _RAIter, _Compare);
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
void
partial_sort(_RAIter, _RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
partial_sort(_RAIter, _RAIter, _RAIter, _Compare);
template<typename _BIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_BIter
partition(_BIter, _BIter, _Predicate);
@@ -748,72 +842,88 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
#endif
template<typename _FIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
void
replace(_FIter, _FIter, const _Tp&, const _Tp&);
template<typename _FIter, typename _Predicate, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
void
replace_if(_FIter, _FIter, _Predicate, const _Tp&);
template<typename _FIter1, typename _FIter2>
+ _GLIBCXX20_CONSTEXPR
_FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
template<typename _FIter, typename _Size, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_FIter
search_n(_FIter, _FIter, _Size, const _Tp&);
template<typename _FIter, typename _Size, typename _Tp,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_FIter
search_n(_FIter, _FIter, _Size, const _Tp&, _BinaryPredicate);
template<typename _IIter1, typename _IIter2, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2,
_OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
void
sort(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
sort(_RAIter, _RAIter, _Compare);
@@ -826,19 +936,23 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
stable_sort(_RAIter, _RAIter, _Compare);
template<typename _IIter, typename _OIter, typename _UnaryOperation>
+ _GLIBCXX20_CONSTEXPR
_OIter
transform(_IIter, _IIter, _OIter, _UnaryOperation);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _BinaryOperation>
+ _GLIBCXX20_CONSTEXPR
_OIter
transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation);
template<typename _IIter, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
unique_copy(_IIter, _IIter, _OIter);
template<typename _IIter, typename _OIter, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_OIter
unique_copy(_IIter, _IIter, _OIter, _BinaryPredicate);
diff --git a/libstdc++-v3/include/bits/cpp_type_traits.h b/libstdc++-v3/include/bits/cpp_type_traits.h
index d7f8517..3e165c7 100644
--- a/libstdc++-v3/include/bits/cpp_type_traits.h
+++ b/libstdc++-v3/include/bits/cpp_type_traits.h
@@ -424,6 +424,7 @@ __INT_N(__GLIBCXX_TYPE_INT_N_3)
// Fallback implementation of the function in bits/stl_iterator.h used to
// remove the move_iterator wrapper.
template<typename _Iterator>
+ _GLIBCXX20_CONSTEXPR
inline _Iterator
__miter_base(_Iterator __it)
{ return __it; }
diff --git a/libstdc++-v3/include/bits/move.h b/libstdc++-v3/include/bits/move.h
index 7271e27..d7c7068 100644
--- a/libstdc++-v3/include/bits/move.h
+++ b/libstdc++-v3/include/bits/move.h
@@ -145,6 +145,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// C++11 version of std::exchange for internal use.
template <typename _Tp, typename _Up = _Tp>
+ _GLIBCXX20_CONSTEXPR
inline _Tp
__exchange(_Tp& __obj, _Up&& __new_val)
{
@@ -174,6 +175,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @return Nothing.
*/
template<typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline
#if __cplusplus >= 201103L
typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>,
@@ -198,6 +200,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// DR 809. std::swap should be overloaded for array types.
/// Swap the contents of two arrays.
template<typename _Tp, size_t _Nm>
+ _GLIBCXX20_CONSTEXPR
inline
#if __cplusplus >= 201103L
typename enable_if<__is_swappable<_Tp>::value>::type
diff --git a/libstdc++-v3/include/bits/predefined_ops.h b/libstdc++-v3/include/bits/predefined_ops.h
index 65215c7..e39b76c 100644
--- a/libstdc++-v3/include/bits/predefined_ops.h
+++ b/libstdc++-v3/include/bits/predefined_ops.h
@@ -56,19 +56,23 @@ namespace __ops
_Iter_less_val() { }
#endif
+ _GLIBCXX20_CONSTEXPR
explicit
_Iter_less_val(_Iter_less_iter) { }
template<typename _Iterator, typename _Value>
+ _GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator __it, _Value& __val) const
{ return *__it < __val; }
};
+ _GLIBCXX20_CONSTEXPR
inline _Iter_less_val
__iter_less_val()
{ return _Iter_less_val(); }
+ _GLIBCXX20_CONSTEXPR
inline _Iter_less_val
__iter_comp_val(_Iter_less_iter)
{ return _Iter_less_val(); }
@@ -81,19 +85,23 @@ namespace __ops
_Val_less_iter() { }
#endif
+ _GLIBCXX20_CONSTEXPR
explicit
_Val_less_iter(_Iter_less_iter) { }
template<typename _Value, typename _Iterator>
+ _GLIBCXX20_CONSTEXPR
bool
operator()(_Value& __val, _Iterator __it) const
{ return __val < *__it; }
};
+ _GLIBCXX20_CONSTEXPR
inline _Val_less_iter
__val_less_iter()
{ return _Val_less_iter(); }
+ _GLIBCXX20_CONSTEXPR
inline _Val_less_iter
__val_comp_iter(_Iter_less_iter)
{ return _Val_less_iter(); }
@@ -101,11 +109,13 @@ namespace __ops
struct _Iter_equal_to_iter
{
template<typename _Iterator1, typename _Iterator2>
+ _GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator1 __it1, _Iterator2 __it2) const
{ return *__it1 == *__it2; }
};
+ _GLIBCXX20_CONSTEXPR
inline _Iter_equal_to_iter
__iter_equal_to_iter()
{ return _Iter_equal_to_iter(); }
@@ -113,15 +123,18 @@ namespace __ops
struct _Iter_equal_to_val
{
template<typename _Iterator, typename _Value>
+ _GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator __it, _Value& __val) const
{ return *__it == __val; }
};
+ _GLIBCXX20_CONSTEXPR
inline _Iter_equal_to_val
__iter_equal_to_val()
{ return _Iter_equal_to_val(); }
+ _GLIBCXX20_CONSTEXPR
inline _Iter_equal_to_val
__iter_comp_val(_Iter_equal_to_iter)
{ return _Iter_equal_to_val(); }
@@ -154,17 +167,20 @@ namespace __ops
{
_Compare _M_comp;
+ _GLIBCXX20_CONSTEXPR
explicit
_Iter_comp_val(_Compare __comp)
: _M_comp(_GLIBCXX_MOVE(__comp))
{ }
+ _GLIBCXX20_CONSTEXPR
explicit
_Iter_comp_val(const _Iter_comp_iter<_Compare>& __comp)
: _M_comp(__comp._M_comp)
{ }
#if __cplusplus >= 201103L
+ _GLIBCXX20_CONSTEXPR
explicit
_Iter_comp_val(_Iter_comp_iter<_Compare>&& __comp)
: _M_comp(std::move(__comp._M_comp))
@@ -172,17 +188,20 @@ namespace __ops
#endif
template<typename _Iterator, typename _Value>
+ _GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator __it, _Value& __val)
{ return bool(_M_comp(*__it, __val)); }
};
template<typename _Compare>
- inline _Iter_comp_val<_Compare>
+ _GLIBCXX20_CONSTEXPR
+ inline _Iter_comp_val<_Compare>
__iter_comp_val(_Compare __comp)
{ return _Iter_comp_val<_Compare>(_GLIBCXX_MOVE(__comp)); }
template<typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline _Iter_comp_val<_Compare>
__iter_comp_val(_Iter_comp_iter<_Compare> __comp)
{ return _Iter_comp_val<_Compare>(_GLIBCXX_MOVE(__comp)); }
@@ -192,17 +211,20 @@ namespace __ops
{
_Compare _M_comp;
+ _GLIBCXX20_CONSTEXPR
explicit
_Val_comp_iter(_Compare __comp)
: _M_comp(_GLIBCXX_MOVE(__comp))
{ }
+ _GLIBCXX20_CONSTEXPR
explicit
_Val_comp_iter(const _Iter_comp_iter<_Compare>& __comp)
: _M_comp(__comp._M_comp)
{ }
#if __cplusplus >= 201103L
+ _GLIBCXX20_CONSTEXPR
explicit
_Val_comp_iter(_Iter_comp_iter<_Compare>&& __comp)
: _M_comp(std::move(__comp._M_comp))
@@ -210,17 +232,20 @@ namespace __ops
#endif
template<typename _Value, typename _Iterator>
+ _GLIBCXX20_CONSTEXPR
bool
operator()(_Value& __val, _Iterator __it)
{ return bool(_M_comp(__val, *__it)); }
};
template<typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline _Val_comp_iter<_Compare>
__val_comp_iter(_Compare __comp)
{ return _Val_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); }
template<typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline _Val_comp_iter<_Compare>
__val_comp_iter(_Iter_comp_iter<_Compare> __comp)
{ return _Val_comp_iter<_Compare>(_GLIBCXX_MOVE(__comp)); }
@@ -230,18 +255,21 @@ namespace __ops
{
_Value& _M_value;
+ _GLIBCXX20_CONSTEXPR
explicit
_Iter_equals_val(_Value& __value)
: _M_value(__value)
{ }
template<typename _Iterator>
+ _GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator __it)
{ return *__it == _M_value; }
};
template<typename _Value>
+ _GLIBCXX20_CONSTEXPR
inline _Iter_equals_val<_Value>
__iter_equals_val(_Value& __val)
{ return _Iter_equals_val<_Value>(__val); }
@@ -251,18 +279,21 @@ namespace __ops
{
_Iterator1 _M_it1;
+ _GLIBCXX20_CONSTEXPR
explicit
_Iter_equals_iter(_Iterator1 __it1)
: _M_it1(__it1)
{ }
template<typename _Iterator2>
+ _GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator2 __it2)
{ return *__it2 == *_M_it1; }
};
template<typename _Iterator>
+ _GLIBCXX20_CONSTEXPR
inline _Iter_equals_iter<_Iterator>
__iter_comp_iter(_Iter_equal_to_iter, _Iterator __it)
{ return _Iter_equals_iter<_Iterator>(__it); }
@@ -272,18 +303,21 @@ namespace __ops
{
_Predicate _M_pred;
+ _GLIBCXX20_CONSTEXPR
explicit
_Iter_pred(_Predicate __pred)
: _M_pred(_GLIBCXX_MOVE(__pred))
{ }
template<typename _Iterator>
+ _GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator __it)
{ return bool(_M_pred(*__it)); }
};
template<typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
inline _Iter_pred<_Predicate>
__pred_iter(_Predicate __pred)
{ return _Iter_pred<_Predicate>(_GLIBCXX_MOVE(__pred)); }
@@ -294,11 +328,13 @@ namespace __ops
_Compare _M_comp;
_Value& _M_value;
+ _GLIBCXX20_CONSTEXPR
_Iter_comp_to_val(_Compare __comp, _Value& __value)
: _M_comp(_GLIBCXX_MOVE(__comp)), _M_value(__value)
{ }
template<typename _Iterator>
+ _GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator __it)
{ return bool(_M_comp(*__it, _M_value)); }
@@ -306,6 +342,7 @@ namespace __ops
template<typename _Compare, typename _Value>
_Iter_comp_to_val<_Compare, _Value>
+ _GLIBCXX20_CONSTEXPR
__iter_comp_val(_Compare __comp, _Value &__val)
{
return _Iter_comp_to_val<_Compare, _Value>(_GLIBCXX_MOVE(__comp), __val);
@@ -317,17 +354,20 @@ namespace __ops
_Compare _M_comp;
_Iterator1 _M_it1;
+ _GLIBCXX20_CONSTEXPR
_Iter_comp_to_iter(_Compare __comp, _Iterator1 __it1)
: _M_comp(_GLIBCXX_MOVE(__comp)), _M_it1(__it1)
{ }
template<typename _Iterator2>
+ _GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator2 __it2)
{ return bool(_M_comp(*__it2, *_M_it1)); }
};
template<typename _Compare, typename _Iterator>
+ _GLIBCXX20_CONSTEXPR
inline _Iter_comp_to_iter<_Compare, _Iterator>
__iter_comp_iter(_Iter_comp_iter<_Compare> __comp, _Iterator __it)
{
@@ -340,18 +380,21 @@ namespace __ops
{
_Predicate _M_pred;
+ _GLIBCXX20_CONSTEXPR
explicit
_Iter_negate(_Predicate __pred)
: _M_pred(_GLIBCXX_MOVE(__pred))
{ }
template<typename _Iterator>
+ _GLIBCXX20_CONSTEXPR
bool
operator()(_Iterator __it)
{ return !bool(_M_pred(*__it)); }
};
template<typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
inline _Iter_negate<_Predicate>
__negate(_Iter_pred<_Predicate> __pred)
{ return _Iter_negate<_Predicate>(_GLIBCXX_MOVE(__pred._M_pred)); }
diff --git a/libstdc++-v3/include/bits/std_function.h b/libstdc++-v3/include/bits/std_function.h
index 5733bf5..42f8787 100644
--- a/libstdc++-v3/include/bits/std_function.h
+++ b/libstdc++-v3/include/bits/std_function.h
@@ -293,10 +293,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
};
- template<typename _From, typename _To>
- using __check_func_return_type
- = __or_<is_void<_To>, is_same<_From, _To>, is_convertible<_From, _To>>;
-
/**
* @brief Primary class template for std::function.
* @ingroup functors
@@ -309,8 +305,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private _Function_base
{
template<typename _Func,
- typename _Res2 = typename result_of<_Func&(_ArgTypes...)>::type>
- struct _Callable : __check_func_return_type<_Res2, _Res> { };
+ typename _Res2 = __invoke_result<_Func&, _ArgTypes...>>
+ struct _Callable
+ : __is_invocable_impl<_Res2, _Res>::type
+ { };
// Used so the return type convertibility checks aren't done when
// performing overload resolution for copy construction/assignment.
diff --git a/libstdc++-v3/include/bits/stl_algo.h b/libstdc++-v3/include/bits/stl_algo.h
index ac21c55..bece933 100644
--- a/libstdc++-v3/include/bits/stl_algo.h
+++ b/libstdc++-v3/include/bits/stl_algo.h
@@ -74,6 +74,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Swaps the median value of *__a, *__b and *__c under __comp to *__result
template<typename _Iterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
__move_median_to_first(_Iterator __result,_Iterator __a, _Iterator __b,
_Iterator __c, _Compare __comp)
@@ -97,6 +98,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// This is an overload used by find algos for the Input Iterator case.
template<typename _InputIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
inline _InputIterator
__find_if(_InputIterator __first, _InputIterator __last,
_Predicate __pred, input_iterator_tag)
@@ -108,6 +110,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// This is an overload used by find algos for the RAI case.
template<typename _RandomAccessIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_RandomAccessIterator
__find_if(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Predicate __pred, random_access_iterator_tag)
@@ -155,6 +158,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _Iterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
inline _Iterator
__find_if(_Iterator __first, _Iterator __last, _Predicate __pred)
{
@@ -164,6 +168,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Provided for stable_partition to use.
template<typename _InputIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
inline _InputIterator
__find_if_not(_InputIterator __first, _InputIterator __last,
_Predicate __pred)
@@ -177,6 +182,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// remaining range length instead of comparing against an end
/// iterator.
template<typename _InputIterator, typename _Predicate, typename _Distance>
+ _GLIBCXX20_CONSTEXPR
_InputIterator
__find_if_not_n(_InputIterator __first, _Distance& __len, _Predicate __pred)
{
@@ -201,6 +207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _ForwardIterator1, typename _ForwardIterator2,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_ForwardIterator1
__search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2,
@@ -217,7 +224,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__gnu_cxx::__ops::__iter_comp_iter(__predicate, __first2));
// General case.
- _ForwardIterator2 __p;
_ForwardIterator1 __current = __first1;
for (;;)
@@ -229,7 +235,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__first1 == __last1)
return __last1;
- __p = __p1;
+ _ForwardIterator2 __p = __p1;
__current = __first1;
if (++__current == __last1)
return __last1;
@@ -253,6 +259,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _ForwardIterator, typename _Integer,
typename _UnaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_ForwardIterator
__search_n_aux(_ForwardIterator __first, _ForwardIterator __last,
_Integer __count, _UnaryPredicate __unary_pred,
@@ -285,6 +292,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _RandomAccessIter, typename _Integer,
typename _UnaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_RandomAccessIter
__search_n_aux(_RandomAccessIter __first, _RandomAccessIter __last,
_Integer __count, _UnaryPredicate __unary_pred,
@@ -315,6 +323,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _ForwardIterator, typename _Integer,
typename _UnaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_ForwardIterator
__search_n(_ForwardIterator __first, _ForwardIterator __last,
_Integer __count,
@@ -333,6 +342,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// find_end for forward iterators.
template<typename _ForwardIterator1, typename _ForwardIterator2,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_ForwardIterator1
__find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2,
@@ -361,6 +371,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// find_end for bidirectional iterators (much faster).
template<typename _BidirectionalIterator1, typename _BidirectionalIterator2,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_BidirectionalIterator1
__find_end(_BidirectionalIterator1 __first1,
_BidirectionalIterator1 __last1,
@@ -421,6 +432,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* [__first1,__last1-(__last2-__first2))
*/
template<typename _ForwardIterator1, typename _ForwardIterator2>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator1
find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2)
@@ -470,6 +482,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _ForwardIterator1, typename _ForwardIterator2,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator1
find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2,
@@ -504,6 +517,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @p [__first,__last), and false otherwise.
*/
template<typename _InputIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
inline bool
all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
{ return __last == std::find_if_not(__first, __last, __pred); }
@@ -521,6 +535,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @p [__first,__last), and false otherwise.
*/
template<typename _InputIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
inline bool
none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
{ return __last == _GLIBCXX_STD_A::find_if(__first, __last, __pred); }
@@ -539,6 +554,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* otherwise.
*/
template<typename _InputIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
inline bool
any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred)
{ return !std::none_of(__first, __last, __pred); }
@@ -554,6 +570,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* such that @p __pred(*i) is false, or @p __last if no such iterator exists.
*/
template<typename _InputIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
inline _InputIterator
find_if_not(_InputIterator __first, _InputIterator __last,
_Predicate __pred)
@@ -578,6 +595,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* do not.
*/
template<typename _InputIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
inline bool
is_partitioned(_InputIterator __first, _InputIterator __last,
_Predicate __pred)
@@ -599,6 +617,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* and @p none_of(mid, __last, __pred) are both true.
*/
template<typename _ForwardIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_ForwardIterator
partition_point(_ForwardIterator __first, _ForwardIterator __last,
_Predicate __pred)
@@ -615,13 +634,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_DistanceType;
_DistanceType __len = std::distance(__first, __last);
- _DistanceType __half;
- _ForwardIterator __middle;
while (__len > 0)
{
- __half = __len >> 1;
- __middle = __first;
+ _DistanceType __half = __len >> 1;
+ _ForwardIterator __middle = __first;
std::advance(__middle, __half);
if (__pred(*__middle))
{
@@ -638,6 +655,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _InputIterator, typename _OutputIterator,
typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_OutputIterator
__remove_copy_if(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _Predicate __pred)
@@ -666,6 +684,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* are copied is unchanged.
*/
template<typename _InputIterator, typename _OutputIterator, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
remove_copy(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, const _Tp& __value)
@@ -699,6 +718,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _InputIterator, typename _OutputIterator,
typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
remove_copy_if(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _Predicate __pred)
@@ -733,6 +753,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _InputIterator, typename _OutputIterator,
typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_OutputIterator
copy_if(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _Predicate __pred)
@@ -755,6 +776,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _InputIterator, typename _Size, typename _OutputIterator>
+ _GLIBCXX20_CONSTEXPR
_OutputIterator
__copy_n(_InputIterator __first, _Size __n,
_OutputIterator __result, input_iterator_tag)
@@ -776,6 +798,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _RandomAccessIterator, typename _Size,
typename _OutputIterator>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
__copy_n(_RandomAccessIterator __first, _Size __n,
_OutputIterator __result, random_access_iterator_tag)
@@ -795,6 +818,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* optimizations such as unrolling).
*/
template<typename _InputIterator, typename _Size, typename _OutputIterator>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
copy_n(_InputIterator __first, _Size __n, _OutputIterator __result)
{
@@ -824,6 +848,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _InputIterator, typename _OutputIterator1,
typename _OutputIterator2, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
pair<_OutputIterator1, _OutputIterator2>
partition_copy(_InputIterator __first, _InputIterator __last,
_OutputIterator1 __out_true, _OutputIterator2 __out_false,
@@ -856,6 +881,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
template<typename _ForwardIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_ForwardIterator
__remove_if(_ForwardIterator __first, _ForwardIterator __last,
_Predicate __pred)
@@ -892,6 +918,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* are still present, but their value is unspecified.
*/
template<typename _ForwardIterator, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
remove(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __value)
@@ -925,6 +952,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* are still present, but their value is unspecified.
*/
template<typename _ForwardIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
remove_if(_ForwardIterator __first, _ForwardIterator __last,
_Predicate __pred)
@@ -941,6 +969,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _ForwardIterator, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_ForwardIterator
__adjacent_find(_ForwardIterator __first, _ForwardIterator __last,
_BinaryPredicate __binary_pred)
@@ -958,6 +987,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _ForwardIterator, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_ForwardIterator
__unique(_ForwardIterator __first, _ForwardIterator __last,
_BinaryPredicate __binary_pred)
@@ -991,6 +1021,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* are still present, but their value is unspecified.
*/
template<typename _ForwardIterator>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
unique(_ForwardIterator __first, _ForwardIterator __last)
{
@@ -1021,6 +1052,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* are still present, but their value is unspecified.
*/
template<typename _ForwardIterator, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
unique(_ForwardIterator __first, _ForwardIterator __last,
_BinaryPredicate __binary_pred)
@@ -1045,6 +1077,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _ForwardIterator, typename _OutputIterator,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_OutputIterator
__unique_copy(_ForwardIterator __first, _ForwardIterator __last,
_OutputIterator __result, _BinaryPredicate __binary_pred,
@@ -1074,6 +1107,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _InputIterator, typename _OutputIterator,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_OutputIterator
__unique_copy(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _BinaryPredicate __binary_pred,
@@ -1106,6 +1140,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _InputIterator, typename _ForwardIterator,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_ForwardIterator
__unique_copy(_InputIterator __first, _InputIterator __last,
_ForwardIterator __result, _BinaryPredicate __binary_pred,
@@ -1128,6 +1163,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* overloaded for bidirectional iterators.
*/
template<typename _BidirectionalIterator>
+ _GLIBCXX20_CONSTEXPR
void
__reverse(_BidirectionalIterator __first, _BidirectionalIterator __last,
bidirectional_iterator_tag)
@@ -1148,6 +1184,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* overloaded for random access iterators.
*/
template<typename _RandomAccessIterator>
+ _GLIBCXX20_CONSTEXPR
void
__reverse(_RandomAccessIterator __first, _RandomAccessIterator __last,
random_access_iterator_tag)
@@ -1176,6 +1213,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* swaps @p *(__first+i) and @p *(__last-(i+1))
*/
template<typename _BidirectionalIterator>
+ _GLIBCXX20_CONSTEXPR
inline void
reverse(_BidirectionalIterator __first, _BidirectionalIterator __last)
{
@@ -1203,6 +1241,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* [__result,__result+(__last-__first)) must not overlap.
*/
template<typename _BidirectionalIterator, typename _OutputIterator>
+ _GLIBCXX20_CONSTEXPR
_OutputIterator
reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last,
_OutputIterator __result)
@@ -1228,6 +1267,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* It returns the greatest common divisor of two integer values.
*/
template<typename _EuclideanRingElement>
+ _GLIBCXX20_CONSTEXPR
_EuclideanRingElement
__gcd(_EuclideanRingElement __m, _EuclideanRingElement __n)
{
@@ -1245,6 +1285,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// This is a helper function for the rotate algorithm.
template<typename _ForwardIterator>
+ _GLIBCXX20_CONSTEXPR
_ForwardIterator
__rotate(_ForwardIterator __first,
_ForwardIterator __middle,
@@ -1286,6 +1327,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// This is a helper function for the rotate algorithm.
template<typename _BidirectionalIterator>
+ _GLIBCXX20_CONSTEXPR
_BidirectionalIterator
__rotate(_BidirectionalIterator __first,
_BidirectionalIterator __middle,
@@ -1324,6 +1366,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// This is a helper function for the rotate algorithm.
template<typename _RandomAccessIterator>
+ _GLIBCXX20_CONSTEXPR
_RandomAccessIterator
__rotate(_RandomAccessIterator __first,
_RandomAccessIterator __middle,
@@ -1430,6 +1473,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* for each @p n in the range @p [0,__last-__first).
*/
template<typename _ForwardIterator>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
rotate(_ForwardIterator __first, _ForwardIterator __middle,
_ForwardIterator __last)
@@ -1467,6 +1511,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* for each @p n in the range @p [0,__last-__first).
*/
template<typename _ForwardIterator, typename _OutputIterator>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
rotate_copy(_ForwardIterator __first, _ForwardIterator __middle,
_ForwardIterator __last, _OutputIterator __result)
@@ -1484,6 +1529,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// This is a helper function...
template<typename _ForwardIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_ForwardIterator
__partition(_ForwardIterator __first, _ForwardIterator __last,
_Predicate __pred, forward_iterator_tag)
@@ -1509,6 +1555,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// This is a helper function...
template<typename _BidirectionalIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_BidirectionalIterator
__partition(_BidirectionalIterator __first, _BidirectionalIterator __last,
_Predicate __pred, bidirectional_iterator_tag)
@@ -1663,6 +1710,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// This is a helper function for the sort routines.
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
__heap_select(_RandomAccessIterator __first,
_RandomAccessIterator __middle,
@@ -1678,6 +1726,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _InputIterator, typename _RandomAccessIterator,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_RandomAccessIterator
__partial_sort_copy(_InputIterator __first, _InputIterator __last,
_RandomAccessIterator __result_first,
@@ -1732,6 +1781,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* The value returned is @p __result_first+N.
*/
template<typename _InputIterator, typename _RandomAccessIterator>
+ _GLIBCXX20_CONSTEXPR
inline _RandomAccessIterator
partial_sort_copy(_InputIterator __first, _InputIterator __last,
_RandomAccessIterator __result_first,
@@ -1782,6 +1832,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _InputIterator, typename _RandomAccessIterator,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline _RandomAccessIterator
partial_sort_copy(_InputIterator __first, _InputIterator __last,
_RandomAccessIterator __result_first,
@@ -1816,6 +1867,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// This is a helper function for the sort routine.
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
__unguarded_linear_insert(_RandomAccessIterator __last,
_Compare __comp)
@@ -1835,6 +1887,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// This is a helper function for the sort routine.
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
__insertion_sort(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
@@ -1858,6 +1911,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// This is a helper function for the sort routine.
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline void
__unguarded_insertion_sort(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
@@ -1875,6 +1929,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// This is a helper function for the sort routine.
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
__final_insertion_sort(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
@@ -1891,6 +1946,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// This is a helper function...
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_RandomAccessIterator
__unguarded_partition(_RandomAccessIterator __first,
_RandomAccessIterator __last,
@@ -1912,6 +1968,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// This is a helper function...
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline _RandomAccessIterator
__unguarded_partition_pivot(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
@@ -1923,6 +1980,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline void
__partial_sort(_RandomAccessIterator __first,
_RandomAccessIterator __middle,
@@ -1935,6 +1993,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// This is a helper function for the sort routine.
template<typename _RandomAccessIterator, typename _Size, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
__introsort_loop(_RandomAccessIterator __first,
_RandomAccessIterator __last,
@@ -1958,6 +2017,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// sort
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline void
__sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
@@ -1972,6 +2032,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _RandomAccessIterator, typename _Size, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
__introselect(_RandomAccessIterator __first, _RandomAccessIterator __nth,
_RandomAccessIterator __last, _Size __depth_limit,
@@ -2018,6 +2079,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* the function used for the initial sort.
*/
template<typename _ForwardIterator, typename _Tp, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
lower_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val, _Compare __comp)
@@ -2034,6 +2096,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _ForwardIterator, typename _Tp, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_ForwardIterator
__upper_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val, _Compare __comp)
@@ -2072,6 +2135,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @ingroup binary_search_algorithms
*/
template<typename _ForwardIterator, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
upper_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val)
@@ -2102,6 +2166,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* the function used for the initial sort.
*/
template<typename _ForwardIterator, typename _Tp, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
upper_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val, _Compare __comp)
@@ -2119,6 +2184,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _ForwardIterator, typename _Tp,
typename _CompareItTp, typename _CompareTpIt>
+ _GLIBCXX20_CONSTEXPR
pair<_ForwardIterator, _ForwardIterator>
__equal_range(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val,
@@ -2173,6 +2239,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* but does not actually call those functions.
*/
template<typename _ForwardIterator, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline pair<_ForwardIterator, _ForwardIterator>
equal_range(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val)
@@ -2209,6 +2276,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* but does not actually call those functions.
*/
template<typename _ForwardIterator, typename _Tp, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline pair<_ForwardIterator, _ForwardIterator>
equal_range(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val, _Compare __comp)
@@ -2242,6 +2310,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* that, use std::find or a container's specialized find member functions.
*/
template<typename _ForwardIterator, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
bool
binary_search(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val)
@@ -2275,6 +2344,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* the function used for the initial sort.
*/
template<typename _ForwardIterator, typename _Tp, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
binary_search(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val, _Compare __comp)
@@ -2679,6 +2749,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _RandomAccessIterator, typename _Distance,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
__chunk_insertion_sort(_RandomAccessIterator __first,
_RandomAccessIterator __last,
@@ -2778,6 +2849,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _InputIterator1, typename _InputIterator2,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
__includes(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -2816,6 +2888,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* returned.
*/
template<typename _InputIterator1, typename _InputIterator2>
+ _GLIBCXX20_CONSTEXPR
inline bool
includes(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2)
@@ -2861,6 +2934,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline bool
includes(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -2895,6 +2969,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// max_element
template<typename _BidirectionalIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
__next_permutation(_BidirectionalIterator __first,
_BidirectionalIterator __last, _Compare __comp)
@@ -2944,6 +3019,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* is the largest of the set, the smallest is generated and false returned.
*/
template<typename _BidirectionalIterator>
+ _GLIBCXX20_CONSTEXPR
inline bool
next_permutation(_BidirectionalIterator __first,
_BidirectionalIterator __last)
@@ -2976,6 +3052,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* smallest is generated and false returned.
*/
template<typename _BidirectionalIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline bool
next_permutation(_BidirectionalIterator __first,
_BidirectionalIterator __last, _Compare __comp)
@@ -2994,6 +3071,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _BidirectionalIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
__prev_permutation(_BidirectionalIterator __first,
_BidirectionalIterator __last, _Compare __comp)
@@ -3044,6 +3122,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* returned.
*/
template<typename _BidirectionalIterator>
+ _GLIBCXX20_CONSTEXPR
inline bool
prev_permutation(_BidirectionalIterator __first,
_BidirectionalIterator __last)
@@ -3076,6 +3155,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* the largest is generated and false returned.
*/
template<typename _BidirectionalIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline bool
prev_permutation(_BidirectionalIterator __first,
_BidirectionalIterator __last, _Compare __comp)
@@ -3098,6 +3178,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _InputIterator, typename _OutputIterator,
typename _Predicate, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_OutputIterator
__replace_copy_if(_InputIterator __first, _InputIterator __last,
_OutputIterator __result,
@@ -3126,6 +3207,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* equal to @p __old_value with @p __new_value.
*/
template<typename _InputIterator, typename _OutputIterator, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
replace_copy(_InputIterator __first, _InputIterator __last,
_OutputIterator __result,
@@ -3161,6 +3243,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _InputIterator, typename _OutputIterator,
typename _Predicate, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
replace_copy_if(_InputIterator __first, _InputIterator __last,
_OutputIterator __result,
@@ -3180,6 +3263,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _InputIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
typename iterator_traits<_InputIterator>::difference_type
__count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
{
@@ -3199,6 +3283,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @return True if the elements are sorted, false otherwise.
*/
template<typename _ForwardIterator>
+ _GLIBCXX20_CONSTEXPR
inline bool
is_sorted(_ForwardIterator __first, _ForwardIterator __last)
{ return std::is_sorted_until(__first, __last) == __last; }
@@ -3213,12 +3298,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @return True if the elements are sorted, false otherwise.
*/
template<typename _ForwardIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline bool
is_sorted(_ForwardIterator __first, _ForwardIterator __last,
_Compare __comp)
{ return std::is_sorted_until(__first, __last, __comp) == __last; }
template<typename _ForwardIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_ForwardIterator
__is_sorted_until(_ForwardIterator __first, _ForwardIterator __last,
_Compare __comp)
@@ -3242,6 +3329,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* for which the range [__first, i) is sorted.
*/
template<typename _ForwardIterator>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last)
{
@@ -3266,6 +3354,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* for which the range [__first, i) is sorted.
*/
template<typename _ForwardIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
is_sorted_until(_ForwardIterator __first, _ForwardIterator __last,
_Compare __comp)
@@ -3484,6 +3573,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _ForwardIterator1, typename _ForwardIterator2,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
bool
__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _BinaryPredicate __pred)
@@ -3532,6 +3622,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* returns true; otherwise, returns false.
*/
template<typename _ForwardIterator1, typename _ForwardIterator2>
+ _GLIBCXX20_CONSTEXPR
inline bool
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2)
@@ -3564,6 +3655,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _ForwardIterator1, typename _ForwardIterator2,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
inline bool
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _BinaryPredicate __pred)
@@ -3583,6 +3675,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus > 201103L
template<typename _ForwardIterator1, typename _ForwardIterator2,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
bool
__is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2,
@@ -3656,6 +3749,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* otherwise, returns false.
*/
template<typename _ForwardIterator1, typename _ForwardIterator2>
+ _GLIBCXX20_CONSTEXPR
inline bool
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2)
@@ -3684,6 +3778,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _ForwardIterator1, typename _ForwardIterator2,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
inline bool
is_permutation(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2,
@@ -3866,6 +3961,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* If @p __f has a return value it is ignored.
*/
template<typename _InputIterator, typename _Function>
+ _GLIBCXX20_CONSTEXPR
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
{
@@ -3920,6 +4016,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* such that @c *i == @p __val, or @p __last if no such iterator exists.
*/
template<typename _InputIterator, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline _InputIterator
find(_InputIterator __first, _InputIterator __last,
const _Tp& __val)
@@ -3944,6 +4041,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* such that @p __pred(*i) is true, or @p __last if no such iterator exists.
*/
template<typename _InputIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
inline _InputIterator
find_if(_InputIterator __first, _InputIterator __last,
_Predicate __pred)
@@ -3975,6 +4073,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* otherwise returns @p __last1.
*/
template<typename _InputIterator, typename _ForwardIterator>
+ _GLIBCXX20_CONSTEXPR
_InputIterator
find_first_of(_InputIterator __first1, _InputIterator __last1,
_ForwardIterator __first2, _ForwardIterator __last2)
@@ -4016,6 +4115,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator, typename _ForwardIterator,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_InputIterator
find_first_of(_InputIterator __first1, _InputIterator __last1,
_ForwardIterator __first2, _ForwardIterator __last2,
@@ -4047,6 +4147,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* or @p __last if no such iterator exists.
*/
template<typename _ForwardIterator>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
adjacent_find(_ForwardIterator __first, _ForwardIterator __last)
{
@@ -4072,6 +4173,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* exists.
*/
template<typename _ForwardIterator, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
adjacent_find(_ForwardIterator __first, _ForwardIterator __last,
_BinaryPredicate __binary_pred)
@@ -4097,6 +4199,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* for which @c *i == @p __value
*/
template<typename _InputIterator, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline typename iterator_traits<_InputIterator>::difference_type
count(_InputIterator __first, _InputIterator __last, const _Tp& __value)
{
@@ -4120,6 +4223,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* for which @p __pred(*i) is true.
*/
template<typename _InputIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
inline typename iterator_traits<_InputIterator>::difference_type
count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred)
{
@@ -4160,6 +4264,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* @p [__first1,__last1-(__last2-__first2))
*/
template<typename _ForwardIterator1, typename _ForwardIterator2>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator1
search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2)
@@ -4200,6 +4305,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _ForwardIterator1, typename _ForwardIterator2,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator1
search(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2, _ForwardIterator2 __last2,
@@ -4234,6 +4340,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* equal to @p __val.
*/
template<typename _ForwardIterator, typename _Integer, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
search_n(_ForwardIterator __first, _ForwardIterator __last,
_Integer __count, const _Tp& __val)
@@ -4268,6 +4375,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _ForwardIterator, typename _Integer, typename _Tp,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
search_n(_ForwardIterator __first, _ForwardIterator __last,
_Integer __count, const _Tp& __val,
@@ -4316,6 +4424,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator, typename _OutputIterator,
typename _UnaryOperation>
+ _GLIBCXX20_CONSTEXPR
_OutputIterator
transform(_InputIterator __first, _InputIterator __last,
_OutputIterator __result, _UnaryOperation __unary_op)
@@ -4353,6 +4462,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator, typename _BinaryOperation>
+ _GLIBCXX20_CONSTEXPR
_OutputIterator
transform(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _OutputIterator __result,
@@ -4385,6 +4495,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* @p __old_value then the assignment @c *i = @p __new_value is performed.
*/
template<typename _ForwardIterator, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
void
replace(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __old_value, const _Tp& __new_value)
@@ -4417,6 +4528,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* is true then the assignment @c *i = @p __new_value is performed.
*/
template<typename _ForwardIterator, typename _Predicate, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
void
replace_if(_ForwardIterator __first, _ForwardIterator __last,
_Predicate __pred, const _Tp& __new_value)
@@ -4449,6 +4561,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* @p [__first,__last).
*/
template<typename _ForwardIterator, typename _Generator>
+ _GLIBCXX20_CONSTEXPR
void
generate(_ForwardIterator __first, _ForwardIterator __last,
_Generator __gen)
@@ -4482,6 +4595,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
// DR 865. More algorithms that throw away information
// DR 426. search_n(), fill_n(), and generate_n() with negative n
template<typename _OutputIterator, typename _Size, typename _Generator>
+ _GLIBCXX20_CONSTEXPR
_OutputIterator
generate_n(_OutputIterator __first, _Size __n, _Generator __gen)
{
@@ -4519,6 +4633,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* Assignable?
*/
template<typename _InputIterator, typename _OutputIterator>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
unique_copy(_InputIterator __first, _InputIterator __last,
_OutputIterator __result)
@@ -4560,6 +4675,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator, typename _OutputIterator,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
unique_copy(_InputIterator __first, _InputIterator __last,
_OutputIterator __result,
@@ -4667,6 +4783,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* @p stable_partition() if this is needed.
*/
template<typename _ForwardIterator, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
partition(_ForwardIterator __first, _ForwardIterator __last,
_Predicate __pred)
@@ -4700,6 +4817,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* the range @p [__middle,__last) then *j<*i and *k<*i are both false.
*/
template<typename _RandomAccessIterator>
+ _GLIBCXX20_CONSTEXPR
inline void
partial_sort(_RandomAccessIterator __first,
_RandomAccessIterator __middle,
@@ -4738,6 +4856,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* are both false.
*/
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline void
partial_sort(_RandomAccessIterator __first,
_RandomAccessIterator __middle,
@@ -4774,6 +4893,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* holds that *j < *i is false.
*/
template<typename _RandomAccessIterator>
+ _GLIBCXX20_CONSTEXPR
inline void
nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth,
_RandomAccessIterator __last)
@@ -4813,6 +4933,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* holds that @p __comp(*j,*i) is false.
*/
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline void
nth_element(_RandomAccessIterator __first, _RandomAccessIterator __nth,
_RandomAccessIterator __last, _Compare __comp)
@@ -4850,6 +4971,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* @p stable_sort() if this is needed.
*/
template<typename _RandomAccessIterator>
+ _GLIBCXX20_CONSTEXPR
inline void
sort(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
@@ -4880,6 +5002,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* @p stable_sort() if this is needed.
*/
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline void
sort(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
@@ -4898,6 +5021,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_OutputIterator
__merge(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -4942,6 +5066,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
merge(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -4992,6 +5117,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
merge(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -5109,6 +5235,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_OutputIterator
__set_union(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -5159,6 +5286,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
set_union(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -5209,6 +5337,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
set_union(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -5240,6 +5369,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_OutputIterator
__set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -5280,6 +5410,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -5329,6 +5460,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
set_intersection(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -5358,6 +5490,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_OutputIterator
__set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -5402,6 +5535,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -5453,6 +5587,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
set_difference(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -5482,6 +5617,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_OutputIterator
__set_symmetric_difference(_InputIterator1 __first1,
_InputIterator1 __last1,
@@ -5532,6 +5668,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -5583,6 +5720,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _OutputIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline _OutputIterator
set_symmetric_difference(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index 58bfb6c..36bb9cc 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -77,6 +77,57 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ /*
+ * A constexpr wrapper for __builtin_memmove.
+ * @param __num The number of elements of type _Tp (not bytes).
+ */
+ template<bool _IsMove, typename _Tp>
+ _GLIBCXX14_CONSTEXPR
+ inline void*
+ __memmove(_Tp* __dst, const _Tp* __src, size_t __num)
+ {
+#ifdef __cpp_lib_is_constant_evaluated
+ if (std::is_constant_evaluated())
+ {
+ for(; __num > 0; --__num)
+ {
+ if constexpr (_IsMove)
+ *__dst = std::move(*__src);
+ else
+ *__dst = *__src;
+ ++__src;
+ ++__dst;
+ }
+ return __dst;
+ }
+ else
+#endif
+ return __builtin_memmove(__dst, __src, sizeof(_Tp) * __num);
+ return __dst;
+ }
+
+ /*
+ * A constexpr wrapper for __builtin_memcmp.
+ * @param __num The number of elements of type _Tp (not bytes).
+ */
+ template<typename _Tp>
+ _GLIBCXX14_CONSTEXPR
+ inline int
+ __memcmp(const _Tp* __first1, const _Tp* __first2, size_t __num)
+ {
+#ifdef __cpp_lib_is_constant_evaluated
+ if (std::is_constant_evaluated())
+ {
+ for(; __num > 0; ++__first1, ++__first2, --__num)
+ if (*__first1 != *__first2)
+ return *__first1 < *__first2 ? -1 : 1;
+ return 0;
+ }
+ else
+#endif
+ return __builtin_memcmp(__first1, __first2, sizeof(_Tp) * __num);
+ }
+
#if __cplusplus < 201103L
// See http://gcc.gnu.org/ml/libstdc++/2004-08/msg00167.html: in a
// nutshell, we are partially implementing the resolution of DR 187,
@@ -85,6 +136,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __iter_swap
{
template<typename _ForwardIterator1, typename _ForwardIterator2>
+ _GLIBCXX20_CONSTEXPR
static void
iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b)
{
@@ -100,6 +152,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __iter_swap<true>
{
template<typename _ForwardIterator1, typename _ForwardIterator2>
+ _GLIBCXX20_CONSTEXPR
static void
iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b)
{
@@ -119,6 +172,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* iterators themselves.
*/
template<typename _ForwardIterator1, typename _ForwardIterator2>
+ _GLIBCXX20_CONSTEXPR
inline void
iter_swap(_ForwardIterator1 __a, _ForwardIterator2 __b)
{
@@ -165,6 +219,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* The ranges must not overlap.
*/
template<typename _ForwardIterator1, typename _ForwardIterator2>
+ _GLIBCXX20_CONSTEXPR
_ForwardIterator2
swap_ranges(_ForwardIterator1 __first1, _ForwardIterator1 __last1,
_ForwardIterator2 __first2)
@@ -276,6 +331,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Fallback implementation of the function in bits/stl_iterator.h used to
// remove the __normal_iterator wrapper. See copy, fill, ...
template<typename _Iterator>
+ _GLIBCXX20_CONSTEXPR
inline _Iterator
__niter_base(_Iterator __it)
_GLIBCXX_NOEXCEPT_IF(std::is_nothrow_copy_constructible<_Iterator>::value)
@@ -285,12 +341,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// __normal_iterator back again (this assumes that __normal_iterator
// is only used to wrap random access iterators, like pointers).
template<typename _From, typename _To>
+ _GLIBCXX20_CONSTEXPR
inline _From
__niter_wrap(_From __from, _To __res)
{ return __from + (__res - std::__niter_base(__from)); }
// No need to wrap, iterator already has the right type.
template<typename _Iterator>
+ _GLIBCXX20_CONSTEXPR
inline _Iterator
__niter_wrap(const _Iterator&, _Iterator __res)
{ return __res; }
@@ -305,6 +363,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __copy_move
{
template<typename _II, typename _OI>
+ _GLIBCXX20_CONSTEXPR
static _OI
__copy_m(_II __first, _II __last, _OI __result)
{
@@ -319,6 +378,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __copy_move<true, false, _Category>
{
template<typename _II, typename _OI>
+ _GLIBCXX20_CONSTEXPR
static _OI
__copy_m(_II __first, _II __last, _OI __result)
{
@@ -333,6 +393,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __copy_move<false, false, random_access_iterator_tag>
{
template<typename _II, typename _OI>
+ _GLIBCXX20_CONSTEXPR
static _OI
__copy_m(_II __first, _II __last, _OI __result)
{
@@ -352,6 +413,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __copy_move<true, false, random_access_iterator_tag>
{
template<typename _II, typename _OI>
+ _GLIBCXX20_CONSTEXPR
static _OI
__copy_m(_II __first, _II __last, _OI __result)
{
@@ -371,6 +433,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __copy_move<_IsMove, true, random_access_iterator_tag>
{
template<typename _Tp>
+ _GLIBCXX20_CONSTEXPR
static _Tp*
__copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result)
{
@@ -383,12 +446,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
const ptrdiff_t _Num = __last - __first;
if (_Num)
- __builtin_memmove(__result, __first, sizeof(_Tp) * _Num);
+ std::__memmove<_IsMove>(__result, __first, _Num);
return __result + _Num;
}
};
template<bool _IsMove, typename _II, typename _OI>
+ _GLIBCXX20_CONSTEXPR
inline _OI
__copy_move_a(_II __first, _II __last, _OI __result)
{
@@ -399,7 +463,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
&& __is_pointer<_II>::__value
&& __is_pointer<_OI>::__value
&& __are_same<_ValueTypeI, _ValueTypeO>::__value);
-
return std::__copy_move<_IsMove, __simple,
_Category>::__copy_m(__first, __last, __result);
}
@@ -434,6 +497,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
istreambuf_iterator<_CharT, char_traits<_CharT> >, _CharT*);
template<bool _IsMove, typename _II, typename _OI>
+ _GLIBCXX20_CONSTEXPR
inline _OI
__copy_move_a2(_II __first, _II __last, _OI __result)
{
@@ -461,6 +525,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* within [first,last).
*/
template<typename _II, typename _OI>
+ _GLIBCXX20_CONSTEXPR
inline _OI
copy(_II __first, _II __last, _OI __result)
{
@@ -493,6 +558,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* within [first,last).
*/
template<typename _II, typename _OI>
+ _GLIBCXX20_CONSTEXPR
inline _OI
move(_II __first, _II __last, _OI __result)
{
@@ -515,6 +581,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __copy_move_backward
{
template<typename _BI1, typename _BI2>
+ _GLIBCXX20_CONSTEXPR
static _BI2
__copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
{
@@ -529,6 +596,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __copy_move_backward<true, false, _Category>
{
template<typename _BI1, typename _BI2>
+ _GLIBCXX20_CONSTEXPR
static _BI2
__copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
{
@@ -543,11 +611,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __copy_move_backward<false, false, random_access_iterator_tag>
{
template<typename _BI1, typename _BI2>
+ _GLIBCXX20_CONSTEXPR
static _BI2
__copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
{
- typename iterator_traits<_BI1>::difference_type __n;
- for (__n = __last - __first; __n > 0; --__n)
+ typename iterator_traits<_BI1>::difference_type
+ __n = __last - __first;
+ for (; __n > 0; --__n)
*--__result = *--__last;
return __result;
}
@@ -558,11 +628,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __copy_move_backward<true, false, random_access_iterator_tag>
{
template<typename _BI1, typename _BI2>
+ _GLIBCXX20_CONSTEXPR
static _BI2
__copy_move_b(_BI1 __first, _BI1 __last, _BI2 __result)
{
- typename iterator_traits<_BI1>::difference_type __n;
- for (__n = __last - __first; __n > 0; --__n)
+ typename iterator_traits<_BI1>::difference_type
+ __n = __last - __first;
+ for (; __n > 0; --__n)
*--__result = std::move(*--__last);
return __result;
}
@@ -573,6 +645,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __copy_move_backward<_IsMove, true, random_access_iterator_tag>
{
template<typename _Tp>
+ _GLIBCXX20_CONSTEXPR
static _Tp*
__copy_move_b(const _Tp* __first, const _Tp* __last, _Tp* __result)
{
@@ -585,12 +658,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
const ptrdiff_t _Num = __last - __first;
if (_Num)
- __builtin_memmove(__result - _Num, __first, sizeof(_Tp) * _Num);
+ std::__memmove<_IsMove>(__result - _Num, __first, _Num);
return __result - _Num;
}
};
template<bool _IsMove, typename _BI1, typename _BI2>
+ _GLIBCXX20_CONSTEXPR
inline _BI2
__copy_move_backward_a(_BI1 __first, _BI1 __last, _BI2 __result)
{
@@ -602,6 +676,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
&& __is_pointer<_BI2>::__value
&& __are_same<_ValueType1, _ValueType2>::__value);
+#ifdef __cpp_lib_is_constant_evaluated
+ if (std::is_constant_evaluated())
+ return std::__copy_move_backward<true, false,
+ _Category>::__copy_move_b(__first, __last,
+ __result);
+#endif
return std::__copy_move_backward<_IsMove, __simple,
_Category>::__copy_move_b(__first,
__last,
@@ -609,6 +689,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<bool _IsMove, typename _BI1, typename _BI2>
+ _GLIBCXX20_CONSTEXPR
inline _BI2
__copy_move_backward_a2(_BI1 __first, _BI1 __last, _BI2 __result)
{
@@ -637,6 +718,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* that the start of the output range may overlap [first,last).
*/
template<typename _BI1, typename _BI2>
+ _GLIBCXX20_CONSTEXPR
inline _BI2
copy_backward(_BI1 __first, _BI1 __last, _BI2 __result)
{
@@ -672,6 +754,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* that the start of the output range may overlap [first,last).
*/
template<typename _BI1, typename _BI2>
+ _GLIBCXX20_CONSTEXPR
inline _BI2
move_backward(_BI1 __first, _BI1 __last, _BI2 __result)
{
@@ -694,6 +777,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
template<typename _ForwardIterator, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline typename
__gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, void>::__type
__fill_a(_ForwardIterator __first, _ForwardIterator __last,
@@ -704,6 +788,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _ForwardIterator, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline typename
__gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, void>::__type
__fill_a(_ForwardIterator __first, _ForwardIterator __last,
@@ -738,6 +823,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* to @c memset or @c wmemset.
*/
template<typename _ForwardIterator, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline void
fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
{
@@ -801,6 +887,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
template<typename _OutputIterator, typename _Size, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline typename
__gnu_cxx::__enable_if<!__is_scalar<_Tp>::__value, _OutputIterator>::__type
__fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value)
@@ -814,6 +901,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _OutputIterator, typename _Size, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline typename
__gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, _OutputIterator>::__type
__fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value)
@@ -828,6 +916,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _Size, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline typename
__gnu_cxx::__enable_if<__is_byte<_Tp>::__value, _Tp*>::__type
__fill_n_a(_Tp* __first, _Size __n, const _Tp& __c)
@@ -854,6 +943,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// DR 865. More algorithms that throw away information
// DR 426. search_n(), fill_n(), and generate_n() with negative n
template<typename _OI, typename _Size, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline _OI
fill_n(_OI __first, _Size __n, const _Tp& __value)
{
@@ -870,6 +960,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __equal
{
template<typename _II1, typename _II2>
+ _GLIBCXX20_CONSTEXPR
static bool
equal(_II1 __first1, _II1 __last1, _II2 __first2)
{
@@ -884,16 +975,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __equal<true>
{
template<typename _Tp>
+ _GLIBCXX20_CONSTEXPR
static bool
equal(const _Tp* __first1, const _Tp* __last1, const _Tp* __first2)
{
if (const size_t __len = (__last1 - __first1))
- return !__builtin_memcmp(__first1, __first2, sizeof(_Tp) * __len);
+ return !std::__memcmp(__first1, __first2, __len);
return true;
}
};
template<typename _II1, typename _II2>
+ _GLIBCXX20_CONSTEXPR
inline bool
__equal_aux(_II1 __first1, _II1 __last1, _II2 __first2)
{
@@ -912,11 +1005,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __lc_rai
{
template<typename _II1, typename _II2>
+ _GLIBCXX20_CONSTEXPR
static _II1
__newlast1(_II1, _II1 __last1, _II2, _II2)
{ return __last1; }
template<typename _II>
+ _GLIBCXX20_CONSTEXPR
static bool
__cnd2(_II __first, _II __last)
{ return __first != __last; }
@@ -926,6 +1021,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __lc_rai<random_access_iterator_tag, random_access_iterator_tag>
{
template<typename _RAI1, typename _RAI2>
+ _GLIBCXX20_CONSTEXPR
static _RAI1
__newlast1(_RAI1 __first1, _RAI1 __last1,
_RAI2 __first2, _RAI2 __last2)
@@ -938,12 +1034,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _RAI>
- static bool
+ static _GLIBCXX20_CONSTEXPR bool
__cnd2(_RAI, _RAI)
{ return true; }
};
template<typename _II1, typename _II2, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
__lexicographical_compare_impl(_II1 __first1, _II1 __last1,
_II2 __first2, _II2 __last2,
@@ -969,11 +1066,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __lexicographical_compare
{
template<typename _II1, typename _II2>
+ _GLIBCXX20_CONSTEXPR
static bool __lc(_II1, _II1, _II2, _II2);
};
template<bool _BoolType>
template<typename _II1, typename _II2>
+ _GLIBCXX20_CONSTEXPR
bool
__lexicographical_compare<_BoolType>::
__lc(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2)
@@ -987,6 +1086,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __lexicographical_compare<true>
{
template<typename _Tp, typename _Up>
+ _GLIBCXX20_CONSTEXPR
static bool
__lc(const _Tp* __first1, const _Tp* __last1,
const _Up* __first2, const _Up* __last2)
@@ -994,13 +1094,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const size_t __len1 = __last1 - __first1;
const size_t __len2 = __last2 - __first2;
if (const size_t __len = std::min(__len1, __len2))
- if (int __result = __builtin_memcmp(__first1, __first2, __len))
+ if (int __result = std::__memcmp(__first1, __first2, __len))
return __result < 0;
return __len1 < __len2;
}
};
template<typename _II1, typename _II2>
+ _GLIBCXX20_CONSTEXPR
inline bool
__lexicographical_compare_aux(_II1 __first1, _II1 __last1,
_II2 __first2, _II2 __last2)
@@ -1019,6 +1120,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _ForwardIterator, typename _Tp, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_ForwardIterator
__lower_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val, _Compare __comp)
@@ -1057,6 +1159,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @ingroup binary_search_algorithms
*/
template<typename _ForwardIterator, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline _ForwardIterator
lower_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val)
@@ -1112,6 +1215,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* ranges are equal.
*/
template<typename _II1, typename _II2>
+ _GLIBCXX20_CONSTEXPR
inline bool
equal(_II1 __first1, _II1 __last1, _II2 __first2)
{
@@ -1144,6 +1248,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* ranges are equal.
*/
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
inline bool
equal(_IIter1 __first1, _IIter1 __last1,
_IIter2 __first2, _BinaryPredicate __binary_pred)
@@ -1162,6 +1267,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
#if __cplusplus >= 201103L
// 4-iterator version of std::equal<It1, It2> for use in C++11.
template<typename _II1, typename _II2>
+ _GLIBCXX20_CONSTEXPR
inline bool
__equal4(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2)
{
@@ -1187,6 +1293,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
// 4-iterator version of std::equal<It1, It2, BinaryPred> for use in C++11.
template<typename _II1, typename _II2, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
inline bool
__equal4(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2,
_BinaryPredicate __binary_pred)
@@ -1231,6 +1338,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* ranges are equal.
*/
template<typename _II1, typename _II2>
+ _GLIBCXX20_CONSTEXPR
inline bool
equal(_II1 __first1, _II1 __last1, _II2 __first2, _II2 __last2)
{
@@ -1263,6 +1371,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* ranges are equal.
*/
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
inline bool
equal(_IIter1 __first1, _IIter1 __last1,
_IIter2 __first2, _IIter2 __last2, _BinaryPredicate __binary_pred)
@@ -1294,6 +1403,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* then this is an inline call to @c memcmp.
*/
template<typename _II1, typename _II2>
+ _GLIBCXX20_CONSTEXPR
inline bool
lexicographical_compare(_II1 __first1, _II1 __last1,
_II2 __first2, _II2 __last2)
@@ -1330,6 +1440,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* comp parameter instead of @c <.
*/
template<typename _II1, typename _II2, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline bool
lexicographical_compare(_II1 __first1, _II1 __last1,
_II2 __first2, _II2 __last2, _Compare __comp)
@@ -1347,6 +1458,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
template<typename _InputIterator1, typename _InputIterator2,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
pair<_InputIterator1, _InputIterator2>
__mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _BinaryPredicate __binary_pred)
@@ -1373,6 +1485,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* to by the iterators are not equal.
*/
template<typename _InputIterator1, typename _InputIterator2>
+ _GLIBCXX20_CONSTEXPR
inline pair<_InputIterator1, _InputIterator2>
mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2)
@@ -1407,6 +1520,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
inline pair<_InputIterator1, _InputIterator2>
mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _BinaryPredicate __binary_pred)
@@ -1424,6 +1538,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
template<typename _InputIterator1, typename _InputIterator2,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
pair<_InputIterator1, _InputIterator2>
__mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
@@ -1453,6 +1568,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
* to by the iterators are not equal.
*/
template<typename _InputIterator1, typename _InputIterator2>
+ _GLIBCXX20_CONSTEXPR
inline pair<_InputIterator1, _InputIterator2>
mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2)
@@ -1489,6 +1605,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO
*/
template<typename _InputIterator1, typename _InputIterator2,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
inline pair<_InputIterator1, _InputIterator2>
mismatch(_InputIterator1 __first1, _InputIterator1 __last1,
_InputIterator2 __first2, _InputIterator2 __last2,
diff --git a/libstdc++-v3/include/bits/stl_heap.h b/libstdc++-v3/include/bits/stl_heap.h
index a711ad6..7eb12f0 100644
--- a/libstdc++-v3/include/bits/stl_heap.h
+++ b/libstdc++-v3/include/bits/stl_heap.h
@@ -70,6 +70,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _RandomAccessIterator, typename _Distance,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_Distance
__is_heap_until(_RandomAccessIterator __first, _Distance __n,
_Compare& __comp)
@@ -88,6 +89,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// __is_heap, a predicate testing whether or not a range is a heap.
// This function is an extension, not part of the C++ standard.
template<typename _RandomAccessIterator, typename _Distance>
+ _GLIBCXX20_CONSTEXPR
inline bool
__is_heap(_RandomAccessIterator __first, _Distance __n)
{
@@ -97,6 +99,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _RandomAccessIterator, typename _Compare,
typename _Distance>
+ _GLIBCXX20_CONSTEXPR
inline bool
__is_heap(_RandomAccessIterator __first, _Compare __comp, _Distance __n)
{
@@ -106,11 +109,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _RandomAccessIterator>
+ _GLIBCXX20_CONSTEXPR
inline bool
__is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{ return std::__is_heap(__first, std::distance(__first, __last)); }
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline bool
__is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
@@ -124,6 +129,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _RandomAccessIterator, typename _Distance, typename _Tp,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
__push_heap(_RandomAccessIterator __first,
_Distance __holeIndex, _Distance __topIndex, _Tp __value,
@@ -150,6 +156,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* [__first,__last) is a valid heap.
*/
template<typename _RandomAccessIterator>
+ _GLIBCXX20_CONSTEXPR
inline void
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
@@ -185,6 +192,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* performed using comp.
*/
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline void
push_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
@@ -210,6 +218,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _RandomAccessIterator, typename _Distance,
typename _Tp, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
__adjust_heap(_RandomAccessIterator __first, _Distance __holeIndex,
_Distance __len, _Tp __value, _Compare __comp)
@@ -239,6 +248,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline void
__pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_RandomAccessIterator __result, _Compare& __comp)
@@ -267,6 +277,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* heap.
*/
template<typename _RandomAccessIterator>
+ _GLIBCXX20_CONSTEXPR
inline void
pop_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
@@ -300,6 +311,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* heap. Comparisons are made using comp.
*/
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline void
pop_heap(_RandomAccessIterator __first,
_RandomAccessIterator __last, _Compare __comp)
@@ -322,6 +334,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare& __comp)
@@ -356,6 +369,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* This operation makes the elements in [__first,__last) into a heap.
*/
template<typename _RandomAccessIterator>
+ _GLIBCXX20_CONSTEXPR
inline void
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
@@ -382,6 +396,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* Comparisons are made using __comp.
*/
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline void
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
@@ -398,6 +413,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
__sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare& __comp)
@@ -418,6 +434,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* This operation sorts the valid heap in the range [__first,__last).
*/
template<typename _RandomAccessIterator>
+ _GLIBCXX20_CONSTEXPR
inline void
sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
@@ -445,6 +462,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* Comparisons are made using __comp.
*/
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline void
sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
@@ -473,6 +491,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* the range [__first, i) is a heap.
*/
template<typename _RandomAccessIterator>
+ _GLIBCXX20_CONSTEXPR
inline _RandomAccessIterator
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last)
{
@@ -501,6 +520,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* the range [__first, i) is a heap. Comparisons are made using __comp.
*/
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline _RandomAccessIterator
is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
@@ -525,6 +545,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @ingroup heap_algorithms
*/
template<typename _RandomAccessIterator>
+ _GLIBCXX20_CONSTEXPR
inline bool
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last)
{ return std::is_heap_until(__first, __last) == __last; }
@@ -538,6 +559,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @ingroup heap_algorithms
*/
template<typename _RandomAccessIterator, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
inline bool
is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last,
_Compare __comp)
diff --git a/libstdc++-v3/include/bits/stl_iterator.h b/libstdc++-v3/include/bits/stl_iterator.h
index e9d90fa..8ab0d72 100644
--- a/libstdc++-v3/include/bits/stl_iterator.h
+++ b/libstdc++-v3/include/bits/stl_iterator.h
@@ -446,7 +446,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
template<typename _Iterator>
- auto
+ _GLIBCXX20_CONSTEXPR auto
__niter_base(reverse_iterator<_Iterator> __it)
-> decltype(__make_reverse_iterator(__niter_base(__it.base())))
{ return __make_reverse_iterator(__niter_base(__it.base())); }
@@ -457,7 +457,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ };
template<typename _Iterator>
- auto
+ _GLIBCXX20_CONSTEXPR auto
__miter_base(reverse_iterator<_Iterator> __it)
-> decltype(__make_reverse_iterator(__miter_base(__it.base())))
{ return __make_reverse_iterator(__miter_base(__it.base())); }
diff --git a/libstdc++-v3/include/bits/unique_ptr.h b/libstdc++-v3/include/bits/unique_ptr.h
index 484c8b3..0c4eb25 100644
--- a/libstdc++-v3/include/bits/unique_ptr.h
+++ b/libstdc++-v3/include/bits/unique_ptr.h
@@ -245,14 +245,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// unique_ptr
template<typename _Up, typename _Ep>
using __safe_conversion_up = __and_<
- is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
- __not_<is_array<_Up>>,
- __or_<__and_<is_reference<deleter_type>,
- is_same<deleter_type, _Ep>>,
- __and_<__not_<is_reference<deleter_type>>,
- is_convertible<_Ep, deleter_type>>
- >
- >;
+ is_convertible<typename unique_ptr<_Up, _Ep>::pointer, pointer>,
+ __not_<is_array<_Up>>
+ >;
public:
// Constructors.
@@ -492,16 +487,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// helper template for detecting a safe conversion from another
// unique_ptr
template<typename _Up, typename _Ep,
- typename _Up_up = unique_ptr<_Up, _Ep>,
- typename _Up_element_type = typename _Up_up::element_type>
+ typename _UPtr = unique_ptr<_Up, _Ep>,
+ typename _UP_pointer = typename _UPtr::pointer,
+ typename _UP_element_type = typename _UPtr::element_type>
using __safe_conversion_up = __and_<
is_array<_Up>,
is_same<pointer, element_type*>,
- is_same<typename _Up_up::pointer, _Up_element_type*>,
- is_convertible<_Up_element_type(*)[], element_type(*)[]>,
- __or_<__and_<is_reference<deleter_type>, is_same<deleter_type, _Ep>>,
- __and_<__not_<is_reference<deleter_type>>,
- is_convertible<_Ep, deleter_type>>>
+ is_same<_UP_pointer, _UP_element_type*>,
+ is_convertible<_UP_element_type(*)[], element_type(*)[]>
>;
// helper template for detecting a safe conversion from a raw pointer
@@ -590,8 +583,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _M_t()
{ }
- template<typename _Up, typename _Ep,
- typename = _Require<__safe_conversion_up<_Up, _Ep>>>
+ template<typename _Up, typename _Ep, typename = _Require<
+ __safe_conversion_up<_Up, _Ep>,
+ typename conditional<is_reference<_Dp>::value,
+ is_same<_Ep, _Dp>,
+ is_convertible<_Ep, _Dp>>::type>>
unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
: _M_t(__u.release(), std::forward<_Ep>(__u.get_deleter()))
{ }
diff --git a/libstdc++-v3/include/experimental/array b/libstdc++-v3/include/experimental/array
index 5a35fd4..0064a0b 100644
--- a/libstdc++-v3/include/experimental/array
+++ b/libstdc++-v3/include/experimental/array
@@ -101,7 +101,7 @@ template <typename _Tp, size_t _Nm>
to_array(_Tp (&__a)[_Nm])
noexcept(is_nothrow_constructible<remove_cv_t<_Tp>, _Tp&>::value)
{
- return __to_array(__a, make_index_sequence<_Nm>{});
+ return experimental::__to_array(__a, make_index_sequence<_Nm>{});
}
// @} group make_array
diff --git a/libstdc++-v3/include/ext/random b/libstdc++-v3/include/ext/random
index 41a2962..d5574e0 100644
--- a/libstdc++-v3/include/ext/random
+++ b/libstdc++-v3/include/ext/random
@@ -752,6 +752,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_InputIterator2 __varbegin,
_InputIterator2 __varend);
+ // param_type constructors apply Cholesky decomposition to the
+ // varcov matrix in _M_init_full and _M_init_lower, but the
+ // varcov matrix output ot a stream is already decomposed, so
+ // we need means to restore it as-is when reading it back in.
+ template<size_t _Dimen1, typename _RealType1,
+ typename _CharT, typename _Traits>
+ friend std::basic_istream<_CharT, _Traits>&
+ operator>>(std::basic_istream<_CharT, _Traits>& __is,
+ __gnu_cxx::normal_mv_distribution<_Dimen1, _RealType1>&
+ __x);
+ param_type(std::array<_RealType, _Dimen> const &__mean,
+ std::array<_RealType, _M_t_size> const &__varcov)
+ : _M_mean (__mean), _M_t (__varcov)
+ {}
+
std::array<_RealType, _Dimen> _M_mean;
std::array<_RealType, _M_t_size> _M_t;
};
diff --git a/libstdc++-v3/include/ext/random.tcc b/libstdc++-v3/include/ext/random.tcc
index 31dc33a..a8a49a3 100644
--- a/libstdc++-v3/include/ext/random.tcc
+++ b/libstdc++-v3/include/ext/random.tcc
@@ -581,7 +581,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__sum = *__varcovbegin++ - __sum;
if (__builtin_expect(__sum <= _RealType(0), 0))
std::__throw_runtime_error(__N("normal_mv_distribution::"
- "param_type::_M_init_full"));
+ "param_type::_M_init_lower"));
*__w++ = std::sqrt(__sum);
}
}
@@ -709,9 +709,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__is >> __x._M_nd;
+ // The param_type temporary is built with a private constructor,
+ // to skip the Cholesky decomposition that would be performed
+ // otherwise.
__x.param(typename normal_mv_distribution<_Dimen, _RealType>::
- param_type(__mean.begin(), __mean.end(),
- __varcov.begin(), __varcov.end()));
+ param_type(__mean, __varcov));
__is.flags(__flags);
return __is;
diff --git a/libstdc++-v3/include/precompiled/stdc++.h b/libstdc++-v3/include/precompiled/stdc++.h
index 477c5c8..d62f64b 100644
--- a/libstdc++-v3/include/precompiled/stdc++.h
+++ b/libstdc++-v3/include/precompiled/stdc++.h
@@ -136,6 +136,9 @@
#if __cplusplus > 201703L
#include <bit>
// #include <compare>
+// #include <concepts>
+#include <numbers>
+// #include <ranges>
// #include <span>
// #include <syncstream>
#include <version>
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
index 230e2b0..a380f52 100644
--- a/libstdc++-v3/include/std/array
+++ b/libstdc++-v3/include/std/array
@@ -88,7 +88,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
* Sets support random access iterators.
*
* @tparam Tp Type of element. Required to be a complete type.
- * @tparam N Number of elements.
+ * @tparam Nm Number of elements.
*/
template<typename _Tp, std::size_t _Nm>
struct array
@@ -248,16 +248,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
// Array comparisons.
template<typename _Tp, std::size_t _Nm>
+ _GLIBCXX20_CONSTEXPR
inline bool
operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
{ return std::equal(__one.begin(), __one.end(), __two.begin()); }
template<typename _Tp, std::size_t _Nm>
+ _GLIBCXX20_CONSTEXPR
inline bool
operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
{ return !(__one == __two); }
template<typename _Tp, std::size_t _Nm>
+ _GLIBCXX20_CONSTEXPR
inline bool
operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
{
@@ -266,16 +269,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
template<typename _Tp, std::size_t _Nm>
+ _GLIBCXX20_CONSTEXPR
inline bool
operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
{ return __two < __one; }
template<typename _Tp, std::size_t _Nm>
+ _GLIBCXX20_CONSTEXPR
inline bool
operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
{ return !(__one > __two); }
template<typename _Tp, std::size_t _Nm>
+ _GLIBCXX20_CONSTEXPR
inline bool
operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
{ return !(__one < __two); }
@@ -289,6 +295,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
_GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::_Is_swappable::value
>::type
#else
+ _GLIBCXX20_CONSTEXPR
void
#endif
swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
@@ -336,6 +343,44 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
return std::move(_GLIBCXX_STD_C::get<_Int>(__arr));
}
+#if __cplusplus > 201703L
+#define __cpp_lib_to_array 201907L
+
+ template<bool _Move = false, typename _Tp, size_t... _Idx>
+ constexpr array<remove_cv_t<_Tp>, sizeof...(_Idx)>
+ __to_array(_Tp (&__a)[sizeof...(_Idx)], index_sequence<_Idx...>)
+ {
+ if constexpr (_Move)
+ return {{std::move(__a[_Idx])...}};
+ else
+ return {{__a[_Idx]...}};
+ }
+
+ template<typename _Tp, size_t _Nm>
+ constexpr array<remove_cv_t<_Tp>, _Nm>
+ to_array(_Tp (&__a)[_Nm])
+ noexcept(is_nothrow_constructible_v<_Tp, _Tp&>)
+ {
+ static_assert(!is_array_v<_Tp>);
+ static_assert(is_constructible_v<_Tp, _Tp&>);
+ if constexpr (is_constructible_v<_Tp, _Tp&>)
+ return _GLIBCXX_STD_C::__to_array(__a, make_index_sequence<_Nm>{});
+ __builtin_unreachable(); // FIXME: see PR c++/91388
+ }
+
+ template<typename _Tp, size_t _Nm>
+ constexpr array<remove_cv_t<_Tp>, _Nm>
+ to_array(_Tp (&&__a)[_Nm])
+ noexcept(is_nothrow_move_constructible_v<_Tp>)
+ {
+ static_assert(!is_array_v<_Tp>);
+ static_assert(is_move_constructible_v<_Tp>);
+ if constexpr (is_move_constructible_v<_Tp>)
+ return _GLIBCXX_STD_C::__to_array<1>(__a, make_index_sequence<_Nm>{});
+ __builtin_unreachable(); // FIXME: see PR c++/91388
+ }
+#endif // C++20
+
_GLIBCXX_END_NAMESPACE_CONTAINER
} // namespace std
diff --git a/libstdc++-v3/include/std/bit b/libstdc++-v3/include/std/bit
index f17d2f1..914cdfe 100644
--- a/libstdc++-v3/include/std/bit
+++ b/libstdc++-v3/include/std/bit
@@ -40,6 +40,17 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ /**
+ * @defgroup bit_manip Bit manipulation
+ * @ingroup numerics
+ *
+ * Utilities for examining and manipulating individual bits.
+ *
+ * @{
+ */
+
+ /// @cond undoc
+
template<typename _Tp>
constexpr _Tp
__rotl(_Tp __x, int __s) noexcept
@@ -248,19 +259,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return _Nd - std::__countl_zero(__x);
}
+ /// @endcond
+
#if __cplusplus > 201703L
+ /// @cond undoc
template<typename _Tp, typename _Up = _Tp>
using _If_is_unsigned_integer
= enable_if_t<__is_unsigned_integer<_Tp>::value, _Up>;
+ /// @endcond
// [bit.rot], rotating
+ /// Rotate `x` to the left by `s` bits.
template<typename _Tp>
[[nodiscard]] constexpr _If_is_unsigned_integer<_Tp>
rotl(_Tp __x, int __s) noexcept
{ return std::__rotl(__x, __s); }
+ /// Rotate `x` to the right by `s` bits.
template<typename _Tp>
[[nodiscard]] constexpr _If_is_unsigned_integer<_Tp>
rotr(_Tp __x, int __s) noexcept
@@ -268,26 +285,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// [bit.count], counting
+ /// The number of contiguous zero bits, starting from the highest bit.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp, int>
countl_zero(_Tp __x) noexcept
{ return std::__countl_zero(__x); }
+ /// The number of contiguous one bits, starting from the highest bit.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp, int>
countl_one(_Tp __x) noexcept
{ return std::__countl_one(__x); }
+ /// The number of contiguous zero bits, starting from the lowest bit.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp, int>
countr_zero(_Tp __x) noexcept
{ return std::__countr_zero(__x); }
+ /// The number of contiguous one bits, starting from the lowest bit.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp, int>
countr_one(_Tp __x) noexcept
{ return std::__countr_one(__x); }
+ /// The number of bits set in `x`.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp, int>
popcount(_Tp __x) noexcept
@@ -295,28 +317,43 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// [bit.pow.two], integral powers of 2
+ /// True if `x` is a power of two, false otherwise.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp, bool>
ispow2(_Tp __x) noexcept
{ return std::__ispow2(__x); }
+ /// The smallest power-of-two not less than `x`.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp>
ceil2(_Tp __x) noexcept
{ return std::__ceil2(__x); }
+ /// The largest power-of-two not greater than `x`.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp>
floor2(_Tp __x) noexcept
{ return std::__floor2(__x); }
+ /// The smallest integer greater than the base-2 logarithm of `x`.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp>
log2p1(_Tp __x) noexcept
{ return std::__log2p1(__x); }
+#define __cpp_lib_endian 201907L
+
+ /// Byte order
+ enum class endian
+ {
+ little = __ORDER_LITTLE_ENDIAN__,
+ big = __ORDER_BIG_ENDIAN__,
+ native = __BYTE_ORDER__
+ };
#endif // C++2a
+ /// @}
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional
index d610e91..30576f2 100644
--- a/libstdc++-v3/include/std/functional
+++ b/libstdc++-v3/include/std/functional
@@ -791,7 +791,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#if __cplusplus > 201703L
-#define __cpp_lib_bind_front 201902L
+#define __cpp_lib_bind_front 201907L
template<typename _Fd, typename... _BoundArgs>
struct _Bind_front
@@ -877,7 +877,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Fn, typename... _Args>
using _Bind_front_t
- = _Bind_front<decay_t<_Fn>, unwrap_ref_decay_t<_Args>...>;
+ = _Bind_front<decay_t<_Fn>, decay_t<_Args>...>;
template<typename _Fn, typename... _Args>
_Bind_front_t<_Fn, _Args...>
diff --git a/libstdc++-v3/include/std/memory b/libstdc++-v3/include/std/memory
index 3036802..0a483d2 100644
--- a/libstdc++-v3/include/std/memory
+++ b/libstdc++-v3/include/std/memory
@@ -375,8 +375,9 @@ get_pointer_safety() noexcept { return pointer_safety::relaxed; }
inline _Tp
make_obj_using_allocator(const _Alloc& __a, _Args&&... __args)
{
- return std::make_from_tuple<_Tp>(uses_allocator_construction_args<_Tp>(
- __a, std::forward<_Args>(__args)...));
+ return std::make_from_tuple<_Tp>(
+ std::uses_allocator_construction_args<_Tp>(__a,
+ std::forward<_Args>(__args)...));
}
template<typename _Tp, typename _Alloc, typename... _Args>
diff --git a/libstdc++-v3/include/std/numbers b/libstdc++-v3/include/std/numbers
new file mode 100644
index 0000000..314b130
--- /dev/null
+++ b/libstdc++-v3/include/std/numbers
@@ -0,0 +1,208 @@
+// <numbers> -*- C++ -*-
+
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file include/numbers
+ * This is a Standard C++ Library header.
+ */
+
+#ifndef _GLIBCXX_NUMBERS
+#define _GLIBCXX_NUMBERS 1
+
+#pragma GCC system_header
+
+#if __cplusplus > 201703L
+
+#include <type_traits>
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+/** @defgroup math_constants Mathematical constants
+ * @ingroup numerics
+ * @{
+ */
+
+/// Namespace for mathematical constants
+namespace numbers
+{
+#define __cpp_lib_math_constants 201907L
+
+ /// @cond undoc
+ template<typename _Tp>
+ using _Enable_if_floating = enable_if_t<is_floating_point_v<_Tp>, _Tp>;
+ /// @endcond
+
+ /// e
+ template<typename _Tp>
+ inline constexpr _Tp e_v
+ = _Enable_if_floating<_Tp>(2.718281828459045235360287471352662498L);
+
+ /// log_2 e
+ template<typename _Tp>
+ inline constexpr _Tp log2e_v
+ = _Enable_if_floating<_Tp>(1.442695040888963407359924681001892137L);
+
+ /// log_10 e
+ template<typename _Tp>
+ inline constexpr _Tp log10e_v
+ = _Enable_if_floating<_Tp>(0.434294481903251827651128918916605082L);
+
+ /// pi
+ template<typename _Tp>
+ inline constexpr _Tp pi_v
+ = _Enable_if_floating<_Tp>(3.141592653589793238462643383279502884L);
+
+ /// 1/pi
+ template<typename _Tp>
+ inline constexpr _Tp inv_pi_v
+ = _Enable_if_floating<_Tp>(0.318309886183790671537767526745028724L);
+
+ /// 1/sqrt(pi)
+ template<typename _Tp>
+ inline constexpr _Tp inv_sqrtpi_v
+ = _Enable_if_floating<_Tp>(0.564189583547756286948079451560772586L);
+
+ /// log_e 2
+ template<typename _Tp>
+ inline constexpr _Tp ln2_v
+ = _Enable_if_floating<_Tp>(0.693147180559945309417232121458176568L);
+
+ /// log_e 10
+ template<typename _Tp>
+ inline constexpr _Tp ln10_v
+ = _Enable_if_floating<_Tp>(2.302585092994045684017991454684364208L);
+
+ /// sqrt(2)
+ template<typename _Tp>
+ inline constexpr _Tp sqrt2_v
+ = _Enable_if_floating<_Tp>(1.414213562373095048801688724209698079L);
+
+ /// sqrt(3)
+ template<typename _Tp>
+ inline constexpr _Tp sqrt3_v
+ = _Enable_if_floating<_Tp>(1.732050807568877293527446341505872367L);
+
+ /// 1/sqrt(3)
+ template<typename _Tp>
+ inline constexpr _Tp inv_sqrt3_v
+ = _Enable_if_floating<_Tp>(0.577350269189625764509148780501957456L);
+
+ /// The Euler-Mascheroni constant
+ template<typename _Tp>
+ inline constexpr _Tp egamma_v
+ = _Enable_if_floating<_Tp>(0.577215664901532860606512090082402431L);
+
+ /// The golden ratio, (1+sqrt(5))/2
+ template<typename _Tp>
+ inline constexpr _Tp phi_v
+ = _Enable_if_floating<_Tp>(1.618033988749894848204586834365638118L);
+
+ inline constexpr double e = e_v<double>;
+ inline constexpr double log2e = log2e_v<double>;
+ inline constexpr double log10e = log10e_v<double>;
+ inline constexpr double pi = pi_v<double>;
+ inline constexpr double inv_pi = inv_pi_v<double>;
+ inline constexpr double inv_sqrtpi = inv_sqrtpi_v<double>;
+ inline constexpr double ln2 = ln2_v<double>;
+ inline constexpr double ln10 = ln10_v<double>;
+ inline constexpr double sqrt2 = sqrt2_v<double>;
+ inline constexpr double sqrt3 = sqrt3_v<double>;
+ inline constexpr double inv_sqrt3 = inv_sqrt3_v<double>;
+ inline constexpr double egamma = egamma_v<double>;
+ inline constexpr double phi = phi_v<double>;
+
+#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
+ template<>
+ inline constexpr __float128 e_v<__float128>
+ = 2.718281828459045235360287471352662498Q;
+
+ /// log_2 e
+ template<>
+ inline constexpr __float128 log2e_v<__float128>
+ = 1.442695040888963407359924681001892137Q;
+
+ /// log_10 e
+ template<>
+ inline constexpr __float128 log10e_v<__float128>
+ = 0.434294481903251827651128918916605082Q;
+
+ /// pi
+ template<>
+ inline constexpr __float128 pi_v<__float128>
+ = 3.141592653589793238462643383279502884Q;
+
+ /// 1/pi
+ template<>
+ inline constexpr __float128 inv_pi_v<__float128>
+ = 0.318309886183790671537767526745028724Q;
+
+ /// 1/sqrt(pi)
+ template<>
+ inline constexpr __float128 inv_sqrtpi_v<__float128>
+ = 0.564189583547756286948079451560772586Q;
+
+ /// log_e 2
+ template<>
+ inline constexpr __float128 ln2_v<__float128>
+ = 0.693147180559945309417232121458176568Q;
+
+ /// log_e 10
+ template<>
+ inline constexpr __float128 ln10_v<__float128>
+ = 2.302585092994045684017991454684364208Q;
+
+ /// sqrt(2)
+ template<>
+ inline constexpr __float128 sqrt2_v<__float128>
+ = 1.414213562373095048801688724209698079Q;
+
+ /// sqrt(3)
+ template<>
+ inline constexpr __float128 sqrt3_v<__float128>
+ = 1.732050807568877293527446341505872367Q;
+
+ /// 1/sqrt(3)
+ template<>
+ inline constexpr __float128 inv_sqrt3_v<__float128>
+ = 0.577350269189625764509148780501957456Q;
+
+ /// The Euler-Mascheroni constant
+ template<>
+ inline constexpr __float128 egamma_v<__float128>
+ = 0.577215664901532860606512090082402431Q;
+
+ /// The golden ratio, (1+sqrt(5))/2
+ template<>
+ inline constexpr __float128 phi_v<__float128>
+ = 1.618033988749894848204586834365638118Q;
+#endif // USE_FLOAT128
+
+} // namespace numbers
+/// @}
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif // C++20
+#endif // _GLIBCXX_NUMBERS
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 980dd6d..dd966b3 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -1591,6 +1591,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ }
#if __cplusplus >= 201703L
+
+ // Unpack a std::tuple into a type trait and use its value.
+ // For cv std::tuple<_Up> the result is _Trait<_Tp, cv _Up...>::value.
+ // For cv std::tuple<_Up>& the result is _Trait<_Tp, cv _Up&...>::value.
+ // Otherwise the result is false (because we don't know if std::get throws).
+ template<template<typename...> class _Trait, typename _Tp, typename _Tuple>
+ inline constexpr bool __unpack_std_tuple = false;
+
+ template<template<typename...> class _Trait, typename _Tp, typename... _Up>
+ inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>>
+ = _Trait<_Tp, _Up...>::value;
+
+ template<template<typename...> class _Trait, typename _Tp, typename... _Up>
+ inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&>
+ = _Trait<_Tp, _Up&...>::value;
+
+ template<template<typename...> class _Trait, typename _Tp, typename... _Up>
+ inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>>
+ = _Trait<_Tp, const _Up...>::value;
+
+ template<template<typename...> class _Trait, typename _Tp, typename... _Up>
+ inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&>
+ = _Trait<_Tp, const _Up&...>::value;
+
# define __cpp_lib_apply 201603
template <typename _Fn, typename _Tuple, size_t... _Idx>
@@ -1604,6 +1628,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template <typename _Fn, typename _Tuple>
constexpr decltype(auto)
apply(_Fn&& __f, _Tuple&& __t)
+ noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>)
{
using _Indices
= make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>;
@@ -1622,6 +1647,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template <typename _Tp, typename _Tuple>
constexpr _Tp
make_from_tuple(_Tuple&& __t)
+ noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>)
{
return __make_from_tuple_impl<_Tp>(
std::forward<_Tuple>(__t),
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index d8ed1ce..44db2ca 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -597,11 +597,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: public __is_null_pointer_helper<typename remove_cv<_Tp>::type>::type
{ };
- /// __is_nullptr_t (extension).
+ /// __is_nullptr_t (deprecated extension).
template<typename _Tp>
struct __is_nullptr_t
: public is_null_pointer<_Tp>
- { };
+ { } _GLIBCXX_DEPRECATED;
// Composite type categories.
@@ -2695,6 +2695,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ };
template<typename _Tp>
+ _GLIBCXX20_CONSTEXPR
inline
typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>,
is_move_constructible<_Tp>,
@@ -2704,6 +2705,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
is_nothrow_move_assignable<_Tp>>::value);
template<typename _Tp, size_t _Nm>
+ _GLIBCXX20_CONSTEXPR
inline
typename enable_if<__is_swappable<_Tp>::value>::type
swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm])
@@ -2881,14 +2883,49 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// __is_invocable (std::is_invocable for C++11)
- template<typename _Result, typename _Ret, typename = void>
+ // 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 { };
+ // Used for valid INVOKE and INVOKE<void> expressions.
template<typename _Result, typename _Ret>
- struct __is_invocable_impl<_Result, _Ret, __void_t<typename _Result::type>>
- : __or_<is_void<_Ret>, is_convertible<typename _Result::type, _Ret>>::type
+ struct __is_invocable_impl<_Result, _Ret,
+ /* is_void<_Ret> = */ true,
+ __void_t<typename _Result::type>>
+ : true_type
{ };
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wctor-dtor-privacy"
+ // Used for INVOKE<R> expressions to check the implicit conversion to R.
+ template<typename _Result, typename _Ret>
+ struct __is_invocable_impl<_Result, _Ret,
+ /* is_void<_Ret> = */ false,
+ __void_t<typename _Result::type>>
+ {
+ private:
+ // The type of the INVOKE expression.
+ // Unlike declval, this doesn't add_rvalue_reference.
+ static typename _Result::type _S_get();
+
+ template<typename _Tp>
+ static void _S_conv(_Tp);
+
+ // 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
+ _S_test(int);
+
+ template<typename _Tp>
+ static false_type
+ _S_test(...);
+
+ public:
+ using type = decltype(_S_test<_Ret>(1));
+ };
+#pragma GCC diagnostic pop
+
template<typename _Fn, typename... _ArgTypes>
struct __is_invocable
: __is_invocable_impl<__invoke_result<_Fn, _ArgTypes...>, void>::type
@@ -3226,14 +3263,6 @@ template <typename _From, typename _To>
#endif // C++17
#if __cplusplus > 201703L
- /// Byte order
- enum class endian
- {
- little = __ORDER_LITTLE_ENDIAN__,
- big = __ORDER_BIG_ENDIAN__,
- native = __BYTE_ORDER__
- };
-
/// Remove references and cv-qualifiers.
template<typename _Tp>
struct remove_cvref
diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility
index c687c1d..5f496f6 100644
--- a/libstdc++-v3/include/std/utility
+++ b/libstdc++-v3/include/std/utility
@@ -280,11 +280,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#define __cpp_lib_exchange_function 201304
+#if __cplusplus > 201703L
+# define __cpp_lib_constexpr_algorithms 201711L
+#endif
+
/// Assign @p __new_val to @p __obj and return its previous value.
template <typename _Tp, typename _Up = _Tp>
+ _GLIBCXX20_CONSTEXPR
inline _Tp
exchange(_Tp& __obj, _Up&& __new_val)
{ return std::__exchange(__obj, std::forward<_Up>(__new_val)); }
+
#endif
// Stores a tuple of indices. Used by tuple and pair, and by bind() to
diff --git a/libstdc++-v3/include/std/version b/libstdc++-v3/include/std/version
index d134f7f..7f7d05f 100644
--- a/libstdc++-v3/include/std/version
+++ b/libstdc++-v3/include/std/version
@@ -151,17 +151,22 @@
#if __cplusplus > 201703L
// c++2a
#define __cpp_lib_atomic_ref 201806L
-#define __cpp_lib_bind_front 201902L
+#define __cpp_lib_bind_front 201907L
#define __cpp_lib_bounded_array_traits 201902L
+#define __cpp_lib_constexpr_algorithms 201711L
+#define __cpp_lib_constexpr_swap_algorithms 201806L
#if __cpp_impl_destroying_delete
# define __cpp_lib_destroying_delete 201806L
#endif
+#define __cpp_lib_endian 201907L
#define __cpp_lib_erase_if 201900L
#define __cpp_lib_interpolate 201902L
#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
# define __cpp_lib_is_constant_evaluated 201811L
#endif
#define __cpp_lib_list_remove_return_type 201806L
+#define __cpp_lib_math_constants 201907L
+#define __cpp_lib_to_array 201907L
#endif // C++2a
#endif // C++17
#endif // C++14
diff --git a/libstdc++-v3/libsupc++/cxxabi.h b/libstdc++-v3/libsupc++/cxxabi.h
index 3562d4c..4d9f829 100644
--- a/libstdc++-v3/libsupc++/cxxabi.h
+++ b/libstdc++-v3/libsupc++/cxxabi.h
@@ -684,8 +684,9 @@ namespace __gnu_cxx
* @brief Exception thrown by __cxa_guard_acquire.
* @ingroup exceptions
*
- * 6.7[stmt.dcl]/4: If control re-enters the declaration (recursively)
- * while the object is being initialized, the behavior is undefined.
+ * C++ 2011 6.7 [stmt.dcl]/4: If control re-enters the declaration
+ * recursively while the variable is being initialized, the behavior
+ * is undefined.
*
* Since we already have a library function to handle locking, we might
* as well check for this situation and throw an exception.
@@ -695,8 +696,8 @@ namespace __gnu_cxx
class recursive_init_error: public std::exception
{
public:
- recursive_init_error() throw() { }
- virtual ~recursive_init_error() throw ();
+ recursive_init_error() _GLIBCXX_NOTHROW;
+ virtual ~recursive_init_error() _GLIBCXX_NOTHROW;
};
}
#endif // __cplusplus
diff --git a/libstdc++-v3/libsupc++/guard_error.cc b/libstdc++-v3/libsupc++/guard_error.cc
index 7595c67..d7625af 100644
--- a/libstdc++-v3/libsupc++/guard_error.cc
+++ b/libstdc++-v3/libsupc++/guard_error.cc
@@ -26,6 +26,6 @@
namespace __gnu_cxx
{
- recursive_init_error::~recursive_init_error() throw() { }
+ recursive_init_error::recursive_init_error() noexcept { }
+ recursive_init_error::~recursive_init_error() noexcept { }
}
-
diff --git a/libstdc++-v3/src/c++17/string-inst.cc b/libstdc++-v3/src/c++17/string-inst.cc
index c095a90..4dc0a9c 100644
--- a/libstdc++-v3/src/c++17/string-inst.cc
+++ b/libstdc++-v3/src/c++17/string-inst.cc
@@ -26,6 +26,12 @@
// ISO C++ 14882:2017 24 Strings library
//
+#ifndef _GLIBCXX_USE_CXX11_ABI
+// Instantiations in this file use the new SSO std::string ABI unless included
+// by another file which defines _GLIBCXX_USE_CXX11_ABI=0.
+# define _GLIBCXX_USE_CXX11_ABI 1
+#endif
+
#include <string>
namespace std _GLIBCXX_VISIBILITY(default)
diff --git a/libstdc++-v3/testsuite/18_support/51333.cc b/libstdc++-v3/testsuite/18_support/51333.cc
new file mode 100644
index 0000000..0fb7c33
--- /dev/null
+++ b/libstdc++-v3/testsuite/18_support/51333.cc
@@ -0,0 +1,22 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-fkeep-inline-functions" }
+// { dg-do link }
+
+#include <cxxabi.h>
+int main() { } // PR libstdc++/51333
diff --git a/libstdc++-v3/testsuite/20_util/exchange/constexpr.cc b/libstdc++-v3/testsuite/20_util/exchange/constexpr.cc
new file mode 100644
index 0000000..38edfaa
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/exchange/constexpr.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <utility>
+
+constexpr bool
+test()
+{
+ constexpr double e_v = 2.71828182846;
+ double e = e_v;
+ constexpr double pi_v = 3.14159265359;
+ const auto x = std::exchange(e, pi_v);
+
+ return x == e_v && e == pi_v;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/20_util/function/91456.cc b/libstdc++-v3/testsuite/20_util/function/91456.cc
new file mode 100644
index 0000000..a2d412d
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/function/91456.cc
@@ -0,0 +1,37 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++17 } }
+
+#include <functional>
+
+struct Immovable {
+ Immovable() = default;
+ Immovable(const Immovable&) = delete;
+ Immovable& operator=(const Immovable&) = delete;
+};
+
+Immovable get() { return {}; }
+const Immovable i = get(); // OK
+std::function<const Immovable()> f{&get}; // fails
+const Immovable i2 = f();
+
+const Immovable cget() { return {}; }
+Immovable ci = cget(); // OK
+std::function<Immovable()> cf{&cget}; // fails
+Immovable ci2 = cf();
diff --git a/libstdc++-v3/testsuite/20_util/function_objects/bind_front/1.cc b/libstdc++-v3/testsuite/20_util/function_objects/bind_front/1.cc
index 8ebc2ba..c6cf5cf 100644
--- a/libstdc++-v3/testsuite/20_util/function_objects/bind_front/1.cc
+++ b/libstdc++-v3/testsuite/20_util/function_objects/bind_front/1.cc
@@ -23,7 +23,7 @@
#ifndef __cpp_lib_bind_front
# error "Feature test macro for bind_front is missing"
-#elif __cpp_lib_bind_front < 201811L
+#elif __cpp_lib_bind_front < 201902L
# error "Feature test macro for bind_front has wrong value"
#endif
diff --git a/libstdc++-v3/testsuite/20_util/function_objects/bind_front/2.cc b/libstdc++-v3/testsuite/20_util/function_objects/bind_front/2.cc
new file mode 100644
index 0000000..b68cc65
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/function_objects/bind_front/2.cc
@@ -0,0 +1,91 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do run { target c++2a } }
+
+#include <functional>
+#include <memory>
+#include <string>
+#include <testsuite_hooks.h>
+
+// P1651R0 bind_front should not unwrap reference_wrapper
+
+#ifndef __cpp_lib_bind_front
+# error "Feature test macro for bind_front is missing"
+#elif __cpp_lib_bind_front < 201907L
+# error "Feature test macro for bind_front has wrong value"
+#endif
+
+void functionAcceptingStringView(std::string_view) { }
+
+void
+test01()
+{
+ std::string s;
+ auto fs = std::bind_front(&functionAcceptingStringView, std::string_view(s));
+ fs();
+}
+
+template <typename F>
+struct PartialApply {
+ PartialApply(F f) : f(f) {}
+ F f;
+
+ template <typename... A> decltype(auto) operator()(A const&... a) const {
+ if constexpr (std::is_invocable<F const&, A const&...>::value) {
+ return f(a...);
+ } else {
+ return bind_front(*this, a...);
+ }
+ }
+};
+
+void
+test02()
+{
+ struct Thingy { };
+ std::unique_ptr<Thingy> thingy;
+ auto func = [](const std::unique_ptr<Thingy>&, int) {};
+ PartialApply{func}(std::ref(thingy))(10);
+}
+
+void
+test03()
+{
+ std::string str;
+ auto func = [](const std::string& s, int) -> const std::string& { return s; };
+
+ // sref refers to copy of str stored in bind_front result:
+ const std::string& sref = PartialApply{func}(std::ref(str))(10);
+
+ // pre-P1651R0 this is a use of a dangling reference:
+ const char& c = sref[0];
+
+ // post-P1651R0 the bind_front result stores a reference_wrapper by value,
+ // and so sref is bound to str instead of dangling:
+ VERIFY( &c == str.data() );
+ VERIFY( &sref == &str );
+}
+
+int
+main()
+{
+ test01();
+ test02();
+ test03();
+}
diff --git a/libstdc++-v3/testsuite/20_util/is_invocable/91456.cc b/libstdc++-v3/testsuite/20_util/is_invocable/91456.cc
new file mode 100644
index 0000000..d510d22
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/is_invocable/91456.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++17 } }
+
+#include <type_traits>
+
+#include <functional>
+
+struct Immovable {
+ Immovable() = default;
+ Immovable(const Immovable&) = delete;
+ Immovable& operator=(const Immovable&) = delete;
+};
+
+Immovable get() { return {}; }
+const Immovable i = get(); // OK
+std::function<const Immovable()> f{&get}; // fails
+const Immovable i2 = f();
diff --git a/libstdc++-v3/testsuite/20_util/tuple/apply/2.cc b/libstdc++-v3/testsuite/20_util/tuple/apply/2.cc
new file mode 100644
index 0000000..aa5968f
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/apply/2.cc
@@ -0,0 +1,62 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++17 } }
+
+// Test noexcept-specifier on std::apply
+
+#include <tuple>
+
+using std::tuple;
+using std::declval;
+
+void f1();
+
+static_assert( !noexcept(apply(f1, declval<tuple<>>())) );
+static_assert( !noexcept(apply(f1, declval<tuple<>&>())) );
+static_assert( !noexcept(apply(f1, declval<const tuple<>>())) );
+static_assert( !noexcept(apply(f1, declval<const tuple<>&>())) );
+
+void f2() noexcept;
+
+static_assert( noexcept(apply(f2, declval<tuple<>>())) );
+static_assert( noexcept(apply(f2, declval<tuple<>&>())) );
+static_assert( noexcept(apply(f2, declval<const tuple<>>())) );
+static_assert( noexcept(apply(f2, declval<const tuple<>&>())) );
+
+struct F3 {
+ void operator()(int&);
+ void operator()(int&&) noexcept;
+ void operator()(const int&) noexcept;
+ void operator()(const int&&);
+} f3;
+
+static_assert( noexcept(apply(f3, declval<tuple<int>>())) );
+static_assert( !noexcept(apply(f3, declval<tuple<int>&>())) );
+static_assert( !noexcept(apply(f3, declval<const tuple<int>>())) );
+static_assert( noexcept(apply(f3, declval<const tuple<int>&>())) );
+
+struct F4 {
+ void operator()(int&, const int&);
+ void operator()(int&&, int&&) noexcept;
+} f4;
+
+static_assert( noexcept(apply(f4, declval<tuple<int, int>>())) );
+static_assert( !noexcept(apply(f4, declval<tuple<int, int>&>())) );
+static_assert( !noexcept(apply(f4, declval<tuple<int&, const int>>())) );
+static_assert( !noexcept(apply(f4, declval<tuple<int, const int>&>())) );
diff --git a/libstdc++-v3/testsuite/20_util/tuple/make_from_tuple/2.cc b/libstdc++-v3/testsuite/20_util/tuple/make_from_tuple/2.cc
new file mode 100644
index 0000000..18a9466
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/make_from_tuple/2.cc
@@ -0,0 +1,63 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++17" }
+// { dg-do compile { target c++17 } }
+
+// Test noexcept-specifier on std::make_from_tuple
+
+#include <tuple>
+
+using std::make_from_tuple;
+using std::tuple;
+using std::declval;
+
+struct T1 { T1(); };
+
+static_assert( !noexcept(make_from_tuple<T1>(declval<tuple<>>())) );
+static_assert( !noexcept(make_from_tuple<T1>(declval<tuple<>&>())) );
+static_assert( !noexcept(make_from_tuple<T1>(declval<const tuple<>>())) );
+static_assert( !noexcept(make_from_tuple<T1>(declval<const tuple<>&>())) );
+
+struct T2 { };
+
+static_assert( noexcept(make_from_tuple<T2>(declval<tuple<>>())) );
+static_assert( noexcept(make_from_tuple<T2>(declval<tuple<>&>())) );
+static_assert( noexcept(make_from_tuple<T2>(declval<const tuple<>>())) );
+static_assert( noexcept(make_from_tuple<T2>(declval<const tuple<>&>())) );
+
+struct T3 {
+ T3(int&);
+ T3(int&&) noexcept;
+ T3(const int&) noexcept;
+ T3(const int&&);
+};
+
+static_assert( noexcept(make_from_tuple<T3>(declval<tuple<int>>())) );
+static_assert( !noexcept(make_from_tuple<T3>(declval<tuple<int>&>())) );
+static_assert( !noexcept(make_from_tuple<T3>(declval<const tuple<int>>())) );
+static_assert( noexcept(make_from_tuple<T3>(declval<const tuple<int>&>())) );
+
+struct T4 {
+ T4(int&, const int&);
+ T4(int&&, int&&) noexcept;
+};
+
+static_assert( noexcept(make_from_tuple<T4>(declval<tuple<int, int>>())) );
+static_assert( !noexcept(make_from_tuple<T4>(declval<tuple<int, int>&>())) );
+static_assert( !noexcept(make_from_tuple<T4>(declval<tuple<int&, const int>>())) );
+static_assert( !noexcept(make_from_tuple<T4>(declval<tuple<int, const int>&>())) );
diff --git a/libstdc++-v3/testsuite/20_util/unique_ptr/assign/91308.cc b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/91308.cc
new file mode 100644
index 0000000..6500ea4
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/unique_ptr/assign/91308.cc
@@ -0,0 +1,46 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++11 } }
+
+#include <memory>
+
+struct D1
+{
+ void operator()(int* p) const noexcept { }
+};
+
+struct D2 : D1
+{
+ D2& operator=(D1&&) noexcept { return *this; }
+};
+
+void
+test01()
+{
+ std::unique_ptr<int, D1> d1;
+ std::unique_ptr<int, D2> d2;
+ d2 = std::move(d1);
+}
+
+void
+test02()
+{
+ std::unique_ptr<int[], D1> d1;
+ std::unique_ptr<int[], D2> d2;
+ d2 = std::move(d1);
+}
diff --git a/libstdc++-v3/testsuite/23_containers/array/comparison_operators/constexpr.cc b/libstdc++-v3/testsuite/23_containers/array/comparison_operators/constexpr.cc
new file mode 100644
index 0000000..8655a9b
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/array/comparison_operators/constexpr.cc
@@ -0,0 +1,33 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+//
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <array>
+
+constexpr std::array<int, 3> a1{{1, 2, 3}};
+constexpr std::array<int, 3> a2{{4, 5, 6}};
+constexpr std::array<int, 3> a3{{1, 2, 4}};
+constexpr std::array<int, 3> a4{{1, 3, 3}};
+
+static_assert(a1 == a1);
+static_assert(a1 != a2);
+static_assert(a1 < a3);
+static_assert(a4 > a1);
+static_assert(a1 <= a3);
+static_assert(a4 >= a1);
diff --git a/libstdc++-v3/testsuite/23_containers/array/creation/1.cc b/libstdc++-v3/testsuite/23_containers/array/creation/1.cc
new file mode 100644
index 0000000..6279d73
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/array/creation/1.cc
@@ -0,0 +1,57 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <array>
+
+#ifndef __cpp_lib_to_array
+# error "Feature test macro for to_array is missing"
+#elif __cpp_lib_to_array < 201907L
+# error "Feature test macro for to_array has wrong value"
+#endif
+
+void test01()
+{
+ const char x[6]{};
+ std::array<char, 6> y = std::to_array(x);
+
+ constexpr char x2[] = "foo";
+ constexpr std::array<char, 4> y2 = std::to_array(x2);
+ static_assert( std::equal(y2.begin(), y2.end(), x2) );
+}
+
+void
+test02()
+{
+ struct MoveOnly
+ {
+ constexpr MoveOnly(int i = 0) : i(i) { }
+ constexpr MoveOnly(MoveOnly&& m) : i(m.i + 100) { }
+ int i;
+ };
+
+ struct X {
+ MoveOnly m[3];
+ };
+ X x;
+ std::array<MoveOnly, 3> y = std::to_array(std::move(x).m);
+
+ constexpr std::array<MoveOnly, 3> y2 = std::to_array(X{{1, 2, 3}}.m);
+ static_assert( y2[0].i == 101 && y2[1].i == 102 && y2[2].i == 103 );
+}
diff --git a/libstdc++-v3/testsuite/23_containers/array/creation/2.cc b/libstdc++-v3/testsuite/23_containers/array/creation/2.cc
new file mode 100644
index 0000000..725f950
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/array/creation/2.cc
@@ -0,0 +1,27 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <version>
+
+#ifndef __cpp_lib_to_array
+# error "Feature test macro for to_array is missing in <version>"
+#elif __cpp_lib_to_array < 201907L
+# error "Feature test macro for to_array has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/23_containers/array/creation/3_neg.cc b/libstdc++-v3/testsuite/23_containers/array/creation/3_neg.cc
new file mode 100644
index 0000000..72f3899
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/array/creation/3_neg.cc
@@ -0,0 +1,56 @@
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <array>
+
+void
+test01()
+{
+ int two_dee[3][4];
+ std::to_array(two_dee); // { dg-error "here" }
+}
+
+void
+test02()
+{
+ struct X
+ {
+ int two_dee[3][4];
+ };
+ std::to_array(X{}.two_dee); // { dg-error "here" }
+}
+
+void
+test03()
+{
+ struct MoveOnly
+ {
+ MoveOnly() = default;
+ MoveOnly(MoveOnly&&) = default;
+ };
+
+ MoveOnly mo[2];
+ std::to_array(mo); // { dg-error "here" }
+
+ const MoveOnly cmo[3];
+ std::to_array(std::move(cmo)); // { dg-error "here" }
+}
+
+// { dg-prune-output "static assertion failed" }
diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
index f85b8ad..2ae8a5e 100644
--- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
@@ -27,6 +27,6 @@ int n1 = std::get<1>(a);
int n2 = std::get<1>(std::move(a));
int n3 = std::get<1>(ca);
-// { dg-error "static assertion failed" "" { target *-*-* } 309 }
-// { dg-error "static assertion failed" "" { target *-*-* } 318 }
-// { dg-error "static assertion failed" "" { target *-*-* } 326 }
+// { dg-error "static assertion failed" "" { target *-*-* } 316 }
+// { dg-error "static assertion failed" "" { target *-*-* } 325 }
+// { dg-error "static assertion failed" "" { target *-*-* } 333 }
diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc
index 0a4b1c3..393f29d 100644
--- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc
@@ -22,4 +22,4 @@
typedef std::tuple_element<1, std::array<int, 1>>::type type;
-// { dg-error "static assertion failed" "" { target *-*-* } 365 }
+// { dg-error "static assertion failed" "" { target *-*-* } 0 }
diff --git a/libstdc++-v3/testsuite/25_algorithms/adjacent_find/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/adjacent_find/constexpr.cc
new file mode 100644
index 0000000..e62f43c
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/adjacent_find/constexpr.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr std::array<int, 12> car{{0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 9, 11}};
+
+constexpr auto out0x = std::adjacent_find(car.begin(), car.end());
+
+constexpr auto out1x = std::adjacent_find(car.begin(), car.end(),
+ std::equal_to<int>());
+
+constexpr bool
+test()
+{
+ return out0x == car.begin() + 6 && out1x == car.begin() + 6;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/all_of/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/all_of/constexpr.cc
new file mode 100644
index 0000000..e3d187c
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/all_of/constexpr.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr std::array<int, 6> cae{{0, 2, 4, 6, 8, 10}};
+
+constexpr auto out2 = std::all_of(cae.begin(), cae.end(),
+ [](int i){ return i % 2 == 0; });
+
+constexpr bool
+test()
+{
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/any_of/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/any_of/constexpr.cc
new file mode 100644
index 0000000..0ff427c
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/any_of/constexpr.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ const auto out3 = std::any_of(ca0.begin(), ca0.end(),
+ [](int i){ return i % 2 == 0; });
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/binary_search/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/binary_search/constexpr.cc
new file mode 100644
index 0000000..aaa4112
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/binary_search/constexpr.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ const auto out4 = std::binary_search(ca0.begin(), ca0.end(), 5);
+
+ const auto out5 = std::binary_search(ca0.begin(), ca0.end(), 5,
+ std::equal_to<int>());
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/constexpr_macro.cc b/libstdc++-v3/testsuite/25_algorithms/constexpr_macro.cc
new file mode 100644
index 0000000..07808ee
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/constexpr_macro.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <version>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing in <version>"
+#elif __cpp_lib_constexpr_algorithms != 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/58982.cc b/libstdc++-v3/testsuite/25_algorithms/copy/58982.cc
index b0366e96..826a35f 100644
--- a/libstdc++-v3/testsuite/25_algorithms/copy/58982.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/copy/58982.cc
@@ -36,6 +36,7 @@ void
test01(T* result)
{
T t[1];
- std::copy(t, t+1, result); // { dg-error "here" }
+ std::copy(t, t+1, result); // { dg-error "here|deleted" }
}
// { dg-prune-output "not assignable" }
+// { dg-prune-output "use of deleted" }
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/copy/constexpr.cc
new file mode 100644
index 0000000..9a4aa25
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/copy/constexpr.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ std::array<int, 12> ma0{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+
+ const auto out6 = std::copy(ca0.begin(), ca0.begin() + 8, ma0.begin() + 2);
+
+ return out6 == ma0.begin() + 10;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/move_iterators/69478.cc b/libstdc++-v3/testsuite/25_algorithms/copy/move_iterators/69478.cc
index 25e8110..293927d 100644
--- a/libstdc++-v3/testsuite/25_algorithms/copy/move_iterators/69478.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/copy/move_iterators/69478.cc
@@ -37,3 +37,4 @@ test01()
trivial_rvalstruct a[1], b[1];
copy(std::make_move_iterator(a), std::make_move_iterator(a + 1), b);
}
+// { dg-prune-output "use of deleted" }
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_backward/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/copy_backward/constexpr.cc
new file mode 100644
index 0000000..25cf97f
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/copy_backward/constexpr.cc
@@ -0,0 +1,42 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ std::array<int, 12> ma0{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+ const auto out7 = std::copy_backward(ca0.begin(), ca0.begin() + 8,
+ ma0.begin() + 10);
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_backward/move_iterators/69478.cc b/libstdc++-v3/testsuite/25_algorithms/copy_backward/move_iterators/69478.cc
index fd7601c..84d6793 100644
--- a/libstdc++-v3/testsuite/25_algorithms/copy_backward/move_iterators/69478.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/copy_backward/move_iterators/69478.cc
@@ -37,3 +37,4 @@ test01()
trivial_rvalstruct a[1], b[1];
copy_backward(std::make_move_iterator(a), std::make_move_iterator(a+1), b);
}
+// { dg-prune-output "use of deleted" }
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_if/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/copy_if/constexpr.cc
new file mode 100644
index 0000000..59deacf
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/copy_if/constexpr.cc
@@ -0,0 +1,42 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+constexpr bool
+test()
+{
+ std::array<int, 12> ma0{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+ const auto out1 = std::copy_if(ca0.begin(), ca0.end(), ma0.begin(),
+ [](int i){ return i % 2 == 1; });
+
+ return out1 == ma0.begin() + 6;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_n/58982.cc b/libstdc++-v3/testsuite/25_algorithms/copy_n/58982.cc
index 790d407..bd08be4 100644
--- a/libstdc++-v3/testsuite/25_algorithms/copy_n/58982.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/copy_n/58982.cc
@@ -36,6 +36,7 @@ void
test01(T* result)
{
T t[1];
- std::copy_n(t, 1, result); // { dg-error "here" }
+ std::copy_n(t, 1, result); // { dg-error "here|deleted" }
}
// { dg-prune-output "not assignable" }
+// { dg-prune-output "use of deleted" }
diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_n/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/copy_n/constexpr.cc
new file mode 100644
index 0000000..72bc1e6
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/copy_n/constexpr.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+constexpr bool
+test()
+{
+ std::array<int, 12> ma0{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+ std::copy_n(ca0.begin(), 12, ma0.begin());
+
+ return ma0[3] == ca0[3];
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/count/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/count/constexpr.cc
new file mode 100644
index 0000000..d7cd56d
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/count/constexpr.cc
@@ -0,0 +1,40 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ const auto out8 = std::count(ca0.begin(), ca0.end(), 6);
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/count_if/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/count_if/constexpr.cc
new file mode 100644
index 0000000..2a1c7d0
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/count_if/constexpr.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+constexpr auto out9 = std::count_if(ca0.begin(), ca0.end(),
+ [](int i){ return i % 2 == 0; });
+
+constexpr bool
+test()
+{
+ return out9 == 6;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/equal/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/equal/constexpr.cc
new file mode 100644
index 0000000..a95704d
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/equal/constexpr.cc
@@ -0,0 +1,45 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ constexpr std::array<int, 12> ca1{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ constexpr std::array<int, 12> cas{{3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}};
+
+ const auto outa = std::equal(ca0.begin(), ca0.end(), ca1.begin());
+
+ const auto outb = std::equal(ca0.begin(), ca0.end(), cas.begin(),
+ [](int i, int j){ return i + 3 == j; });
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/equal_range/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/equal_range/constexpr.cc
new file mode 100644
index 0000000..2d57096
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/equal_range/constexpr.cc
@@ -0,0 +1,40 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> car{{0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 9, 11}};
+
+ const auto outc = std::equal_range(car.begin(), car.end(), 6);
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/fill/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/fill/constexpr.cc
new file mode 100644
index 0000000..31e3568
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/fill/constexpr.cc
@@ -0,0 +1,39 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ std::array<int, 12> ma0{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+ std::fill(ma0.begin(), ma0.end(), 66);
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/fill_n/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/fill_n/constexpr.cc
new file mode 100644
index 0000000..a201191
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/fill_n/constexpr.cc
@@ -0,0 +1,40 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ std::array<int, 12> ma0{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+
+ const auto outd = std::fill_n(ma0.begin(), 6, 77);
+
+ return outd == ma0.begin() + 6;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/find/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/find/constexpr.cc
new file mode 100644
index 0000000..7d59de2
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/find/constexpr.cc
@@ -0,0 +1,40 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+constexpr auto oute = std::find(ca0.begin(), ca0.end(), 5);
+
+constexpr bool
+test()
+{
+ return oute == ca0.begin() + 5;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/find_end/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/find_end/constexpr.cc
new file mode 100644
index 0000000..88d6cc7
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/find_end/constexpr.cc
@@ -0,0 +1,47 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ constexpr std::array<int, 3> cam{{4, 5, 6}};
+ constexpr std::array<int, 3> camm{{-4, -5, -6}};
+
+ const auto outf = std::find_end(ca0.begin(), ca0.end(),
+ cam.begin(), cam.end());
+
+ const auto outg = std::find_end(ca0.begin(), ca0.end(),
+ camm.begin(), camm.end(),
+ [](int i, int j){ return i + 1 == -j; });
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/find_first_of/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/find_first_of/constexpr.cc
new file mode 100644
index 0000000..99cbed2
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/find_first_of/constexpr.cc
@@ -0,0 +1,46 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+constexpr std::array<int, 12> cas{{3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}};
+
+constexpr auto outh = std::find_first_of(ca0.begin(), ca0.end(),
+ cas.begin(), cas.end());
+
+constexpr auto outi = std::find_first_of(ca0.begin(), ca0.end(),
+ cas.begin(), cas.end(),
+ [](int i, int j){ return i + 1 == j; });
+
+constexpr bool
+test()
+{
+ return outh == ca0.begin() + 3 && outi == ca0.begin() + 2;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/find_if/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/find_if/constexpr.cc
new file mode 100644
index 0000000..395a21e
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/find_if/constexpr.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ const auto outj = std::find_if(ca0.begin(), ca0.end(),
+ [](int i){ return i == 6; });
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/find_if_not/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/find_if_not/constexpr.cc
new file mode 100644
index 0000000..5b1b9c3
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/find_if_not/constexpr.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+constexpr auto outk = std::find_if_not(ca0.begin(), ca0.end(),
+ [](int i){ return i <= 6; });
+
+constexpr bool
+test()
+{
+ return outk == ca0.begin() + 7;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/for_each/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/for_each/constexpr.cc
new file mode 100644
index 0000000..d900ef4
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/for_each/constexpr.cc
@@ -0,0 +1,42 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+constexpr bool
+test()
+{
+ int tot = 0;
+ auto sum = [&total = tot](int i){ total += i; };
+ auto sum2 = std::for_each(ca0.begin(), ca0.end(), sum);
+
+ return tot == 66;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/generate/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/generate/constexpr.cc
new file mode 100644
index 0000000..b0e26b69d
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/generate/constexpr.cc
@@ -0,0 +1,40 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ std::array<int, 12> ma0{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+
+ std::generate(ma0.begin(), ma0.begin() + 6, [](){ return 42; });
+
+ return ma0[5] == 42;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/generate_n/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/generate_n/constexpr.cc
new file mode 100644
index 0000000..f2a203e
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/generate_n/constexpr.cc
@@ -0,0 +1,40 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ std::array<int, 12> ma0{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+
+ const auto outl = std::generate_n(ma0.begin(), 6, [](){ return 42; });
+
+ return outl == ma0.begin() + 6;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/headers/algorithm/synopsis.cc b/libstdc++-v3/testsuite/25_algorithms/headers/algorithm/synopsis.cc
index 3d4aee7..07dd7fb 100644
--- a/libstdc++-v3/testsuite/25_algorithms/headers/algorithm/synopsis.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/headers/algorithm/synopsis.cc
@@ -23,125 +23,154 @@ namespace std
{
// 25.1, non-modifying sequence operations:
template<typename _IIter, typename _Funct>
+ _GLIBCXX20_CONSTEXPR
_Funct
for_each(_IIter, _IIter, _Funct);
template<typename _IIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_IIter
find(_IIter, _IIter, const _Tp&);
template<typename _IIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_IIter
find_if(_IIter, _IIter, _Predicate);
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
bool
all_of(_IIter, _IIter, _Predicate);
template<typename _IIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
bool
any_of(_IIter, _IIter, _Predicate);
template<typename _IIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
bool
none_of(_IIter, _IIter, _Predicate);
template<typename _IIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_IIter
find_if_not(_IIter, _IIter, _Predicate);
template<typename _IIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
bool
is_partitioned(_IIter, _IIter, _Predicate);
template<typename _FIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_FIter
partition_point(_FIter, _FIter, _Predicate);
#endif
template<typename _FIter1, typename _FIter2>
+ _GLIBCXX20_CONSTEXPR
_FIter1
find_end(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_FIter1
find_end(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
template<typename _FIter1, typename _FIter2>
+ _GLIBCXX20_CONSTEXPR
_FIter1
find_first_of(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_FIter1
find_first_of(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
template<typename _FIter>
+ _GLIBCXX20_CONSTEXPR
_FIter
adjacent_find(_FIter, _FIter);
template<typename _FIter, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_FIter
adjacent_find(_FIter, _FIter, _BinaryPredicate);
template<typename _IIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
typename iterator_traits<_IIter>::difference_type
count(_IIter, _IIter, const _Tp&);
template<typename _IIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
typename iterator_traits<_IIter>::difference_type
count_if(_IIter, _IIter, _Predicate);
template<typename _IIter1, typename _IIter2>
+ _GLIBCXX20_CONSTEXPR
pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
template<typename _IIter1, typename _IIter2>
+ _GLIBCXX20_CONSTEXPR
bool
equal(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
bool
equal(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
template<typename _FIter1, typename _FIter2>
+ _GLIBCXX20_CONSTEXPR
_FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
template<typename _FIter, typename _Size, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_FIter
search_n(_FIter, _FIter, _Size, const _Tp&);
template<typename _FIter, typename _Size, typename _Tp,
typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_FIter
search_n(_FIter, _FIter, _Size, const _Tp&, _BinaryPredicate);
// 25.2, modifying sequence operations:
// 25.2.1, copy:
template<typename _IIter, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
copy(_IIter, _IIter, _OIter);
template<typename _BIter1, typename _BIter2>
+ _GLIBCXX20_CONSTEXPR
_BIter2
copy_backward (_BIter1, _BIter1, _BIter2);
// 25.2.2, swap:
#if __cplusplus < 201103L
template<typename _Tp>
+ _GLIBCXX20_CONSTEXPR
void
swap(_Tp&, _Tp& b);
template<typename _Tp, size_t _Nm>
+ _GLIBCXX20_CONSTEXPR
void
swap(_Tp (&)[_Nm], _Tp (&)[_Nm]);
#else
@@ -151,114 +180,141 @@ namespace std
#endif
template<typename _FIter1, typename _FIter2>
+ _GLIBCXX20_CONSTEXPR
_FIter2
swap_ranges(_FIter1 first1, _FIter1, _FIter2);
template<typename _FIter1, typename _FIter2>
+ _GLIBCXX20_CONSTEXPR
void
iter_swap(_FIter1, _FIter2 b);
template<typename _IIter, typename _OIter, typename _UnaryOperation>
+ _GLIBCXX20_CONSTEXPR
_OIter
transform(_IIter, _IIter, _OIter, _UnaryOperation op);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _BinaryOperation>
+ _GLIBCXX20_CONSTEXPR
_OIter
transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation);
template<typename _FIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
void
replace(_FIter, _FIter, const _Tp&, const _Tp&);
template<typename _FIter, typename _Predicate, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
void
replace_if(_FIter, _FIter, _Predicate, const _Tp&);
template<typename _IIter, typename _OIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_OIter
replace_copy(_IIter, _IIter, _OIter, const _Tp&, const _Tp&);
template<typename _Iter, typename _OIter, typename _Predicate, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_OIter
replace_copy_if(_Iter, _Iter, _OIter, _Predicate, const _Tp&);
template<typename _FIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
void
fill(_FIter, _FIter, const _Tp&);
template<typename _OIter, typename _Size, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
void
fill_n(_OIter, _Size n, const _Tp&);
template<typename _FIter, typename _Generator>
+ _GLIBCXX20_CONSTEXPR
void
generate(_FIter, _FIter, _Generator);
template<typename _OIter, typename _Size, typename _Generator>
+ _GLIBCXX20_CONSTEXPR
void
generate_n(_OIter, _Size, _Generator);
template<typename _FIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_FIter
remove(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_FIter
remove_if(_FIter, _FIter, _Predicate);
template<typename _IIter, typename _OIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_OIter
remove_copy(_IIter, _IIter, _OIter, const _Tp&);
template<typename _IIter, typename _OIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_OIter
remove_copy_if(_IIter, _IIter, _OIter, _Predicate);
#if __cplusplus >= 201103L
template<typename _IIter, typename _OIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_OIter
copy_if(_IIter, _IIter, _OIter, _Predicate);
template<typename _IIter, typename _Size, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
copy_n(_IIter, _Size, _OIter);
template<typename _IIter, typename _OIter1,
typename _OIter2, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
pair<_OIter1, _OIter2>
partition_copy(_IIter, _IIter, _OIter1, _OIter2, _Predicate);
#endif
template<typename _FIter>
+ _GLIBCXX20_CONSTEXPR
_FIter
unique(_FIter, _FIter);
template<typename _FIter, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_FIter
unique(_FIter, _FIter, _BinaryPredicate);
template<typename _IIter, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
unique_copy(_IIter, _IIter, _OIter);
template<typename _IIter, typename _OIter, typename _BinaryPredicate>
+ _GLIBCXX20_CONSTEXPR
_OIter
unique_copy(_IIter, _IIter, _OIter, _BinaryPredicate);
template<typename _BIter>
+ _GLIBCXX20_CONSTEXPR
void
reverse(_BIter, _BIter);
template<typename _BIter, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
reverse_copy(_BIter, _BIter, _OIter);
template<typename _FIter>
+ _GLIBCXX20_CONSTEXPR
void
rotate(_FIter, _FIter, _FIter);
template<typename _FIter, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
rotate_copy (_FIter, _FIter, _FIter, _OIter);
@@ -272,6 +328,7 @@ namespace std
// 25.2.12, partitions:
template<typename _BIter, typename _Predicate>
+ _GLIBCXX20_CONSTEXPR
_BIter
partition(_BIter, _BIter, _Predicate);
@@ -282,10 +339,12 @@ namespace std
// 25.3, sorting and related operations:
// 25.3.1, sorting:
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
void
sort(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
sort(_RAIter, _RAIter, _Compare);
@@ -298,69 +357,85 @@ namespace std
stable_sort(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
void
partial_sort(_RAIter, _RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
partial_sort(_RAIter, _RAIter, _RAIter, _Compare);
template<typename _IIter, typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
_RAIter
partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter);
template<typename _IIter, typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_RAIter
partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter, _Compare);
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
void
nth_element(_RAIter, _RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
nth_element(_RAIter, _RAIter, _RAIter, _Compare);
// 25.3.3, binary search:
template<typename _FIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_FIter
lower_bound(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_FIter
lower_bound(_FIter, _FIter, const _Tp&, _Compare);
template<typename _FIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
_FIter
upper_bound(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_FIter
upper_bound(_FIter, _FIter, const _Tp&, _Compare);
template<typename _FIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
pair<_FIter, _FIter>
equal_range(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
pair<_FIter, _FIter>
equal_range(_FIter, _FIter, const _Tp&, _Compare);
template<typename _FIter, typename _Tp>
+ _GLIBCXX20_CONSTEXPR
bool
binary_search(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
binary_search(_FIter, _FIter, const _Tp&, _Compare);
// 25.3.4, merge:
template<typename _IIter1, typename _IIter2, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
@@ -374,113 +449,139 @@ namespace std
// 25.3.5, set operations:
template<typename _IIter1, typename _IIter2>
+ _GLIBCXX20_CONSTEXPR
bool
includes(_IIter1, _IIter1, _IIter2, _IIter2);
template<typename _IIter1, typename _IIter2, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
includes(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2,
_OIter, _Compare);
// 25.3.6, heap operations:
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
void
push_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
push_heap(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
void
pop_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
pop_heap(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
void
make_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
make_heap(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
void
sort_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
void
sort_heap(_RAIter, _RAIter, _Compare);
#if __cplusplus >= 201103L
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
bool
is_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
is_heap(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
+ _GLIBCXX20_CONSTEXPR
_RAIter
is_heap_until(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_RAIter
is_heap_until(_RAIter, _RAIter, _Compare);
template<typename _FIter>
+ _GLIBCXX20_CONSTEXPR
bool
is_sorted(_FIter, _FIter);
template<typename _FIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
is_sorted(_FIter, _FIter, _Compare);
template<typename _FIter>
+ _GLIBCXX20_CONSTEXPR
_FIter
is_sorted_until(_FIter, _FIter);
template<typename _FIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
_FIter
is_sorted_until(_FIter, _FIter, _Compare);
#endif
@@ -579,27 +680,33 @@ namespace std
#endif
template<typename _IIter1, typename _IIter2>
+ _GLIBCXX20_CONSTEXPR
bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2);
template<typename _IIter1, typename _IIter2, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
// 25.3.9, permutations
template<typename _BIter>
+ _GLIBCXX20_CONSTEXPR
bool
next_permutation(_BIter, _BIter);
template<typename _BIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
next_permutation(_BIter, _BIter, _Compare);
template<typename _BIter>
+ _GLIBCXX20_CONSTEXPR
bool
prev_permutation(_BIter, _BIter);
template<typename _BIter, typename _Compare>
+ _GLIBCXX20_CONSTEXPR
bool
prev_permutation(_BIter, _BIter, _Compare);
}
diff --git a/libstdc++-v3/testsuite/25_algorithms/is_heap/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/is_heap/constexpr.cc
new file mode 100644
index 0000000..5f25a30
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/is_heap/constexpr.cc
@@ -0,0 +1,47 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+// heap
+constexpr std::array<int, 23>
+ah{{22,
+ 21, 20,
+ 17, 16, 19, 18,
+ 11, 10, 9, 8, 15, 14, 13, 12, 3, 2, 1, 0, 7, 6, 5, 4}};
+
+constexpr auto outo = std::is_heap(ah.begin(), ah.end());
+
+constexpr auto outp = std::is_heap(ah.begin(), ah.end(), std::less<int>());
+
+constexpr bool
+test()
+{
+ return outo && outp;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/is_heap_until/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/is_heap_until/constexpr.cc
new file mode 100644
index 0000000..ddd4cdd
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/is_heap_until/constexpr.cc
@@ -0,0 +1,48 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+// heap
+constexpr std::array<int, 23>
+ahu{{22,
+ 21, 20,
+ 17, 16, 19, 18,//v
+ 11, 10, 9, 8, 23, 14, 13, 12, 3, 2, 1, 0, 7, 6, 5, 4}};
+
+constexpr auto outq = std::is_heap_until(ahu.begin(), ahu.end());
+
+constexpr auto outr = std::is_heap_until(ahu.begin(), ahu.end(),
+ std::less<int>());
+
+constexpr bool
+test()
+{
+ return outq == ahu.begin() + 11 && outr == ahu.begin() + 11;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/is_partitioned/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/is_partitioned/constexpr.cc
new file mode 100644
index 0000000..527746f
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/is_partitioned/constexpr.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> caeo{{0, 2, 4, 6, 8, 10, 1, 3, 5, 7, 9, 11}};
+
+ const auto outs = std::is_partitioned(caeo.begin(), caeo.end(),
+ [](int i){ return i % 2 == 0; });
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/is_permutation/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/is_permutation/constexpr.cc
new file mode 100644
index 0000000..3f5df35
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/is_permutation/constexpr.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ constexpr std::array<int, 12> cap{{2, 1, 3, 6, 7, 5, 4, 8, 10, 9, 0, 11}};
+
+ const auto outt = std::is_permutation(ca0.begin(), ca0.end(), cap.begin());
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/is_sorted/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/is_sorted/constexpr.cc
new file mode 100644
index 0000000..623d72c
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/is_sorted/constexpr.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+constexpr auto outv = std::is_sorted(ca0.begin(), ca0.end());
+
+constexpr auto outw = std::is_sorted(ca0.begin(), ca0.end(),
+ std::equal_to<int>());
+
+constexpr bool
+test()
+{
+ return outv && outw;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/is_sorted_until/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/is_sorted_until/constexpr.cc
new file mode 100644
index 0000000..f109ee8
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/is_sorted_until/constexpr.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> aus{{0, 1, 2, 3, 4, 5, 66, 7, 8, 9, 10, 11}};
+
+ const auto outx = std::is_sorted_until(aus.begin(), aus.end());
+
+ const auto outy = std::is_sorted_until(aus.begin(), aus.end(),
+ std::less<int>());
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/iter_swap/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/iter_swap/constexpr.cc
new file mode 100644
index 0000000..9444bf4
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/iter_swap/constexpr.cc
@@ -0,0 +1,42 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ std::array<int, 12> ar0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ std::iter_swap(ar0.begin() + 2, ar0.begin() + 5);
+
+ return ok = ar0[2] == 5 && ar0[5] == 2;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/lexicographical_compare/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/lexicographical_compare/constexpr.cc
new file mode 100644
index 0000000..93dee5d
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/lexicographical_compare/constexpr.cc
@@ -0,0 +1,46 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ constexpr std::array<int, 12> ca1{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ const auto outz = !std::lexicographical_compare(ca0.begin(), ca0.end(),
+ ca1.begin(), ca1.end());
+
+ const auto outaa = !std::lexicographical_compare(ca0.begin(), ca0.end(),
+ ca1.begin(), ca1.end(),
+ std::less<int>());
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/lower_bound/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/lower_bound/constexpr.cc
new file mode 100644
index 0000000..f8c191b
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/lower_bound/constexpr.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ const auto outbb = std::lower_bound(ca0.begin(), ca0.end(), 6);
+
+ const auto outcc = std::lower_bound(ca0.begin(), ca0.end(), 6,
+ std::less<int>());
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/make_heap/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/make_heap/constexpr.cc
new file mode 100644
index 0000000..426310a
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/make_heap/constexpr.cc
@@ -0,0 +1,47 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ std::array<int, 23>
+ ah{{0,
+ 1, 2,
+ 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}};
+
+ std::make_heap(ah.begin(), ah.begin() + 17);
+ ok = ok && std::is_heap(ah.begin(), ah.begin() + 17);
+
+ return ok;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/merge/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/merge/constexpr.cc
new file mode 100644
index 0000000..e240e44
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/merge/constexpr.cc
@@ -0,0 +1,48 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ constexpr std::array<int, 12> cas{{3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}};
+ constexpr std::array<int, 3> camm{{-4, -5, -6}};
+ std::array<int, 24> out0{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+ const auto outdd = std::merge(ca0.begin(), ca0.end(),
+ cas.begin(), cas.end(), out0.begin());
+
+ const auto outee = std::merge(ca0.begin(), ca0.end(),
+ camm.begin(), camm.end(), out0.begin(),
+ [](int i, int j){ return i < -j; });
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/mismatch/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/mismatch/constexpr.cc
new file mode 100644
index 0000000..946199b
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/mismatch/constexpr.cc
@@ -0,0 +1,44 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ constexpr std::array<int, 12> cax{{0, 1, 2, 3, 4, 5, 66, 7, 8, 99, 10, 11}};
+
+ const auto outff = std::mismatch(ca0.begin(), ca0.end(), cax.begin());
+
+ const auto outgg = std::mismatch(ca0.begin(), ca0.end(), cax.begin(),
+ std::equal_to<int>());
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/move/69478.cc b/libstdc++-v3/testsuite/25_algorithms/move/69478.cc
index ba18f00..c7f9f88 100644
--- a/libstdc++-v3/testsuite/25_algorithms/move/69478.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/move/69478.cc
@@ -37,3 +37,4 @@ test01()
trivial_rvalstruct a[1], b[1];
std::move(a, a + 1, b);
}
+// { dg-prune-output "use of deleted" }
diff --git a/libstdc++-v3/testsuite/25_algorithms/move_backward/69478.cc b/libstdc++-v3/testsuite/25_algorithms/move_backward/69478.cc
index 683d7950..3a6e465 100644
--- a/libstdc++-v3/testsuite/25_algorithms/move_backward/69478.cc
+++ b/libstdc++-v3/testsuite/25_algorithms/move_backward/69478.cc
@@ -37,3 +37,4 @@ test01()
trivial_rvalstruct a[1], b[1];
std::move_backward(a, a + 1, b);
}
+// { dg-prune-output "use of deleted" }
diff --git a/libstdc++-v3/testsuite/25_algorithms/next_permutation/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/next_permutation/constexpr.cc
new file mode 100644
index 0000000..4b5c218
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/next_permutation/constexpr.cc
@@ -0,0 +1,42 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ std::array<int, 12> ar0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ std::next_permutation(ar0.begin(), ar0.end());
+
+ return ok = ar0[11] == 10 && ar0[10] == 11;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/none_of/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/none_of/constexpr.cc
new file mode 100644
index 0000000..2d02ada
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/none_of/constexpr.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ const auto outhh = std::none_of(ca0.begin(), ca0.end(),
+ [](int i){ return i > 12; });
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/nth_element/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/nth_element/constexpr.cc
new file mode 100644
index 0000000..1c43074
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/nth_element/constexpr.cc
@@ -0,0 +1,47 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ std::array<int, 12> ar0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ std::nth_element(ar0.begin(), ar0.begin() + 5, ar0.end());
+ ok = ok && ar0[5] == 5;
+
+ std::sort(ar0.begin(), ar0.end(), std::greater<>());
+ std::nth_element(ar0.begin(), ar0.begin() + 5, ar0.end(), std::greater<>());
+ ok = ok && ar0[5] == 6;
+
+ return ok;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/partial_sort/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/partial_sort/constexpr.cc
new file mode 100644
index 0000000..b31be71
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/partial_sort/constexpr.cc
@@ -0,0 +1,46 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ std::array<int, 12> ar0{{0, 1, 7, 8, 9, 2, 3, 4, 5, 6, 10, 11}};
+
+ std::partial_sort(ar0.begin(), ar0.begin() + 5, ar0.end());
+ ok = ok && ar0[0] == 0 && ar0[4] == 4;
+
+ std::partial_sort(ar0.begin(), ar0.begin() + 5, ar0.end(), std::greater<>());
+ ok = ok && ar0[0] == 11 && ar0[4] == 7;
+
+ return ok;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/partial_sort_copy/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/partial_sort_copy/constexpr.cc
new file mode 100644
index 0000000..b7f538f
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/partial_sort_copy/constexpr.cc
@@ -0,0 +1,47 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ const std::array<int, 12> ar0{{0, 7, 8, 9, 1, 2, 5, 6, 10, 3, 4, 11}};
+ std::array<int, 12> or0{{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
+
+ std::partial_sort_copy(ar0.begin() + 5, ar0.begin() + 10,
+ or0.begin(), or0.begin() + 5);
+
+ std::partial_sort_copy(ar0.begin() + 5, ar0.begin() + 10,
+ or0.begin(), or0.begin() + 5, std::greater<>());
+
+ return ok;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/partition/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/partition/constexpr.cc
new file mode 100644
index 0000000..bd678af
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/partition/constexpr.cc
@@ -0,0 +1,44 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ std::array<int, 12> ar0{{10, 0, 5, 1, 2, 6, 7, 8, 3, 4, 9, 11}};
+
+ auto iter1 = std::partition(ar0.begin(), ar0.end(),
+ [](int i){ return i < 7; });
+ ok = ok && *iter1 == 8;
+
+ return ok;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/partition_copy/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/partition_copy/constexpr.cc
new file mode 100644
index 0000000..11c42ee
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/partition_copy/constexpr.cc
@@ -0,0 +1,44 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ std::array<int, 24> out0{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+ std::array<int, 24> out1{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+ const auto outii = std::partition_copy(ca0.begin(), ca0.end(),
+ out0.begin(), out1.begin(),
+ [](int i){ return i % 2 == 0; });
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/partition_point/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/partition_point/constexpr.cc
new file mode 100644
index 0000000..4ba8284
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/partition_point/constexpr.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr std::array<int, 12> caeo{{0, 2, 4, 6, 8, 10, 1, 3, 5, 7, 9, 11}};
+
+constexpr bool
+test()
+{
+ const auto outjj = std::partition_point(caeo.begin(), caeo.end(),
+ [](int i){ return i % 2 == 0; });
+
+ return outjj == caeo.begin() + 6;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/pop_heap/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/pop_heap/constexpr.cc
new file mode 100644
index 0000000..ff9ca7bb
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/pop_heap/constexpr.cc
@@ -0,0 +1,53 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ std::array<int, 23>
+ ah{{0,
+ 1, 2,
+ 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}};
+
+ std::make_heap(ah.begin(), ah.end());
+ ok = ok && std::is_heap(ah.begin(), ah.end());
+
+ std::pop_heap(ah.begin(), ah.end());
+ std::pop_heap(ah.begin(), ah.end() - 1);
+ std::pop_heap(ah.begin(), ah.end() - 2);
+ ok = ok && std::is_heap(ah.begin(), ah.end() - 3)
+ && !std::is_heap(ah.begin(), ah.end());
+
+ return ok;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/prev_permutation/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/prev_permutation/constexpr.cc
new file mode 100644
index 0000000..a3a038c
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/prev_permutation/constexpr.cc
@@ -0,0 +1,42 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ std::array<int, 12> ar0{{1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ std::prev_permutation(ar0.begin(), ar0.end());
+
+ return ok = ar0[0] == 0;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/push_heap/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/push_heap/constexpr.cc
new file mode 100644
index 0000000..04b5688
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/push_heap/constexpr.cc
@@ -0,0 +1,52 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ std::array<int, 23>
+ ah{{0,
+ 1, 2,
+ 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}};
+
+ std::make_heap(ah.begin(), ah.end() - 3);
+ ok = ok && std::is_heap(ah.begin(), ah.end() - 3);
+
+ std::push_heap(ah.begin(), ah.end() - 2);
+ std::push_heap(ah.begin(), ah.end() - 1);
+ std::push_heap(ah.begin(), ah.end());
+ ok = ok && std::is_heap(ah.begin(), ah.end());
+
+ return ok;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/remove/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/remove/constexpr.cc
new file mode 100644
index 0000000..580ac10
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/remove/constexpr.cc
@@ -0,0 +1,40 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ std::array<int, 12> ar4{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ const auto outkk = std::remove(ar4.begin(), ar4.end(), 7);
+
+ return outkk == ar4.begin() + 11;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/remove_copy/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/remove_copy/constexpr.cc
new file mode 100644
index 0000000..a20e529
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/remove_copy/constexpr.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ std::array<int, 24> out0{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+ const auto outmm = std::remove_copy(ca0.begin(), ca0.end(), out0.begin(), 6);
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/remove_copy_if/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/remove_copy_if/constexpr.cc
new file mode 100644
index 0000000..0758d10
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/remove_copy_if/constexpr.cc
@@ -0,0 +1,42 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ std::array<int, 24> out0{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+ const auto outnn = std::remove_copy_if(ca0.begin(), ca0.end(), out0.begin(),
+ [](int i){ return i == 7; });
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/remove_if/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/remove_if/constexpr.cc
new file mode 100644
index 0000000..e8c0048
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/remove_if/constexpr.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ std::array<int, 12> ac2{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ const auto outll = std::remove_if(ac2.begin(), ac2.end(),
+ [](int i){ return i == 7; });
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/replace_copy/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/replace_copy/constexpr.cc
new file mode 100644
index 0000000..754b879
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/replace_copy/constexpr.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+constexpr bool
+test()
+{
+ std::array<int, 24> out0{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+ const auto outoo = std::replace_copy(ca0.begin(), ca0.end(),
+ out0.begin(), 6, 66);
+
+ return outoo == out0.begin() + (ca0.end() - ca0.begin());
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/replace_copy_if/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/replace_copy_if/constexpr.cc
new file mode 100644
index 0000000..1fa6bb0
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/replace_copy_if/constexpr.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+constexpr bool
+test()
+{
+ std::array<int, 24> out0{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+ const auto outpp = std::replace_copy_if(ca0.begin(), ca0.end(),
+ out0.begin(),
+ [](int i){ return i < 6; }, 66);
+
+ return outpp == out0.begin() + (ca0.end() - ca0.begin());
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/replace_if/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/replace_if/constexpr.cc
new file mode 100644
index 0000000..1dc28e1
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/replace_if/constexpr.cc
@@ -0,0 +1,40 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ std::array<int, 12> ar0{{0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 9, 11}};
+
+ std::replace_if(ar0.begin(), ar0.end(), [](int i){ return i % 2 == 1; }, 42);
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/reverse/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/reverse/constexpr.cc
new file mode 100644
index 0000000..8e1065b
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/reverse/constexpr.cc
@@ -0,0 +1,41 @@
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ std::array<int, 12> ar0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ std::reverse(ar0.begin() + 2, ar0.begin() + 9);
+
+ return ar0[2] == 8 && ar0[8] == 2;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/reverse_copy/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/reverse_copy/constexpr.cc
new file mode 100644
index 0000000..2240109
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/reverse_copy/constexpr.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ std::array<int, 24> out0{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+ const auto outqq = std::reverse_copy(ca0.rbegin(), ca0.rend(), out0.begin());
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/rotate/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/rotate/constexpr.cc
new file mode 100644
index 0000000..b586287
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/rotate/constexpr.cc
@@ -0,0 +1,41 @@
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ std::array<int, 12> ar0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ std::rotate(ar0.begin(), ar0.begin() + 5, ar0.end());
+
+ return ar0[0] == 5 && ar0[5] == 10;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/rotate_copy/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/rotate_copy/constexpr.cc
new file mode 100644
index 0000000..63bca00
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/rotate_copy/constexpr.cc
@@ -0,0 +1,42 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ std::array<int, 24> out0{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+ const auto outrr = std::rotate_copy(ca0.begin(), ca0.begin() + 6,
+ ca0.end(), out0.begin());
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/search/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/search/constexpr.cc
new file mode 100644
index 0000000..a611c1c
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/search/constexpr.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ constexpr std::array<int, 3> cam{{4, 5, 6}};
+
+ const auto outtt = std::search(ca0.begin(), ca0.end(),
+ cam.begin(), cam.end(),
+ std::equal_to<int>());
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/search_n/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/search_n/constexpr.cc
new file mode 100644
index 0000000..ac33920
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/search_n/constexpr.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr std::array<int, 12> car{{0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 9, 11}};
+
+constexpr auto outuu = std::search_n(car.begin(), car.end(), 2, 6);
+
+constexpr auto outuv = std::search_n(car.begin(), car.end(), 2, 9,
+ [](int i, int j){ return i == j; });
+
+constexpr bool
+test()
+{
+ return outuu == car.begin() + 6 && outuv == car.begin() + 9 ;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/set_difference/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/set_difference/constexpr.cc
new file mode 100644
index 0000000..ff913ea
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/set_difference/constexpr.cc
@@ -0,0 +1,47 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ constexpr std::array<int, 12> cas{{3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}};
+ std::array<int, 24> out0{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+ const auto outvv = std::set_difference(ca0.begin(), ca0.end(),
+ cas.begin(), cas.end(), out0.begin());
+
+ const auto outww = std::set_difference(ca0.begin(), ca0.end(),
+ cas.begin(), cas.end(),
+ out0.begin(), std::less<int>());
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/set_intersection/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/set_intersection/constexpr.cc
new file mode 100644
index 0000000..f1a95a2
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/set_intersection/constexpr.cc
@@ -0,0 +1,48 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ constexpr std::array<int, 12> cas{{3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}};
+ std::array<int, 24> out0{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+ const auto outxx = std::set_intersection(ca0.begin(), ca0.end(),
+ cas.begin(), cas.end(),
+ out0.begin());
+
+ const auto outyy = std::set_intersection(ca0.begin(), ca0.end(),
+ cas.begin(), cas.end(),
+ out0.begin(), std::less<int>());
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/set_symmetric_difference/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/set_symmetric_difference/constexpr.cc
new file mode 100644
index 0000000..ff913ea
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/set_symmetric_difference/constexpr.cc
@@ -0,0 +1,47 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ constexpr std::array<int, 12> cas{{3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}};
+ std::array<int, 24> out0{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+ const auto outvv = std::set_difference(ca0.begin(), ca0.end(),
+ cas.begin(), cas.end(), out0.begin());
+
+ const auto outww = std::set_difference(ca0.begin(), ca0.end(),
+ cas.begin(), cas.end(),
+ out0.begin(), std::less<int>());
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/set_union/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/set_union/constexpr.cc
new file mode 100644
index 0000000..61d3f1e
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/set_union/constexpr.cc
@@ -0,0 +1,47 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ constexpr std::array<int, 12> cas{{3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}};
+ std::array<int, 24> out0{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+ const auto out11 = std::set_union(ca0.begin(), ca0.end(),
+ cas.begin(), cas.end(), out0.begin());
+
+ const auto out22 = std::set_union(ca0.begin(), ca0.end(),
+ cas.begin(), cas.end(),
+ out0.begin(), std::less<int>());
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/sort/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/sort/constexpr.cc
new file mode 100644
index 0000000..7b91b75
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/sort/constexpr.cc
@@ -0,0 +1,46 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ std::array<int, 12> ar0{{10, 0, 1, 2, 5, 6, 7, 8, 3, 4, 9, 11}};
+
+ std::sort(ar0.begin(), ar0.end());
+ ok = ok && std::is_sorted(ar0.begin(), ar0.end());
+
+ std::sort(ar0.begin(), ar0.end(), std::greater<>());
+ ok = ok && std::is_sorted(ar0.begin(), ar0.end(), std::greater<>());
+
+ return ok;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/sort_heap/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/sort_heap/constexpr.cc
new file mode 100644
index 0000000..fa6e309
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/sort_heap/constexpr.cc
@@ -0,0 +1,56 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ std::array<int, 23>
+ ah{{0,
+ 1, 2,
+ 3, 4, 5, 6,
+ 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22}};
+
+ std::make_heap(ah.begin(), ah.begin() + 17);
+ ok = ok && std::is_heap(ah.begin(), ah.begin() + 17);
+
+ std::sort_heap(ah.begin(), ah.begin() + 17);
+ ok = ok && std::is_sorted(ah.begin(), ah.begin() + 17);
+
+ std::make_heap(ah.begin(), ah.begin() + 17, std::greater<>());
+ ok = ok && std::is_heap(ah.begin(), ah.begin() + 17, std::greater<>());
+
+ std::sort_heap(ah.begin(), ah.begin() + 17, std::greater<>());
+ ok = ok && std::is_sorted(ah.begin(), ah.begin() + 17, std::greater<>());
+
+ return ok;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/swap/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/swap/constexpr.cc
new file mode 100644
index 0000000..7f2d1f8
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/swap/constexpr.cc
@@ -0,0 +1,47 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ double asc = 3.1415;
+ double bsc = 2.7182;
+ std::swap(asc, bsc);
+ ok = ok && asc == 2.7182 && bsc == 3.1415;
+
+ float arr[5]{0.0f, 1.0f, 2.0f, 3.0f, 4.0f};
+ float brr[5]{5.0f, 6.0f, 7.0f, 8.0f, 9.0f};
+ std::swap(arr, brr);
+ ok = ok && arr[2] == 7.0f && brr[2] == 2.0f;
+
+ return ok;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/swap_ranges/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/swap_ranges/constexpr.cc
new file mode 100644
index 0000000..a99155b
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/swap_ranges/constexpr.cc
@@ -0,0 +1,44 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_swap_algorithms
+# error "Feature-test macro for constexpr swap algorithms missing"
+#elif __cpp_lib_constexpr_swap_algorithms < 201806L
+# error "Feature-test macro for constexpr swap algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ auto ok = true;
+
+ std::array<int, 12> ar0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+ std::array<int, 12> ar1{{11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}};
+
+ const auto out01 = std::swap_ranges(ar0.begin(), ar0.begin() + 5,
+ ar1.begin() + 2);
+
+ return ok = ar0[0] == 9 && ar1[2] == 0;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/transform/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/transform/constexpr.cc
new file mode 100644
index 0000000..03c6d71
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/transform/constexpr.cc
@@ -0,0 +1,47 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+constexpr bool
+test()
+{
+ std::array<int, 24> out0{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+ const auto out99 = std::transform(ca0.begin(), ca0.end(), out0.begin(),
+ [del = 6](int i){ return i + del; });
+
+ const auto out11 = std::transform(ca0.begin(), ca0.end(), ca0.begin(),
+ out0.begin(),
+ [](int i, int j){ return i + j; });
+
+ return out99 == out0.begin() + (ca0.end() - ca0.begin())
+ && out11 == out0.begin() + (ca0.end() - ca0.begin());
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/unique/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/unique/constexpr.cc
new file mode 100644
index 0000000..f90aaac
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/unique/constexpr.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ std::array<int, 12> ar1{{0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 9, 11}};
+ std::array<int, 12> ar2{{0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 9, 11}};
+
+ const auto out33 = std::unique(ar1.begin(), ar1.end());
+
+ const auto out44 = std::unique(ar2.begin(), ar2.end(), std::equal_to<int>());
+
+ return out33 == ar1.begin() + 10 && out44 == ar2.begin() + 10;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/unique_copy/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/unique_copy/constexpr.cc
new file mode 100644
index 0000000..f13f388
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/unique_copy/constexpr.cc
@@ -0,0 +1,44 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ std::array<int, 12> ar3{{0, 1, 2, 3, 4, 5, 6, 6, 8, 9, 9, 11}};
+ std::array<int, 24> out0{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
+
+ const auto out55 = std::unique_copy(ar3.begin(), ar3.end(), out0.begin());
+
+ const auto out66 = std::unique_copy(ar3.begin(), ar3.end(), out0.begin(),
+ std::equal_to<int>());
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/25_algorithms/upper_bound/constexpr.cc b/libstdc++-v3/testsuite/25_algorithms/upper_bound/constexpr.cc
new file mode 100644
index 0000000..a0a8e25
--- /dev/null
+++ b/libstdc++-v3/testsuite/25_algorithms/upper_bound/constexpr.cc
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <algorithm>
+#include <array>
+
+#ifndef __cpp_lib_constexpr_algorithms
+# error "Feature-test macro for constexpr algorithms missing"
+#elif __cpp_lib_constexpr_algorithms < 201711L
+# error "Feature-test macro for constexpr algorithms has wrong value"
+#endif
+
+constexpr bool
+test()
+{
+ constexpr std::array<int, 12> ca0{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}};
+
+ const auto out77 = std::upper_bound(ca0.begin(), ca0.end(), 6);
+
+ const auto out88 = std::upper_bound(ca0.begin(), ca0.end(), 6,
+ std::less<int>());
+
+ return true;
+}
+
+static_assert(test());
diff --git a/libstdc++-v3/testsuite/20_util/endian/1.cc b/libstdc++-v3/testsuite/26_numerics/endian/1.cc
index 4faaba8..896a14c 100644
--- a/libstdc++-v3/testsuite/20_util/endian/1.cc
+++ b/libstdc++-v3/testsuite/26_numerics/endian/1.cc
@@ -18,7 +18,7 @@
// { dg-options "-std=gnu++2a" }
// { dg-do compile { target c++2a } }
-#include <type_traits>
+#include <bit>
static_assert( std::is_enum_v<std::endian> );
static_assert( std::endian::little != std::endian::big );
diff --git a/libstdc++-v3/testsuite/26_numerics/endian/2.cc b/libstdc++-v3/testsuite/26_numerics/endian/2.cc
new file mode 100644
index 0000000..474bae4
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/endian/2.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <bit>
+
+#ifndef __cpp_lib_endian
+# error "Feature-test macro for endian missing in <bit>"
+#elif __cpp_lib_endian != 201907L
+# error "Feature-test macro for endian has wrong value in <bit>"
+#endif
diff --git a/libstdc++-v3/testsuite/26_numerics/endian/3.cc b/libstdc++-v3/testsuite/26_numerics/endian/3.cc
new file mode 100644
index 0000000..a7af53d
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/endian/3.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <version>
+
+#ifndef __cpp_lib_endian
+# error "Feature-test macro for endian missing in <version>"
+#elif __cpp_lib_endian != 201907L
+# error "Feature-test macro for endian has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/26_numerics/endian/4.cc b/libstdc++-v3/testsuite/26_numerics/endian/4.cc
new file mode 100644
index 0000000..93bed38
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/endian/4.cc
@@ -0,0 +1,25 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do compile { target c++17_down } }
+
+#include <bit>
+#include <version>
+
+#ifdef __cpp_lib_endian
+# error "Feature-test macro for endian defined before C++20"
+#endif
diff --git a/libstdc++-v3/testsuite/26_numerics/numbers/1.cc b/libstdc++-v3/testsuite/26_numerics/numbers/1.cc
new file mode 100644
index 0000000..78d0a5f
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/numbers/1.cc
@@ -0,0 +1,99 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <numbers>
+
+#ifndef __cpp_lib_math_constants
+# error "Feature-test macro for math constants missing in <numbers>"
+#elif __cpp_lib_math_constants != 201907L
+# error "Feature-test macro for math constants has wrong value in <numbers>"
+#endif
+
+void
+test01()
+{
+ const double* d1 = &std::numbers::e_v<double>;
+ const double* d2 = &std::numbers::log2e_v<double>;
+ const double* d3 = &std::numbers::log10e_v<double>;
+ const double* d4 = &std::numbers::pi_v<double>;
+ const double* d5 = &std::numbers::inv_pi_v<double>;
+ const double* d6 = &std::numbers::inv_sqrtpi_v<double>;
+ const double* d7 = &std::numbers::ln2_v<double>;
+ const double* d8 = &std::numbers::ln10_v<double>;
+ const double* d9 = &std::numbers::sqrt2_v<double>;
+ const double* d10 = &std::numbers::sqrt3_v<double>;
+ const double* d11 = &std::numbers::inv_sqrt3_v<double>;
+ const double* d12 = &std::numbers::egamma_v<double>;
+ const double* d13 = &std::numbers::phi_v<double>;
+}
+
+void
+test02()
+{
+ const float* d1 = &std::numbers::e_v<float>;
+ const float* d2 = &std::numbers::log2e_v<float>;
+ const float* d3 = &std::numbers::log10e_v<float>;
+ const float* d4 = &std::numbers::pi_v<float>;
+ const float* d5 = &std::numbers::inv_pi_v<float>;
+ const float* d6 = &std::numbers::inv_sqrtpi_v<float>;
+ const float* d7 = &std::numbers::ln2_v<float>;
+ const float* d8 = &std::numbers::ln10_v<float>;
+ const float* d9 = &std::numbers::sqrt2_v<float>;
+ const float* d10 = &std::numbers::sqrt3_v<float>;
+ const float* d11 = &std::numbers::inv_sqrt3_v<float>;
+ const float* d12 = &std::numbers::egamma_v<float>;
+ const float* d13 = &std::numbers::phi_v<float>;
+}
+
+void
+test03()
+{
+ const long double* d1 = &std::numbers::e_v<long double>;
+ const long double* d2 = &std::numbers::log2e_v<long double>;
+ const long double* d3 = &std::numbers::log10e_v<long double>;
+ const long double* d4 = &std::numbers::pi_v<long double>;
+ const long double* d5 = &std::numbers::inv_pi_v<long double>;
+ const long double* d6 = &std::numbers::inv_sqrtpi_v<long double>;
+ const long double* d7 = &std::numbers::ln2_v<long double>;
+ const long double* d8 = &std::numbers::ln10_v<long double>;
+ const long double* d9 = &std::numbers::sqrt2_v<long double>;
+ const long double* d10 = &std::numbers::sqrt3_v<long double>;
+ const long double* d11 = &std::numbers::inv_sqrt3_v<long double>;
+ const long double* d12 = &std::numbers::egamma_v<long double>;
+ const long double* d13 = &std::numbers::phi_v<long double>;
+}
+
+void
+test04()
+{
+ static_assert(std::numbers::e == std::numbers::e_v<double>);
+ static_assert(std::numbers::log2e == std::numbers::log2e_v<double>);
+ static_assert(std::numbers::log10e == std::numbers::log10e_v<double>);
+ static_assert(std::numbers::pi == std::numbers::pi_v<double>);
+ static_assert(std::numbers::inv_pi == std::numbers::inv_pi_v<double>);
+ static_assert(std::numbers::inv_sqrtpi == std::numbers::inv_sqrtpi_v<double>);
+ static_assert(std::numbers::ln2 == std::numbers::ln2_v<double>);
+ static_assert(std::numbers::ln10 == std::numbers::ln10_v<double>);
+ static_assert(std::numbers::sqrt2 == std::numbers::sqrt2_v<double>);
+ static_assert(std::numbers::sqrt3 == std::numbers::sqrt3_v<double>);
+ static_assert(std::numbers::inv_sqrt3 == std::numbers::inv_sqrt3_v<double>);
+ static_assert(std::numbers::egamma == std::numbers::egamma_v<double>);
+ static_assert(std::numbers::phi == std::numbers::phi_v<double>);
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/numbers/2.cc b/libstdc++-v3/testsuite/26_numerics/numbers/2.cc
new file mode 100644
index 0000000..a363bce
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/numbers/2.cc
@@ -0,0 +1,27 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <version>
+
+#ifndef __cpp_lib_math_constants
+# error "Feature-test macro for math constants missing in <version>"
+#elif __cpp_lib_math_constants != 201907L
+# error "Feature-test macro for math constants has wrong value in <version>"
+#endif
diff --git a/libstdc++-v3/testsuite/26_numerics/numbers/3.cc b/libstdc++-v3/testsuite/26_numerics/numbers/3.cc
new file mode 100644
index 0000000..56f4c95
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/numbers/3.cc
@@ -0,0 +1,25 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <numbers>
+
+struct D { double val; };
+template<> inline constexpr D std::numbers::pi_v<D> = D{std::numbers::pi};
+static_assert( std::numbers::pi_v<D>.val == std::numbers::pi );
diff --git a/libstdc++-v3/testsuite/26_numerics/numbers/float128.cc b/libstdc++-v3/testsuite/26_numerics/numbers/float128.cc
new file mode 100644
index 0000000..2d9dafc
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/numbers/float128.cc
@@ -0,0 +1,41 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <numbers>
+
+#if defined(_GLIBCXX_USE_FLOAT128)
+void
+test01()
+{
+ const __float128* d1 = &std::numbers::e_v<__float128>;
+ const __float128* d2 = &std::numbers::log2e_v<__float128>;
+ const __float128* d3 = &std::numbers::log10e_v<__float128>;
+ const __float128* d4 = &std::numbers::pi_v<__float128>;
+ const __float128* d5 = &std::numbers::inv_pi_v<__float128>;
+ const __float128* d6 = &std::numbers::inv_sqrtpi_v<__float128>;
+ const __float128* d7 = &std::numbers::ln2_v<__float128>;
+ const __float128* d8 = &std::numbers::ln10_v<__float128>;
+ const __float128* d9 = &std::numbers::sqrt2_v<__float128>;
+ const __float128* d10 = &std::numbers::sqrt3_v<__float128>;
+ const __float128* d11 = &std::numbers::inv_sqrt3_v<__float128>;
+ const __float128* d12 = &std::numbers::egamma_v<__float128>;
+ const __float128* d13 = &std::numbers::phi_v<__float128>;
+}
+#endif
diff --git a/libstdc++-v3/testsuite/26_numerics/numbers/nonfloat_neg.cc b/libstdc++-v3/testsuite/26_numerics/numbers/nonfloat_neg.cc
new file mode 100644
index 0000000..a83f55e
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/numbers/nonfloat_neg.cc
@@ -0,0 +1,36 @@
+// Copyright (C) 2019 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <numbers>
+
+int
+test01()
+{
+ return std::numbers::pi_v<int>; // { dg-error "here" }
+}
+
+void
+test02()
+{
+ struct S { };
+ auto s = std::numbers::egamma_v<S>; // { dg-error "here" }
+}
+
+// { dg-prune-output "no type named 'type' in" }
diff --git a/libstdc++-v3/testsuite/ext/bitmap_allocator/check_delete.cc b/libstdc++-v3/testsuite/ext/bitmap_allocator/check_delete.cc
index 1b44564..1ad1f3c 100644
--- a/libstdc++-v3/testsuite/ext/bitmap_allocator/check_delete.cc
+++ b/libstdc++-v3/testsuite/ext/bitmap_allocator/check_delete.cc
@@ -15,6 +15,8 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+// { dg-options "-fno-allocation-dce" }
+
// 20.4.1.1 allocator members
#include <cstdlib>
diff --git a/libstdc++-v3/testsuite/ext/bitmap_allocator/check_new.cc b/libstdc++-v3/testsuite/ext/bitmap_allocator/check_new.cc
index 0c5f9b6..be16952 100644
--- a/libstdc++-v3/testsuite/ext/bitmap_allocator/check_new.cc
+++ b/libstdc++-v3/testsuite/ext/bitmap_allocator/check_new.cc
@@ -15,6 +15,8 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+// { dg-options "-fno-allocation-dce" }
+
// 20.4.1.1 allocator members
#include <cstdlib>
diff --git a/libstdc++-v3/testsuite/ext/new_allocator/check_delete.cc b/libstdc++-v3/testsuite/ext/new_allocator/check_delete.cc
index 8778bc9..dccee1d 100644
--- a/libstdc++-v3/testsuite/ext/new_allocator/check_delete.cc
+++ b/libstdc++-v3/testsuite/ext/new_allocator/check_delete.cc
@@ -17,6 +17,8 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+// { dg-options "-fno-allocation-dce" }
+
// 20.4.1.1 allocator members
#include <cstdlib>
diff --git a/libstdc++-v3/testsuite/ext/new_allocator/check_new.cc b/libstdc++-v3/testsuite/ext/new_allocator/check_new.cc
index fd90d28..a1d164a 100644
--- a/libstdc++-v3/testsuite/ext/new_allocator/check_new.cc
+++ b/libstdc++-v3/testsuite/ext/new_allocator/check_new.cc
@@ -17,6 +17,8 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+// { dg-options "-fno-allocation-dce" }
+
// 20.4.1.1 allocator members
#include <cstdlib>
diff --git a/libstdc++-v3/testsuite/ext/random/beta_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/ext/random/beta_distribution/operators/serialize.cc
index b054171..a4925fc 100644
--- a/libstdc++-v3/testsuite/ext/random/beta_distribution/operators/serialize.cc
+++ b/libstdc++-v3/testsuite/ext/random/beta_distribution/operators/serialize.cc
@@ -23,6 +23,7 @@
#include <ext/random>
#include <sstream>
+#include <testsuite_hooks.h>
void
test01()
@@ -35,6 +36,7 @@ test01()
str << u;
str >> v;
+ VERIFY( u == v );
}
int main()
diff --git a/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/serialize.cc
index 9c2cc46a..e9077b2 100644
--- a/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/serialize.cc
+++ b/libstdc++-v3/testsuite/ext/random/hypergeometric_distribution/operators/serialize.cc
@@ -38,6 +38,7 @@ test01()
str << u;
str >> v;
+ VERIFY( u == v );
}
int
diff --git a/libstdc++-v3/testsuite/ext/random/normal_mv_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/ext/random/normal_mv_distribution/operators/serialize.cc
index 8d83f9e..f5fbc42a 100644
--- a/libstdc++-v3/testsuite/ext/random/normal_mv_distribution/operators/serialize.cc
+++ b/libstdc++-v3/testsuite/ext/random/normal_mv_distribution/operators/serialize.cc
@@ -23,6 +23,7 @@
#include <ext/random>
#include <sstream>
+#include <testsuite_hooks.h>
void
test01()
@@ -35,6 +36,7 @@ test01()
str << u;
str >> v;
+ VERIFY( u == v );
}
int main()
diff --git a/libstdc++-v3/testsuite/ext/random/triangular_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/ext/random/triangular_distribution/operators/serialize.cc
index cf17fea..75e16cf 100644
--- a/libstdc++-v3/testsuite/ext/random/triangular_distribution/operators/serialize.cc
+++ b/libstdc++-v3/testsuite/ext/random/triangular_distribution/operators/serialize.cc
@@ -23,6 +23,7 @@
#include <ext/random>
#include <sstream>
+#include <testsuite_hooks.h>
void
test01()
@@ -35,6 +36,7 @@ test01()
str << u;
str >> v;
+ VERIFY( u == v );
}
int main()
diff --git a/libstdc++-v3/testsuite/ext/random/von_mises_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/operators/serialize.cc
index f3d7912..b32a31d 100644
--- a/libstdc++-v3/testsuite/ext/random/von_mises_distribution/operators/serialize.cc
+++ b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/operators/serialize.cc
@@ -23,6 +23,7 @@
#include <ext/random>
#include <sstream>
+#include <testsuite_hooks.h>
void
test01()
@@ -35,6 +36,7 @@ test01()
str << u;
str >> v;
+ VERIFY( u == v );
}
int main()
diff --git a/libstdc++-v3/testsuite/util/testsuite_iterators.h b/libstdc++-v3/testsuite/util/testsuite_iterators.h
index ac646a5..42e4274 100644
--- a/libstdc++-v3/testsuite/util/testsuite_iterators.h
+++ b/libstdc++-v3/testsuite/util/testsuite_iterators.h
@@ -344,7 +344,7 @@ namespace __gnu_test
* @brief bidirectional_iterator wrapper for pointer
*
* This class takes a pointer and wraps it to provide exactly
- * the requirements of a forward_iterator. It should not be
+ * the requirements of a bidirectional_iterator. It should not be
* instantiated directly, but generated from a test_container
*/
template<class T>
@@ -408,7 +408,7 @@ namespace __gnu_test
* @brief random_access_iterator wrapper for pointer
*
* This class takes a pointer and wraps it to provide exactly
- * the requirements of a forward_iterator. It should not be
+ * the requirements of a random_access_iterator. It should not be
* instantiated directly, but generated from a test_container
*/
template<class T>
diff --git a/maintainer-scripts/ChangeLog b/maintainer-scripts/ChangeLog
index 3658bda..00d4549 100644
--- a/maintainer-scripts/ChangeLog
+++ b/maintainer-scripts/ChangeLog
@@ -1,3 +1,8 @@
+2019-08-05 David Malcolm <dmalcolm@redhat.com>
+
+ * update_web_docs_svn: Proceed even if the invocation of
+ sphinx fails.
+
2019-05-04 Gerald Pfeifer <gerald@pfeifer.com>
* crontab: Snapshots from trunk are now GCC 10 related.
diff --git a/maintainer-scripts/update_web_docs_svn b/maintainer-scripts/update_web_docs_svn
index 4f262fd..16abfee 100755
--- a/maintainer-scripts/update_web_docs_svn
+++ b/maintainer-scripts/update_web_docs_svn
@@ -190,7 +190,7 @@ done
# /usr/bin/sphinx-1.0-build
# so we need to override SPHINXBUILD with this when invoking "make".
pushd gcc/gcc/jit/docs
-make SPHINXBUILD=/usr/bin/sphinx-1.0-build html
+make SPHINXBUILD=/usr/bin/sphinx-1.0-build html || true
popd
cp -a gcc/gcc/jit/docs/_build/html jit
mkdir -p $DOCSDIR/jit